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

#include "GUI/Model/Descriptor/DoubleProperty.h"
#include "GUI/Support/XML/UtilXML.h"
#include <QUuid>

using std::variant;

void DoubleProperty::init(const QString& label, const QString& tooltip, double value,
                          const variant<QString, Unit>& unit, const QString& uidPrefix)
{
    init(label, tooltip, value, unit, 3, RealLimits::nonnegative(), uidPrefix);
}

void DoubleProperty::init(const QString& label, const QString& tooltip, double value,
                          const variant<QString, Unit>& unit, uint decimals,
                          const RealLimits& limits, const QString& uidPrefix)
{
    init(label, tooltip, value, unit, decimals, 0.01, limits, uidPrefix);
}

void DoubleProperty::init(const QString& label, const QString& tooltip, double value,
                          const std::variant<QString, Unit>& unit, uint decimals, double step,
                          const RealLimits& limits, const QString& uidPrefix)
{
    m_label = label;
    m_tooltip = tooltip;
    m_value = value;
    m_unit = unit;
    m_decimals = decimals;
    m_step = step;
    m_limits = limits;

    if (uidPrefix.size() > 0)
        m_uid = uidPrefix + "/" + QUuid::createUuid().toString();
    else
        m_uid = QUuid::createUuid().toString();
}

void DoubleProperty::setTooltip(const QString& tooltip)
{
    m_tooltip = tooltip;
}

void DoubleProperty::setUnit(const variant<QString, Unit>& unit)
{
    m_unit = unit;
}

void DoubleProperty::setLimits(const RealLimits& limits)
{
    m_limits = limits;
}

bool DoubleProperty::isInitialized() const
{
    return !m_uid.isEmpty();
}

void DoubleProperty::writeTo(QXmlStreamWriter* w) const
{
    XML::writeAttribute(w, XML::Attrib::value, m_value);
    XML::writeAttribute(w, XML::Attrib::id, m_uid);
    XML::writeAttribute(w, XML::Attrib::version, uint(1));
}

void DoubleProperty::writeTo(QXmlStreamWriter* w, const QString& tag) const
{
    w->writeStartElement(tag);
    writeTo(w);
    w->writeEndElement();
}

void DoubleProperty::readFrom(QXmlStreamReader* r)
{
    const uint version = XML::readUIntAttribute(r, XML::Attrib::version);
    Q_UNUSED(version)

    XML::readAttribute(r, XML::Attrib::value, &m_value);
    XML::readAttribute(r, XML::Attrib::id, &m_uid);
}

void DoubleProperty::readFrom(QXmlStreamReader* r, const QString& tag)
{
    readFrom(r);
    XML::gotoEndElementOfTag(r, tag);
}
