//  ************************************************************************************************
//
//  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 <QFormLayout>

AxisPropertyForm::AxisPropertyForm(QWidget* parent, const QString& groupTitle,
                                   AxisProperty* axisProperty, QString nbinsTooltip)
    : StaticGroupBox(groupTitle, parent)
    , m_axis_property(axisProperty)
{
    auto* layout = new QFormLayout;
    body()->setLayout(layout);

    layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);

    m_nbins_spin_box = GUI::Util::createIntSpinBox([axisProperty] { return axisProperty->nbins(); },
                                                   [this, axisProperty](int v) {
                                                       axisProperty->setNbins(v);
                                                       emit dataChanged();
                                                       gDoc->setModified();
                                                   },
                                                   RealLimits::nonnegative(), nbinsTooltip);
    layout->addRow("# bins:", m_nbins_spin_box);

    m_min_spin_box = GUI::Util::createDoubleSpinBoxRow(layout, axisProperty->min());
    m_max_spin_box = GUI::Util::createDoubleSpinBoxRow(layout, axisProperty->max());

    connect(m_min_spin_box, &DoubleSpinBox::valueChanged, [this](double v) {
        if (m_axis_property->min() != v) {
            m_axis_property->setMin(v);
            emit dataChanged();
            if (m_axis_property->max() < v) {
                m_axis_property->setMax(v);
                m_max_spin_box->updateValue();
            }
        }
    });

    connect(m_max_spin_box, &DoubleSpinBox::valueChanged, [this](double v) {
        if (m_axis_property->max() != v) {
            m_axis_property->setMax(v);
            emit dataChanged();
            if (m_axis_property->min() > v) {
                m_axis_property->setMin(v);
                m_min_spin_box->updateValue();
            }
        }
    });
}
