//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Device/SpanPropertyForm.cpp
//! @brief     Implement class SpanPropertyForm
//!
//! @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/SpanPropertyForm.h"
#include "Base/Util/Assert.h"
#include "GUI/Model/Descriptor/SpanProperty.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "GUI/View/Numeric/DoubleSpinBox.h"
#include "GUI/View/Numeric/NumWidgetUtil.h"
#include <QFormLayout>

SpanPropertyForm::SpanPropertyForm(QWidget* parent, const QString& groupTitle,
                                   SpanProperty* spanProperty, QString nbinsTooltip)
    : StaticGroupBox(groupTitle, parent)
    , m_span_property(spanProperty)
{
    auto* layout = new QFormLayout;
    body()->setLayout(layout);

    layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);

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

    m_width_spin_box = GUI::Util::createDoubleSpinBoxRow(layout, spanProperty->width());
    m_center_spin_box = GUI::Util::createDoubleSpinBoxRow(layout, spanProperty->center());

    connect(m_width_spin_box, &DoubleSpinBox::valueChanged, [this](double v) {
        ASSERT(v >= 0); // spin box should have got limits from property
        if (m_span_property->width() != v) {
            m_span_property->setWidth(v);
            emit dataChanged();
        }
    });

    connect(m_center_spin_box, &DoubleSpinBox::valueChanged, [this](double v) {
        if (m_span_property->center() != v) {
            m_span_property->setCenter(v);
            emit dataChanged();
        }
    });
}
