#ifndef BOXINGSETTINGS_H
#define BOXINGSETTINGS_H

#include <QString>
#include <QStringList>
#include <QSettings>
#include <QList>

#ifdef QT_DEBUG
    #include <QDebug>
#endif

/**
 * @group QML Part of view
 */

/**
 * @brief Handle settings about timer. Can save, load and delete a specific preset.
 */
class BoxingSettings : public QSettings {
        Q_OBJECT

        /** @cond */
        Q_PROPERTY(QString preset READ getPreset WRITE setPreset NOTIFY presetChanged)
        Q_PROPERTY(QString presetName READ getPresetName NOTIFY presetChanged)
        Q_PROPERTY(int rounds READ getRounds WRITE setRounds NOTIFY presetChanged)
        Q_PROPERTY(int roundsMs READ getRoundMilliseconds WRITE setRoundMilliseconds NOTIFY presetChanged)
        Q_PROPERTY(int restMs READ getRestMilliseconds WRITE setRestMilliseconds NOTIFY presetChanged)
        Q_PROPERTY(QList<int> innerTimers READ getInnerTimers NOTIFY presetChanged)
        /** @endcond */

        /**
         * @var const int DefaultRounds
         * @brief Default number of rounds
         */
        const int DefaultRounds = 12;

        /**
         * @var const int DefaultRoundMilliseconds
         * @brief Default milliseconds for rounds
         */
        const int DefaultRoundMilliseconds = 3 * 60 * 1000;
        /**
         * @var const int DefaultRestMilliseconds
         * @brief Default milliseconds for rest
         */
        const int DefaultRestMilliseconds = 60 * 1000;

        /**
         * @var const QString DefaultPreset
         * @brief Default preset
         */
        const QString DefaultPreset = "";

        /**
         * @var const QString DefaultPresetName
         * @brief Default preset name
         */
        const QString DefaultPresetName = "Default";

    public:
        /**
         * @addtogroup QML
         * @fn const QStringList presetsList()
         *
         * @author Claudio Maradonna <claudio@unitoo.pw>
         * @return a list with available (probably saved) presets
         */
        Q_INVOKABLE const QStringList presetsList();

        /**
         * @addtogroup QML
         * @fn void savePreset(const QString &name, const int &rounds, const int &roundMilliseconds, const int &restMilliseconds)
         * @param name string name of preset
         * @param rounds int number of rounds
         * @param roundMilliseconds int duration of round
         * @param restMilliseconds int duration of rest
         *
         * @author Claudio Maradonna <claudio@unitoo.pw>
         *
         * @brief Save or override settings about specific preset
         */
        Q_INVOKABLE void savePreset(const QString &name, const int &rounds, const int &roundMilliseconds, const int &restMilliseconds, const QList<int> &innerTimers);

        /**
         * @addtogroup QML
         * @fn void deletePreset(const QString &name)
         * @param name string name of preset
         *
         * @author Claudio Maradonna <claudio@unitoo.pw>
         *
         * @brief Delete a specified preset
         */
        Q_INVOKABLE void deletePreset(const QString &name);

        /**
         * @brief getInnerTimer(const int &index)
         *
         * @return the specific timer in milliseconds
         */
        Q_INVOKABLE int getInnerTimer(const int &index);

        BoxingSettings();
        BoxingSettings(const int &rounds, const int &roundMilliseconds, const int &restMilliseconds);

        /**
         * @fn int getRounds()
         *
         * @return number of rounds
         */
        inline int getRounds() { return this->mRounds; }

        /**
         * @fn int getRoundMilliseconds()
         *
         * @return duration in milliseconds of a rounds
         */
        inline int getRoundMilliseconds() { return this->mRoundMilliseconds; }

        /**
         * @fn int getRestMilliseconds()
         *
         * @return milliseconds of rest
         */
        inline int getRestMilliseconds() { return this->mRestMilliseconds; }

        /**
         * @brief gerInnerTimers()
         *
         * @return the list of inner timers
         */
        inline QList<int> getInnerTimers() { return this->mInnerTimers; }

        /**
         * @fn QString getPreset()
         *
         * @return the loaded preset
         */
        inline QString getPreset() { return this->mPreset; }

        /**
         * @fn QString getPresetName()
         *
         * @return the human readable name of preset
         */
        inline QString getPresetName() { return this->mPresetName; }

        /**
         * @fn void setRounds(const int &rounds)
         * @param rounds int
         *
         * @brief Setter for number of rounds
         */
        inline void setRounds(const int &rounds) { mRounds = rounds; }

        /**
         * @fn void setRoundMilliseconds(const int &roundMilliseconds)
         * @param roundMilliseconds int
         *
         * @brief Setter for duration of round (in milliseconds)
         */
        inline void setRoundMilliseconds(const int &roundMilliseconds) { mRoundMilliseconds = roundMilliseconds; }

        /**
         * @fn void setRestMilliseconds(const int &restMilliseconds)
         * @param restMilliseconds int
         *
         * @brief Setter for milliseconds of rest
         */
        inline void setRestMilliseconds(const int &restMilliseconds) { mRestMilliseconds = restMilliseconds; }

        /**
         * @fn void setPreset(const QString &preset)
         * @param preset QString
         *
         * @brief Setter for preset
         */
        void setPreset(const QString &preset);

    private:
        int mRounds;
        int mRoundMilliseconds;
        int mRestMilliseconds;

        QList<int> mInnerTimers;

        QString mPreset;
        QString mPresetName;

        /**
         * @fn void loadPreset()
         *
         * @brief Load settings about preset
         */
        void loadPreset();

        /**
         * @fn void setDefaultPreset()
         *
         * @brief Load default preset
         */
        void setDefaultPreset();

        /**
         * @fn const QString convertRichNameToGroup(const QString &richName)
         * @param richName const QString
         *
         * @brief Convert the human readable name in preset loadable name
         */
        inline const QString convertRichNameToGroup(const QString &richName) { return richName.toLower().simplified().replace(" ", ""); }

    signals:
        void presetChanged();
};

#endif // BOXINGSETTINGS_H
