//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Fit/FitActivityPanel.cpp
//! @brief     Implements class FitActivityPanel
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "GUI/View/Fit/FitActivityPanel.h"
#include "GUI/View/Fit/FitSessionController.h"
#include "GUI/View/Fit/FitSessionManager.h"
#include "GUI/View/Fit/FitSessionWidget.h"
#include "GUI/View/Fit/JobRealTimeWidget.h"
#include "GUI/View/Fit/RunFitControlWidget.h"
#include "GUI/View/Tool/mainwindow_constants.h"
#include <QLabel>
#include <QSettings>
#include <QVBoxLayout>

FitActivityPanel::FitActivityPanel(QWidget* parent)
    : QWidget(parent)
    , m_realTimeWidget(nullptr)
    , m_fitSessionManager(new FitSessionManager(this))
{
    setWindowTitle(GUI::Constants::JobFitPanelName);
    setObjectName("FitActivityPanel");
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);

    auto* layout = new QVBoxLayout(this);

    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    m_stack = new QStackedWidget(this);
    layout->addWidget(m_stack);

    m_blankWidget = new QWidget(m_stack);
    m_stack->addWidget(m_blankWidget);

    m_nofitLabel = new QLabel("Job has no real data linked to it for fitting.", m_stack);
    m_nofitLabel->setAlignment(Qt::AlignCenter);
    m_stack->addWidget(m_nofitLabel);

    m_fitSessionWidget = new FitSessionWidget(m_stack);
    m_stack->addWidget(m_fitSessionWidget);

    setFixedSize(GUI::Constants::FIT_ACTIVITY_PANEL_WIDTH,
                 GUI::Constants::FIT_ACTIVITY_PANEL_HEIGHT);
    applySettings();
}

FitActivityPanel::~FitActivityPanel()
{
    saveSettings();
}

void FitActivityPanel::setRealTimeWidget(JobRealTimeWidget* realTimeWidget)
{
    ASSERT(realTimeWidget);
    m_realTimeWidget = realTimeWidget;
    connect(m_realTimeWidget, &JobRealTimeWidget::widthChanged, this,
            &FitActivityPanel::adjustWidthToRealTimeWidget, Qt::UniqueConnection);
}

void FitActivityPanel::resizeEvent(QResizeEvent* event)
{
    QWidget::resizeEvent(event);
    setMinimumSize(0, 0);
    setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
}

void FitActivityPanel::setJobItem(JobItem* jobItem)
{
    if (!isValidJobItem(jobItem)) {
        if (!jobItem)
            m_stack->setCurrentWidget(m_blankWidget);
        else
            m_stack->setCurrentWidget(m_nofitLabel);
        emit showLog(nullptr);
        return;
    }

    m_stack->setCurrentWidget(m_fitSessionWidget);
    m_fitSessionWidget->setJobItem(jobItem);
    m_fitSessionWidget->setModelTuningWidget(m_realTimeWidget->parameterTuningWidget(jobItem));
    FitSessionController* controller = m_fitSessionManager->sessionController(jobItem);
    m_fitSessionWidget->setSessionController(controller);
    emit showLog(controller->fitLog());
}

bool FitActivityPanel::isValidJobItem(JobItem* item)
{
    return item ? item->isValidForFitting() : false;
}

FitSessionWidget* FitActivityPanel::currentFitSuiteWidget()
{
    return m_fitSessionWidget;
}

void FitActivityPanel::adjustWidthToRealTimeWidget(int w)
{
    if (w != width()) {
        setFixedWidth(w);
        setMinimumSize(0, 0);
        setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
    }
}

void FitActivityPanel::applySettings()
{
    QSettings settings;
    if (settings.childGroups().contains(GUI::Constants::S_FIT_ACTIVITY_PANEL)) {
        settings.beginGroup(GUI::Constants::S_FIT_ACTIVITY_PANEL);
        setFixedSize(settings.value(GUI::Constants::S_FIT_ACTIVITY_PANEL_SIZE).toSize());
        settings.endGroup();
    }
}

void FitActivityPanel::saveSettings()
{
    QSettings settings;
    settings.beginGroup(GUI::Constants::S_FIT_ACTIVITY_PANEL);
    settings.setValue(GUI::Constants::S_FIT_ACTIVITY_PANEL_SIZE, size());
    settings.endGroup();
    settings.sync();
}
