//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Job/JobsPanel.cpp
//! @brief     Implements class JobsPanel.
//!
//! @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/Job/JobsPanel.h"
#include "Base/Util/Assert.h"
#include "GUI/View/Base/mainwindow_constants.h"
#include "GUI/View/Job/JobMessagesDisplay.h"
#include "GUI/View/Job/JobparQModel.h"
#include "GUI/View/Job/JobsListing.h"
#include <QHeaderView>
#include <QSettings>
#include <QVBoxLayout>

namespace {

QVariant listToQVariant(const QVector<int>& list)
{
    QVector<QVariant> var_list;
    for (int val : list)
        var_list.push_back(QVariant(val));
    return {var_list};
}

QVector<int> qVariantToList(const QVariant& var)
{
    QVector<QVariant> var_list = var.toList();
    QVector<int> list;
    for (const QVariant& var_val : var_list)
        list.push_back(var_val.toInt());
    return list;
}

} // namespace


JobsPanel::JobsPanel(QWidget* parent)
    : QWidget(parent)
    , m_splitter(new QSplitter(Qt::Vertical, this))
    , m_listing(new JobsListing(m_splitter))
    , m_properties_view(new QTreeView(this))
    , m_properties_model(new JobparQModel(this))
    , m_messages_display(new JobMessagesDisplay(this))
{
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
    setWindowTitle("Job Selector");

    auto* layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);

    m_splitter->setChildrenCollapsible(true);
    layout->addWidget(m_splitter);

    m_properties_view->setRootIsDecorated(false);
    m_properties_view->setAlternatingRowColors(true);
    m_properties_view->setModel(m_properties_model);
    m_properties_view->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
    m_properties_view->setFixedHeight(150);

    m_splitter->addWidget(m_listing);
    m_splitter->addWidget(m_messages_display);
    m_splitter->addWidget(m_properties_view);

    m_splitter->setCollapsible(0, false);
    m_splitter->setCollapsible(1, false);
    m_splitter->setCollapsible(2, false);
    m_splitter->setStretchFactor(0, 1);
    m_splitter->setStretchFactor(1, 0);
    m_splitter->setStretchFactor(2, 0);

    connect(m_listing, &JobsListing::selectedJobsChanged, this, &JobsPanel::onSelectedJobsChanged);

    onSelectedJobsChanged(selectedJobItems());

    setFixedWidth(GUI::Style::JOB_SELECTOR_PANEL_WIDTH);
    applySettings();
}

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

void JobsPanel::resizeEvent(QResizeEvent* event)
{
    QWidget::resizeEvent(event);
    setMinimumWidth(0);
    setMaximumWidth(QWIDGETSIZE_MAX);
}

QVector<JobItem*> JobsPanel::selectedJobItems() const
{
    return m_listing->selectedJobItems();
}

void JobsPanel::makeNewJobItemSelected(JobItem* item)
{
    ASSERT(item);
    m_listing->selectNewJob(item);
}

void JobsPanel::onSelectedJobsChanged(const QVector<JobItem*>& jobs)
{
    JobItem* current_job = jobs.size() == 1 ? jobs.front() : nullptr;
    m_properties_view->repaint();
    m_messages_display->setJobItem(current_job);
    emit selectedJobsChanged();
}

void JobsPanel::applySettings()
{
    QSettings settings;
    if (settings.childGroups().contains(GUI::Style::S_JOB_SELECTOR_PANEL)) {
        settings.beginGroup(GUI::Style::S_JOB_SELECTOR_PANEL);
        setFixedWidth(settings.value(GUI::Style::S_JOB_SELECTOR_PANEL_WIDTH).toInt());
        m_splitter->setSizes(
            qVariantToList(settings.value(GUI::Style::S_JOB_SELECTOR_SPLITTER_SIZES)));
        settings.endGroup();
    }
}

void JobsPanel::saveSettings()
{
    QSettings settings;
    settings.beginGroup(GUI::Style::S_JOB_SELECTOR_PANEL);
    settings.setValue(GUI::Style::S_JOB_SELECTOR_PANEL_WIDTH, width());
    settings.setValue(GUI::Style::S_JOB_SELECTOR_SPLITTER_SIZES,
                      listToQVariant(m_splitter->sizes()));
    settings.endGroup();
    settings.sync();
}
