/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/
#ifndef TESTCLASS_H_
#define TESTCLASS_H_

// -- QT stuff
#include <QObject>
#include <QVariant>
#include <QVector3D>
#include <QColor>
#include <QFont>
#include <QTime>

/** A little class with lots of properties.
  * There are static properties declared with Q_PROPERTY and
  * dynamic properties created at run-time.
  */
class TestClass : public QObject {
    Q_OBJECT

    /// declaration of a boolean property
    Q_PROPERTY(bool myBool READ getBool WRITE setBool);
    /// declaration of a double property
    Q_PROPERTY(double radius READ getRadius WRITE setRadius)
    /// A QVector3D property
    Q_PROPERTY(QVector3D position READ getPosition WRITE setPosition);
    /// declaration of a QString property
    Q_PROPERTY(QString name READ getName WRITE setName)

    /// declaration of a static QColor property (see also backgroundColor property)
    Q_PROPERTY(QColor color READ getColor WRITE setColor)

    /// declaration of a QFont property
    Q_PROPERTY(QFont font READ getFont WRITE setFont)

    /// declaration of a QTime property
    Q_PROPERTY(QTime time READ getTime WRITE setTime)

    /// declaration of an enum property (a property which value is in a particular set)
    Q_PROPERTY(StateLevel yourForm READ getLevel WRITE setLevel)

    /** Group some properties in a specific map. Pro: this allows one to show a hierarchy in the properties.
      * Cons: you have to manage the map yourself.
      * Note that the only supported type of map is QVariantMap which is a typedef
      * of QMap<QString, QVariant>.
      * In this group all other misc type of supported properties are demonstrated.
      * see QVariant
      */
    Q_PROPERTY(QVariantMap propertyGroup READ getGroup WRITE setGroup)

    /// this is to test a readonly property
    Q_PROPERTY(bool onWindows READ getOnWindows)

    /// declaration of a readonly int property
    Q_PROPERTY(int someNumber READ getSomeNumber)

public:
    enum StateLevel { I_AM_OK, GOOD_FORM, FEELING_GREAT, HAPPY, VERY_HAPPY };
    Q_ENUM(StateLevel)

    TestClass();
    ~TestClass() override = default;

    bool getBool() const {
        return myBool;
    };
    void setBool(bool newBool);

    double getRadius() const {
        return radius;
    }
    void setRadius(double radius);

    QVector3D getPosition() const {
        return position;
    };
    void setPosition(QVector3D newV3D);

    QString getName() const {
        return name;
    }
    void setName(const QString& name);

    QColor getColor() const {
        return color;
    }
    void setColor(const QColor& color);

    QFont getFont() const {
        return font;
    }
    void setFont(const QFont& font);

    QTime getTime() const {
        return time;
    }
    void setTime(const QTime& time);

    StateLevel getLevel() const {
        return yourForm;
    }
    void setLevel(StateLevel);


    QVariantMap getGroup() const {
        return propertyGroup;
    }
    void setGroup(const QVariantMap&);

    int getSomeNumber() const {
        return someNumber;
    }

    bool getOnWindows() const {
#if defined(_WIN32) || defined(__MINGW32__)
        return true;
#else
        return false;
#endif
    }

    /// intercept signal for dynamic property change.
    bool event(QEvent* e) override;

private:
    /// intern values for the static properties
    bool myBool;
    double radius;
    QVector3D position;
    QString name;
    QColor color;
    QFont font;
    QTime time;
    StateLevel yourForm;
    bool onWindows;
    int someNumber;
    QVariantMap propertyGroup;

    /// intern value for the dynamic property
    QColor backgroundColor;
};


#endif
