#ifndef PQWIDGET_H
#define PQWIDGET_H

#include <QWidget>
#include "classes/pqobject.h"
#include "classes/pqwindow.h"

#define PQ_ENABLED_EVENTS

#define PQWIDGET_ON_SIGNALS() \
    PQ_ADD_ON_SIGNAL("onMousePressed", "mousePressed(int,int,int,int,int)");\
    PQ_ADD_ON_SIGNAL("onMouseClicked", "mouseClicked()");\
    PQ_ADD_ON_SIGNAL("onMouseReleased", "mouseReleased(int,int,int,int,int)");\
    PQ_ADD_ON_SIGNAL("onMouseMoved", "mouseMoved(int,int,int,int)");\
    PQ_ADD_ON_SIGNAL("onMouseDoubleClicked", "doubleClicked(int,int,int,int,int)");\
    PQ_ADD_ON_SIGNAL("onKeyPressed", "keyPressed(int,QString)");\
    PQ_ADD_ON_SIGNAL("onKeyReleased", "keyReleased(int,QString)");\
    PQ_ADD_ON_SIGNAL("onFocusIn", "on_focusIn()");\
    PQ_ADD_ON_SIGNAL("onFocusOut", "on_focusOut()");\
    PQ_ADD_ON_SIGNAL("onShow", "on_show()");\
    PQ_ADD_ON_SIGNAL("onHide", "on_hide()");\
    PQ_ADD_ON_SIGNAL("onResize", "on_resize(int,int,int,int)");\
    PQ_ADD_ON_SIGNAL("onClose", "on_close()");\
    PQ_ADD_ON_SIGNAL("onContextMenu", "on_contextMenu(int,int,int,int)");\
    PQ_ADD_ON_SIGNAL("onMouseEnter", "mouseEnter(int, int, int, int)");\
    PQ_ADD_ON_SIGNAL("onMouseLeave", "mouseLeave()");\
    PQ_ADD_ON_SIGNAL("onPaint", "on_paint()");

#define PQ_WIDGET_EX(T) \
    PQ_OBJECT_EX(T)\
    \
    Q_PROPERTY( int width READ width WRITE setWidth ) \
    Q_PROPERTY( int height READ height WRITE setHeight ) \
    Q_PROPERTY( int x READ x WRITE setX ) \
    Q_PROPERTY( int y READ y WRITE setY ) \
    Q_PROPERTY( bool enabled READ isEnabled WRITE setEnabled ) \
    Q_PROPERTY( bool disabled READ isDisabled WRITE setDisabled ) \
    Q_PROPERTY( bool hidden READ isHidden WRITE setHidden ) \
    Q_PROPERTY( bool visible READ isVisible WRITE setVisible ) \
    Q_PROPERTY( int toolTipDuration READ toolTipDuration WRITE setToolTipDuration ) \
    Q_PROPERTY( QString toolTip READ toolTip WRITE setToolTip ) \
    Q_PROPERTY( int minimumWidth READ minimumWidth WRITE setMinimumWidth ) \
    Q_PROPERTY( int maximumWidth READ maximumWidth WRITE setMaximumWidth ) \
    Q_PROPERTY( int minimumHeight READ minimumHeight WRITE setMinimumHeight ) \
    Q_PROPERTY( int maximumHeight READ maximumHeight WRITE setMaximumHeight ) \
    Q_PROPERTY( QSize maximumSize READ maximumSize WRITE setMaximumSize ) \
    Q_PROPERTY( QSize minimumSize READ minimumSize WRITE setMinimumSize ) \
    Q_PROPERTY( QString styleSheet READ styleSheet WRITE setStyleSheet ) \
    Q_PROPERTY( int cursor READ cursor WRITE setCursor ) \
    Q_PROPERTY( QWidget* parent READ parent WRITE setParent ) \
    Q_PROPERTY( bool lockParentClassEvents READ lockParentClassEvents WRITE setLockParentClassEvents ) \
    Q_PROPERTY( bool mouseTracking READ hasMouseTracking WRITE setMouseTracking ) \
    Q_PROPERTY( QLayout *layout READ layout WRITE setLayout ) \
    Q_PROPERTY( bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground ) \
    Q_PROPERTY( QString windowTitle READ windowTitle WRITE setWindowTitle ) \
    Q_PROPERTY( QString windowIcon READ windowIcon WRITE setWindowIcon ) \
    Q_PROPERTY( QString windowIconText READ windowIconText WRITE setWindowIconText ) \
    Q_PROPERTY( int windowFlags READ windowFlags WRITE setWindowFlags ) \
    Q_PROPERTY( double windowOpacity READ windowOpacity WRITE setWindowOpacity ) \
    Q_PROPERTY( int windowState READ windowState WRITE setWindowState ) \
    Q_PROPERTY( int windowModality READ windowModality WRITE setWindowModality ) \
    Q_PROPERTY( QRect frameGeometry READ frameGeometry ) \
    Q_PROPERTY( QRect geometry READ geometry WRITE setGeometry ) \
    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 long winId();\
    Q_INVOKABLE bool autoFillBackground();\
    Q_INVOKABLE void setPalette(const QString &color);\
    Q_INVOKABLE int x();\
    Q_INVOKABLE int y();\
    Q_INVOKABLE int width();\
    Q_INVOKABLE int height();\
    Q_INVOKABLE bool isEnabled();\
    Q_INVOKABLE bool isDisabled();\
    Q_INVOKABLE bool isHidden();\
    Q_INVOKABLE bool isVisible();\
    Q_INVOKABLE QString toolTip();\
    Q_INVOKABLE int toolTipDuration();\
    Q_INVOKABLE int minimumWidth();\
    Q_INVOKABLE int maximumWidth();\
    Q_INVOKABLE int minimumHeight();\
    Q_INVOKABLE int maximumHeight();\
    Q_INVOKABLE QString styleSheet();\
    Q_INVOKABLE void setCursor(int cursor);\
    Q_INVOKABLE int cursor();\
    Q_INVOKABLE void setSizePolicy(int horizontal, int vertical, int controlType);\
    Q_INVOKABLE void setSizePolicy(int horizontal, int vertical);\
    Q_INVOKABLE void setParent(QWidget *widget);\
    Q_INVOKABLE QWidget *parent();\
    Q_INVOKABLE void setMinimumSize(QSize size);\
    Q_INVOKABLE void setMaximumSize(QSize size);\
    Q_INVOKABLE void setFixedSize(int w, int h);\
    Q_INVOKABLE QSize minimumSize();\
    Q_INVOKABLE QSize maximumSize();\
    Q_INVOKABLE QPoint mapFromGlobal(int x, int y);\
    Q_INVOKABLE QPoint mapToGlobal(int x, int y);\
    Q_INVOKABLE QPoint mapFromParent(int x, int y);\
    Q_INVOKABLE QPoint mapToParent(int x, int y);\
    Q_INVOKABLE bool lockParentClassEvents();\
    Q_INVOKABLE bool hasMouseTracking();\
    Q_INVOKABLE void setLayout(QLayout *layout);\
    Q_INVOKABLE void setLayoutDirection(int direction);\
    Q_INVOKABLE QLayout *layout();\
    Q_INVOKABLE QString windowTitle();\
    Q_INVOKABLE QString windowIcon();\
    Q_INVOKABLE double windowOpacity();\
    Q_INVOKABLE int windowState();\
    Q_INVOKABLE int windowModality();\
    Q_INVOKABLE int windowFlags();\
    Q_INVOKABLE QString windowIconText();\
    Q_INVOKABLE QRect frameGeometry();\
    Q_INVOKABLE QRect geometry();\
    Q_INVOKABLE QSize frameSize();\
    Q_INVOKABLE void setGeometry(int x, int y, int w, int h);\
    Q_INVOKABLE void setGeometry(const QRect &rect);\
    /* void *getSignalPtr(QByteArray signalName);*/ \
public Q_SLOTS:\
    Q_INVOKABLE void setFocus();\
    Q_INVOKABLE void close();\
    Q_INVOKABLE void setAutoFillBackground(bool b);\
    Q_INVOKABLE void raise();\
    Q_INVOKABLE void grabMouse();\
    Q_INVOKABLE void releaseMouse();\
    Q_INVOKABLE void grabKeyboard();\
    Q_INVOKABLE void releaseKeyboard();\
    Q_INVOKABLE void lower();\
    Q_INVOKABLE void setWidth(int width);\
    Q_INVOKABLE void setHeight(int height);\
    Q_INVOKABLE void setX(int x);\
    Q_INVOKABLE void setY(int y);\
    Q_INVOKABLE void resize(int w, int h);\
    Q_INVOKABLE void move(int x, int y);\
    Q_INVOKABLE void hide();\
    Q_INVOKABLE void show();\
    Q_INVOKABLE void setDisabled(bool b);\
    Q_INVOKABLE void setEnabled(bool b);\
    Q_INVOKABLE void setHidden(bool b);\
    Q_INVOKABLE void setVisible(bool b);\
    Q_INVOKABLE void setToolTipDuration(int duration);\
    Q_INVOKABLE void setToolTip(QString text);\
    Q_INVOKABLE void repaint();\
    Q_INVOKABLE void setMinimumWidth(int minw);\
    Q_INVOKABLE void setMaximumWidth(int maxw);\
    Q_INVOKABLE void setMinimumHeight(int minh);\
    Q_INVOKABLE void setMaximumHeight(int maxh);\
    Q_INVOKABLE void setMinimumSize(int minw, int minh);\
    Q_INVOKABLE void setMaximumSize(int maxw, int maxh);\
    Q_INVOKABLE void setAttribute(int attribute, bool on);\
    Q_INVOKABLE void setAttribute(int attribute);\
    Q_INVOKABLE void setStyleSheet(QString styleSheet);\
    Q_INVOKABLE void setLockParentClassEvents(bool b);\
    Q_INVOKABLE void setMouseTracking(bool b);\
    Q_INVOKABLE void adjustSize();\
    Q_INVOKABLE void setWindowOpacity(double val);\
    Q_INVOKABLE void setWindowState(int i);\
    Q_INVOKABLE void setWindowModality(int i);\
    Q_INVOKABLE void setWindowFlags(int i);\
    Q_INVOKABLE void setWindowTitle(QString text);\
    Q_INVOKABLE void setWindowIcon(QString iconPath);\
    Q_INVOKABLE void setWindowIconText(QString text);\
    \
    /* 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;\
    /* ..... */\
    void doubleClicked_pslot(int x, int y, int globalX, int globalY, int button);\
    void mousePressed_pslot(int x, int y, int globalX, int globalY, int button);\
    void mouseReleased_pslot(int x, int y, int globalX, int globalY, int button);\
    void mouseMoved_pslot(int x, int y, int globalX, int globalY);\
    void keyPressed_pslot(int keyId, QString text);\
    void keyReleased_pslot(int keyId, QString text);\
    void mouseEnter_pslot(int x, int y, int globalX, int globalY);\
    void mouseLeave_pslot();\
    void mouseClicked_pslot();\
    void on_focusIn_pslot();\
    void on_focusOut_pslot();\
    void on_show_pslot();\
    void on_hide_pslot();\
    void on_resize_pslot(int x, int y, int oldX, int oldY);\
    void on_close_pslot();\
    void on_contextMenu_pslot(int x, int y, int globalX, int globalY);\
    void on_paint_pslot();\
    \
protected:\
    void mousePressEvent(QMouseEvent *event);\
    void mouseReleaseEvent(QMouseEvent *event);\
    void mouseMoveEvent(QMouseEvent *event);\
    void mouseDoubleClickEvent(QMouseEvent *event);\
    void keyPressEvent(QKeyEvent *event);\
    void keyReleaseEvent(QKeyEvent *event);\
    void focusInEvent(QFocusEvent *event);\
    void focusOutEvent(QFocusEvent *event);\
    void showEvent(QShowEvent *event);\
    void hideEvent(QHideEvent *event);\
    void resizeEvent(QResizeEvent *event);\
    void closeEvent(QCloseEvent *event);\
    void contextMenuEvent(QContextMenuEvent *event);\
    void enterEvent(QEvent *event);\
    void leaveEvent(QEvent *event);\
    void paintEvent(QPaintEvent *event);\
    /*bool event(QEvent *event);*/\
    \
Q_SIGNALS:\
    Q_INVOKABLE void doubleClicked(int, int, int, int, int);\
    Q_INVOKABLE void mousePressed(int, int, int, int, int);\
    Q_INVOKABLE void mouseReleased(int, int, int, int, int);\
    Q_INVOKABLE void mouseMoved(int, int, int, int);\
    Q_INVOKABLE void keyPressed(int, QString);\
    Q_INVOKABLE void keyReleased(int, QString);\
    Q_INVOKABLE void mouseEnter(int, int, int, int);\
    Q_INVOKABLE void mouseLeave();\
    Q_INVOKABLE void mouseClicked();\
    Q_INVOKABLE void on_focusIn();\
    Q_INVOKABLE void on_focusOut();\
    Q_INVOKABLE void on_show();\
    Q_INVOKABLE void on_hide();\
    Q_INVOKABLE void on_resize(int, int, int, int);\
    Q_INVOKABLE void on_close();\
    Q_INVOKABLE void on_contextMenu(int, int, int, int);\
    Q_INVOKABLE void on_paint();\
private:\
    QHash<int,bool> pqMouseClickEvent;\
    int pqCurrentCursor = Qt::ArrowCursor;\
    bool m_lockParentClassEvents = false;\
    QString mWindowIconPath = "";

class PQWidget;
class PQWidget : public QWidget {
    Q_OBJECT
    PQ_WIDGET_EX(QWidget)

public:
    Q_INVOKABLE explicit PQWidget(QWidget *parent = 0);
    virtual ~PQWidget();
};

Q_DECLARE_METATYPE(PQWidget*)

#endif // PQWIDGET_H
