//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Device/SphericalAxisForm.cpp
//! @brief     Implement class SphericalAxisForm
//!
//! @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/Device/SphericalAxisForm.h"
#include "GUI/Model/Axis/BasicAxisItem.h"
#include "GUI/View/Numeric/SafeSpinBox.h"
#include "GUI/View/Numeric/ScientificSpinBox.h"

SphericalAxisForm::SphericalAxisForm(QFormLayout* form, QWidget* parent)
    : QObject(parent)
    , m_axisItem(nullptr)
{
    m_nbinsSpinBox = new SafeSpinBox;
    m_nbinsSpinBox->setRange(1, 65536);
    connect(m_nbinsSpinBox, qOverload<int>(&QSpinBox::valueChanged), this,
            &SphericalAxisForm::onNbinsValueChanged);
    form->addRow("# scan points:", m_nbinsSpinBox);

    m_minimumSpinBox = new ScientificSpinBox(parent);
    m_minimumSpinBox->setMinimum(0);
    m_minimumSpinBox->setMaximum(90);
    m_minimumSpinBox->setDecimals(5);
    m_minimumSpinBox->setSingleStep(0.01);
    connect(m_minimumSpinBox, &ScientificSpinBox::valueChanged, this,
            &SphericalAxisForm::onMinimumValueChanged);
    form->addRow("Initial angle [deg]:", m_minimumSpinBox);

    m_maximumSpinBox = new ScientificSpinBox(parent);
    m_maximumSpinBox->setMinimum(0);
    m_maximumSpinBox->setMaximum(90);
    m_maximumSpinBox->setDecimals(5);
    m_maximumSpinBox->setSingleStep(0.01);
    connect(m_maximumSpinBox, &ScientificSpinBox::valueChanged, this,
            &SphericalAxisForm::onMaximumValueChanged);
    form->addRow("Final angle [deg]:", m_maximumSpinBox);
}

void SphericalAxisForm::setAxisItem(BasicAxisItem* axisItem)
{
    m_axisItem = axisItem;
    setEnabled(m_axisItem);
    updateData();
}

void SphericalAxisForm::setEnabled(bool enabled)
{
    m_nbinsSpinBox->setEnabled(enabled);
    m_minimumSpinBox->setEnabled(enabled);
    m_maximumSpinBox->setEnabled(enabled);
}

void SphericalAxisForm::updateData()
{
    QSignalBlocker b1(m_nbinsSpinBox);
    QSignalBlocker b2(m_minimumSpinBox);
    QSignalBlocker b3(m_maximumSpinBox);
    if (m_axisItem) {
        m_nbinsSpinBox->setValue(m_axisItem->binCount());
        m_minimumSpinBox->setValue(m_axisItem->min());
        m_maximumSpinBox->setValue(m_axisItem->max());
    } else {
        m_nbinsSpinBox->setValue(1);
        m_minimumSpinBox->setValue(0.0);
        m_maximumSpinBox->setValue(0.0);
    }
}

void SphericalAxisForm::onNbinsValueChanged(int value)
{
    if (m_axisItem && m_axisItem->binCount() != value) {
        m_axisItem->setBinCount(value);
        emit dataChanged();
    }
}

void SphericalAxisForm::onMinimumValueChanged(double value)
{
    if (m_axisItem && m_axisItem->min() != value) {
        m_axisItem->setMin(value);
        emit dataChanged();
        if (m_axisItem->max() < value)
            m_maximumSpinBox->setValue(value);
    }
}

void SphericalAxisForm::onMaximumValueChanged(double value)
{
    if (m_axisItem && m_axisItem->max() != value) {
        m_axisItem->setMax(value);
        emit dataChanged();
        if (m_axisItem->min() > value)
            m_minimumSpinBox->setValue(value);
    }
}
