#ifndef PQAPPLICATION_H
#define PQAPPLICATION_H

#include <QApplication>
#include "classes/pqobject.h"

class PQApplication;
class PQApplication : public QApplication {
    Q_OBJECT
    PQ_OBJECT_EX(QApplication)

    Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)

    Q_PROPERTY( QString fontFamily READ fontFamily WRITE setFontFamily )
    Q_PROPERTY( bool fontItalic READ fontItalic WRITE setFontItalic )
    Q_PROPERTY( int fontPointSize READ fontPointSize WRITE setFontPointSize )
    Q_PROPERTY( int fontPixelSize READ fontPixelSize WRITE setFontPixelSize )
    Q_PROPERTY( bool fontUnderline READ fontUnderline WRITE setFontUnderline )
    Q_PROPERTY( int fontWeight READ fontWeight WRITE setFontWeight )

public:
    Q_INVOKABLE explicit PQApplication(int argc, char **argv);
    virtual ~PQApplication();

    Q_INVOKABLE int exec();
    Q_INVOKABLE int desktopHeight(int screen = -1);
    Q_INVOKABLE int desktopWidth(int screen = -1);
    Q_INVOKABLE int applicationPid();
    Q_INVOKABLE void aboutQt();
    Q_INVOKABLE void alert(QWidget *widget, int msec = 0);
    Q_INVOKABLE void closeAllWindows();
    Q_INVOKABLE void beep();
    Q_INVOKABLE void setActiveWindow(QWidget *widget);
    Q_INVOKABLE QWidget *widgetAt(int x, int y);
    Q_INVOKABLE QWidget *activeWindow();
    Q_INVOKABLE QClipboard *clipboard();

    Q_INVOKABLE bool quitOnLastWindowClosed();
    Q_INVOKABLE void setQuitOnLastWindowClosed(bool quit);

    Q_INVOKABLE bool isQuitLockEnabled();
    Q_INVOKABLE void setQuitLockEnabled(bool enabled);

    Q_INVOKABLE QString applicationName();
    Q_INVOKABLE void setApplicationName(const QString &applicationName);

    Q_INVOKABLE QString applicationVersion();
    Q_INVOKABLE void setApplicationVersion(const QString &version);

    Q_INVOKABLE QString organizationName();
    Q_INVOKABLE void setOrganizationName(const QString &orgName);

    Q_INVOKABLE QString organizationDomain();
    Q_INVOKABLE void setOrganizationDomain(const QString &orgDomain);

    Q_INVOKABLE QString applicationDirPath();
    Q_INVOKABLE QString applicationFilePath();

    Q_INVOKABLE void processEvents(int flags = QEventLoop::AllEvents);
    Q_INVOKABLE void processEvents(int flags, int maxtime);

    Q_INVOKABLE QString styleSheet() const;

    /* FONTS */
    Q_INVOKABLE void setFontFamily(const QString &fontFamily);
    Q_INVOKABLE void setFontItalic(bool italic);
    Q_INVOKABLE void setFontPointSize(double size);
    Q_INVOKABLE void setFontPixelSize(int size);
    Q_INVOKABLE void setFontUnderline(bool underline);
    Q_INVOKABLE void setFontWeight(int weight);
    Q_INVOKABLE QString fontFamily() const;
    Q_INVOKABLE bool fontItalic() const;
    Q_INVOKABLE int fontPointSize() const;
    Q_INVOKABLE int fontPixelSize() const;
    Q_INVOKABLE bool fontUnderline() const;
    Q_INVOKABLE int	fontWeight() const;
    /* ..... */

    bool notify(QObject * receiver, QEvent * event) {
        try {
            return QApplication::notify(receiver, event);
        } catch(std::exception& e) {
            pq_ub_write(QString("Qt exception thrown: %1").arg(e.what()));
        }
        catch (...) {
            pq_ub_write(QString("Unexpected application error"));
        }

        return false;
    }

public Q_SLOTS:
    Q_INVOKABLE void quit();
    Q_INVOKABLE void setStyleSheet(const QString &styleSheet);

    void focusChanged_pslot(QWidget *old, QWidget *now);
};

#endif // PQAPPLICATION_H

