/**
 * Copyright (c) 2022
 *    Marcus Britanicus (https://gitlab.com/marcusbritanicus)
 *    Abrar (https://gitlab.com/s96Abrar)
 *    rahmanshaber (https://gitlab.com/rahmanshaber)
 *
 * The DFL::Settings expands the QSettings class.
 * For use with DFL.
 **/

#pragma once

#include <QString>
#include <QMap>
#include <QSize>
#include <QFont>
#include <QRect>
#include <QVariant>
#include <QSettings>
#include <QFileSystemWatcher>

namespace DFL {
    class Settings;
    class SettingsImpl;
}

class DFL::Settings : public QObject {
    Q_OBJECT;

    public:

        /*
         * @project -> Project like DesQ or Oyster
         * @app -> Settings of a specific app: Like Files, Term, Shell, etc...
         * @ConfigPath -> Path where the global config might be strored.
         */
        Settings( QString project, QString app, QString cfgPath = "/usr/share" );

        struct Proxy {
            QVariant value;

            operator int() const {
                return value.toInt();
            }

            operator float() const {
                return value.toReal();
            }

            operator double() const {
                return value.toDouble();
            }

            operator bool() const {
                return value.toBool();
            }

            operator QString() const {
                return value.toString();
            }

            operator QStringList() const {
                return value.value<QStringList>();
            }

            operator QSize() const {
                return value.toSize();
            }

            operator QFont() const {
                return value.value<QFont>();
            }

            operator QRect() const {
                return value.toRect();
            }

            operator QVariant() const {
                return value;
            }
        };

        Proxy value( const QString& key );
        void setValue( const QString& key, QVariant value );

        QStringList allKeys() const;
        bool hasKey( QString ) const;

    private:
        QFileSystemWatcher *watcher;
        DFL::SettingsImpl *impl;

    private Q_SLOTS:
        void emitSettings();

    Q_SIGNALS:
        void settingChanged( QString, QVariant );
        void restartApp();
};
