//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/Model/Descriptor/VectorProperty.cpp
//! @brief     Implements class VectorProperty
//!
//! @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/VectorProperty.h"
#include "GUI/Support/XML/UtilXML.h"
#include <QUuid>

namespace {
namespace Tag {

const QString X("X");
const QString Y("Y");
const QString Z("Z");

} // namespace Tag
} // namespace

using std::variant;

void VectorProperty::init(const QString& label, const QString& tooltip,
                          const variant<QString, Unit>& unit, const QString& uidPrefix)
{
    init(label, tooltip, R3(), unit, 3, 0.01, RealLimits::limitless(), uidPrefix);
}

void VectorProperty::init(const QString& label, const QString& tooltip, const R3& value,
                          const std::variant<QString, Unit>& unit, uint decimals, double step,
                          const RealLimits& limits, const QString& uidPrefix)
{
    m_label = label;

    m_x.init("x", tooltip, value.x(), unit, decimals, step, limits, uidPrefix);
    m_y.init("y", tooltip, value.y(), unit, decimals, step, limits, uidPrefix);
    m_z.init("z", tooltip, value.z(), unit, decimals, step, limits, uidPrefix);

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

    m_x.setUid(uid + "/x");
    m_y.setUid(uid + "/y");
    m_z.setUid(uid + "/z");
}

bool VectorProperty::operator==(const VectorProperty& other) const
{
    return (m_label == other.m_label) && (m_x == other.m_x) && (m_y == other.m_y)
           && (m_z == other.m_z);
}

void VectorProperty::writeTo(QXmlStreamWriter* w) const
{
    XML::writeAttribute(w, XML::Attrib::version, uint(1));

    m_x.writeTo(w, Tag::X);
    m_y.writeTo(w, Tag::Y);
    m_z.writeTo(w, Tag::Z);
}

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

    while (r->readNextStartElement()) {
        QString tag = r->name().toString();

        if (tag == Tag::X)
            m_x.readFrom(r, tag);
        else if (tag == Tag::Y)
            m_y.readFrom(r, tag);
        else if (tag == Tag::Z)
            m_z.readFrom(r, tag);
        else
            r->skipCurrentElement();
    }
}
