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

#ifndef BORNAGAIN_GUI_MODEL_DETECTOR_RECTANGULARDETECTORITEM_H
#define BORNAGAIN_GUI_MODEL_DETECTOR_RECTANGULARDETECTORITEM_H

#include "Device/Detector/RectangularDetector.h"
#include "GUI/Model/Data/ComboProperty.h"
#include "GUI/Model/Descriptor/VectorProperty.h"
#include "GUI/Model/Detector/DetectorItem.h"

class RectangularDetectorItem : public DetectorItem {
public:
    RectangularDetectorItem();

    void writeTo(QXmlStreamWriter* w) const override;
    void readFrom(QXmlStreamReader* r) override;

    int xSize() const override { return m_xSize; }
    void setXSize(size_t nx) override { m_xSize = static_cast<int>(nx); }

    int ySize() const override { return m_ySize; }
    void setYSize(size_t ny) override { m_ySize = static_cast<int>(ny); }

    DoubleProperty& width() { return m_width; }
    const DoubleProperty& width() const { return m_width; }
    void setWidth(double v) { m_width.setValue(v); }

    DoubleProperty& height() { return m_height; }
    const DoubleProperty& height() const { return m_height; }
    void setHeight(double v) { m_height.setValue(v); }

    const ComboProperty& detectorAlignmentCombo() const { return m_detectorAlignment; }
    RectangularDetector::EDetectorArrangement detectorAlignment() const;
    void setDetectorAlignment(const QString& alignment);
    void setDetectorAlignment(RectangularDetector::EDetectorArrangement alignment);

    VectorProperty& normalVector() { return m_normalVector; }
    const VectorProperty& normalVector() const { return m_normalVector; }
    void setNormalVector(const R3& v) { m_normalVector.setR3(v); }

    VectorProperty& directionVector() { return m_directionVector; }
    const VectorProperty& directionVector() const { return m_directionVector; }
    void setDirectionVector(const R3& v) { m_directionVector.setR3(v); }

    DoubleProperty& u0() { return m_u0; }
    const DoubleProperty& u0() const { return m_u0; }
    void setU0(double v) { m_u0.setValue(v); }

    DoubleProperty& v0() { return m_v0; }
    const DoubleProperty& v0() const { return m_v0; }
    void setV0(double v) { m_v0.setValue(v); }

    DoubleProperty& distance() { return m_distance; }
    const DoubleProperty& distance() const { return m_distance; }
    void setDistance(double v) { m_distance.setValue(v); }

    bool isExpandXaxis() const { return m_expandXaxis; }
    void setExpandXaxis(bool b) { m_expandXaxis = b; }

    bool isExpandYaxis() const { return m_expandYaxis; }
    void setExpandYaxis(bool b) { m_expandYaxis = b; }

private:
    std::unique_ptr<IDetector> createDomainDetector() const override;
    void updateTooltips();

private:
    ComboProperty m_detectorAlignment;
    int m_xSize;
    int m_ySize;

    VectorProperty m_normalVector;
    VectorProperty m_directionVector;

    DoubleProperty m_width;
    DoubleProperty m_height;
    DoubleProperty m_u0;
    DoubleProperty m_v0;
    DoubleProperty m_distance;

    bool m_expandXaxis = true;
    bool m_expandYaxis = true;
};

#endif // BORNAGAIN_GUI_MODEL_DETECTOR_RECTANGULARDETECTORITEM_H
