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

#include "GUI/View/Device/AxisPropertyForm.h"
#include "GUI/Model/Descriptor/AxisProperty.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "GUI/View/Numeric/DoubleSpinBox.h"
#include "GUI/View/Numeric/NumWidgetUtil.h"
#include "GUI/View/Tool/GroupBoxCollapser.h"

AxisPropertyForm::AxisPropertyForm(QWidget* parent, const QString& groupTitle,
                                   AxisProperty* axisProperty, QString nbinsTooltip)
    : QGroupBox(groupTitle, parent)
    , m_axisProperty(axisProperty)
{
    auto* formLayout = new QFormLayout(this);
    formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);

    m_nbinsSpinBox = GUI::Util::createIntSpinbox([axisProperty] { return axisProperty->nbins(); },
                                                 [this, axisProperty](int v) {
                                                     axisProperty->setNbins(v);
                                                     emit dataChanged();
                                                     gProjectDocument.value()->setModified();
                                                 },
                                                 RealLimits::nonnegative(), nbinsTooltip);
    formLayout->addRow("# bins:", m_nbinsSpinBox);


    m_minSpinBox = GUI::Util::createDoubleSpinBoxRow(formLayout, axisProperty->min());
    m_maxSpinBox = GUI::Util::createDoubleSpinBoxRow(formLayout, axisProperty->max());

    auto* collapser = GroupBoxCollapser::installIntoGroupBox(this);
    collapser->setExpanded(m_axisProperty->isExpandGroupBox());
    connect(collapser, &GroupBoxCollapser::toggled, this,
            [this](bool b) { m_axisProperty->setExpandGroupBox(b); });

    connect(m_minSpinBox, qOverload<double>(&DoubleSpinBox::baseValueChanged), [this](double v) {
        if (m_axisProperty->min() != v) {
            m_axisProperty->setMin(v);
            emit dataChanged();
            if (m_axisProperty->max() < v) {
                m_axisProperty->setMax(v);
                m_maxSpinBox->updateValue();
            }
        }
    });

    connect(m_maxSpinBox, qOverload<double>(&DoubleSpinBox::baseValueChanged), [this](double v) {
        if (m_axisProperty->max() != v) {
            m_axisProperty->setMax(v);
            emit dataChanged();
            if (m_axisProperty->min() > v) {
                m_axisProperty->setMin(v);
                m_minSpinBox->updateValue();
            }
        }
    });
}

void AxisPropertyForm::updateData()
{
    QSignalBlocker b(m_nbinsSpinBox);
    m_nbinsSpinBox->setValue(m_axisProperty->nbins());
    m_minSpinBox->updateValue();
    m_maxSpinBox->updateValue();
}
