//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Tuning/SliderEditor.cpp
//! @brief     Implements class SliderEditor.
//!
//! @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/Tuning/SliderEditor.h"
#include "Base/Util/Assert.h"
#include "GUI/Model/Data/Data2DItem.h"
#include "GUI/Model/Job/JobItem.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include <QLabel>
#include <QVBoxLayout>

SliderEditor::SliderEditor()
    : m_radio1(nullptr)
    , m_radio2(nullptr)
    , m_radio3(nullptr)
    , m_lockz_check_box(nullptr)
{
    // tuning selectors
    QString tooltip("Allows to tune sample parameters within +/- of given range \nwith the help of "
                    "the slider.");

    auto* label = new QLabel("Tuning:");
    label->setToolTip(tooltip);

    m_radio1 = new QRadioButton("10%");
    m_radio1->setAutoExclusive(true);
    m_radio1->setToolTip(tooltip);
    connect(m_radio1, &QRadioButton::clicked, this, &SliderEditor::rangeChanged);

    m_radio2 = new QRadioButton("100%");
    m_radio2->setChecked(true);
    m_radio2->setAutoExclusive(true);
    m_radio2->setToolTip(tooltip);
    connect(m_radio2, &QRadioButton::clicked, this, &SliderEditor::rangeChanged);

    m_radio3 = new QRadioButton("1000%");
    m_radio3->setAutoExclusive(true);
    m_radio3->setToolTip(tooltip);
    connect(m_radio3, &QRadioButton::clicked, this, &SliderEditor::rangeChanged);

    // Fix z-axis
    m_lockz_check_box = new QCheckBox("Lock-Z");
    m_lockz_check_box->setToolTip(
        "Preserve (min, max) range of intensity axis during parameter tuning.");
    connect(m_lockz_check_box, &QCheckBox::stateChanged, this, &SliderEditor::onLockZChanged);

    auto* hbox = new QHBoxLayout;

    hbox->addWidget(label);
    hbox->addWidget(m_radio1);
    hbox->addWidget(m_radio2);
    hbox->addWidget(m_radio3);
    hbox->addStretch(1);
    hbox->addWidget(m_lockz_check_box);

    setLayout(hbox);
}

void SliderEditor::onJobDestroyed()
{
    m_job_item = nullptr;
}

void SliderEditor::setJobItem(JobItem* job_item)
{
    m_job_item = job_item;
    if (!m_job_item)
        return;

    connect(m_job_item, &QObject::destroyed, this, &SliderEditor::onJobDestroyed,
            Qt::UniqueConnection);

    initSlider();
    initZlock();
}

void SliderEditor::rangeChanged()
{
    if (!m_job_item)
        return;

    if (m_radio1->isChecked())
        m_slider_range = 10;
    else if (m_radio2->isChecked())
        m_slider_range = 100;
    else if (m_radio3->isChecked())
        m_slider_range = 1000;

    emit sliderRangeFactorChanged(m_slider_range);
    gDoc->setModified();
}

void SliderEditor::onLockZChanged(int state)
{
    if (state == Qt::Unchecked)
        emit lockzChanged(false);
    else if (state == Qt::Checked)
        emit lockzChanged(true);
    gDoc->setModified();
}

void SliderEditor::initSlider()
{
    ASSERT(m_job_item);

    if (m_slider_range == 10)
        m_radio1->setChecked(true);
    else if (m_slider_range == 1000)
        m_radio3->setChecked(true);
    else {
        m_slider_range = 100;
        m_radio2->setChecked(true);
    }
    emit sliderRangeFactorChanged(m_slider_range);
}

void SliderEditor::initZlock()
{
    ASSERT(m_job_item);

    if (auto* data_item = m_job_item->data2DItem()) {
        m_lockz_check_box->show();
        m_lockz_check_box->setChecked(data_item->isZaxisLocked());
    } else
        m_lockz_check_box->hide();
}
