#ifndef PQWIDGET_PRIVATE_H
#define PQWIDGET_PRIVATE_H

#include "classes/pqwidget.h"
#include "classes/pqobject_private.h"

#include <QKeyEvent>
#include <QWidget>
#include <QMouseEvent>
#include <QEvent>
#include <QEnterEvent>
#include <QPainter>
#include <QList>
#include <QPalette>
#include <QDebug>

#define PQWIDGET_STANDARD_METHODS(Q)\
    PQOBJECT_STANDARD_METHODS(Q,Q)\
    \
    long P##Q::winId() { return Q::winId(); }\
    bool P##Q::autoFillBackground() {\
        return Q::autoFillBackground();\
    }\
    void P##Q::setPalette(const QString &color) {\
        Q::setPalette(QPalette(QColor(color)));\
    }\
    int P##Q::x() {\
        return Q::x();\
    }\
    int P##Q::y() {\
        return Q::y();\
    }\
    int P##Q::width() {\
        return Q::width();\
    }\
    int P##Q::height() {\
        return Q::height();\
    }\
    bool P##Q::isEnabled() {\
        return Q::isEnabled();\
    }\
    bool P##Q::isDisabled() {\
        return !Q::isEnabled();\
    }\
    bool P##Q::isHidden() {\
        return Q::isHidden();\
    }\
    bool P##Q::isVisible() {\
        return Q::isVisible();\
    }\
    QString P##Q::toolTip() {\
        return Q::toolTip();\
    }\
    int P##Q::toolTipDuration() {\
        return Q::toolTipDuration();\
    }\
    int P##Q::minimumWidth() {\
        return Q::minimumWidth();\
    }\
    int P##Q::maximumWidth() {\
        return Q::maximumWidth();\
    }\
    int P##Q::minimumHeight() {\
        return Q::minimumHeight();\
    }\
    int P##Q::maximumHeight() {\
        return Q::maximumHeight();\
    }\
    QString P##Q::styleSheet() { \
        return Q::styleSheet(); \
    } \
    void P##Q::setCursor(int cursor) { \
        pqCurrentCursor = Qt::CursorShape(cursor); \
        Q::setCursor(Qt::CursorShape(cursor)); \
    } \
    int P##Q::cursor() { \
        return pqCurrentCursor;\
    } \
    void P##Q::setSizePolicy(int horizontal, int vertical, int controlType) { \
        Q::setSizePolicy(QSizePolicy(QSizePolicy::Policy(horizontal),\
                                        QSizePolicy::Policy(vertical),\
                                        QSizePolicy::ControlType(controlType)));\
    } \
    void P##Q::setSizePolicy(int horizontal, int vertical) { \
        Q::setSizePolicy(QSizePolicy::Policy(horizontal),\
                                        QSizePolicy::Policy(vertical));\
    } \
    void P##Q::setParent(QWidget *widget) { \
        Q::setParent(widget);\
    } \
    QWidget *P##Q::parent() { \
        return qobject_cast<QWidget*>(Q::parent());\
    } \
    void P##Q::setMinimumSize(QSize size) {\
        Q::setMinimumSize(size);\
    }\
    void P##Q::setMaximumSize(QSize size) {\
        Q::setMaximumSize(size);\
    }\
    void P##Q::setFixedSize(int w, int h) {\
        Q::setFixedSize(w, h);\
    }\
    QSize P##Q::minimumSize() {\
        return Q::minimumSize();\
    }\
    QSize P##Q::maximumSize() {\
        return Q::maximumSize();\
    }\
    QPoint P##Q::mapFromGlobal(int x, int y) {\
        return Q::mapFromGlobal(QPoint(x, y));\
    }\
    QPoint P##Q::mapToGlobal(int x, int y) {\
        return Q::mapToGlobal(QPoint(x, y));\
    }\
    QPoint P##Q::mapFromParent(int x, int y) {\
        return Q::mapFromParent(QPoint(x, y));\
    }\
    QPoint P##Q::mapToParent(int x, int y) {\
        return Q::mapToParent(QPoint(x, y));\
    }\
    bool P##Q::lockParentClassEvents() {\
        return m_lockParentClassEvents;\
    }\
    bool P##Q::hasMouseTracking() {\
        return Q::hasMouseTracking();\
    }\
    void P##Q::setLayout(QLayout *layout) {\
        Q::setLayout(layout);\
    }\
    void P##Q::setLayoutDirection(int direction) {\
        Q::setLayoutDirection(Qt::LayoutDirection(direction));\
    }\
    QLayout *P##Q::layout() {\
        return Q::layout();\
    }\
    void P##Q::setFocus() {\
        Q::setFocus();\
    }\
    void P##Q::close() {\
        Q::close();\
    }\
    void P##Q::setAutoFillBackground(bool b) {\
        Q::setAutoFillBackground(b);\
    }\
    void P##Q::raise() {\
        Q::raise();\
    }\
    void P##Q::grabMouse() {\
        Q::grabMouse();\
    }\
    void P##Q::releaseMouse() {\
        Q::releaseMouse();\
    }\
    void P##Q::grabKeyboard() {\
        Q::grabKeyboard();\
    }\
    void P##Q::releaseKeyboard() {\
        Q::releaseKeyboard();\
    }\
    void P##Q::lower() {\
        Q::lower();\
    }\
    void P##Q::setWidth(int width) {\
        Q::resize(width, height());\
    }\
    void P##Q::setHeight(int height) {\
        Q::resize(width(), height);\
    }\
    void P##Q::setX(int x) {\
        Q::move(x, y());\
    }\
    void P##Q::setY(int y) {\
        Q::move(x(), y);\
    }\
    void P##Q::resize(int w, int h) {\
        Q::resize(w, h);\
    }\
    void P##Q::move(int x, int y) {\
        Q::move(x, y);\
    }\
    void P##Q::hide() {\
        Q::hide();\
    }\
    void P##Q::show() {\
        Q::show();\
    }\
    void P##Q::setDisabled(bool b) {\
        Q::setEnabled(!b);\
    }\
    void P##Q::setEnabled(bool b) {\
        Q::setEnabled(b);\
    }\
    void P##Q::setHidden(bool b) {\
        Q::setHidden(b);\
    }\
    void P##Q::setVisible(bool b) {\
        Q::setVisible(b);\
    }\
    void P##Q::setToolTipDuration(int duration) {\
        Q::setToolTipDuration(duration);\
    }\
    void P##Q::setToolTip(QString text) {\
        Q::setToolTip(text);\
    }\
    void P##Q::repaint() {\
        Q::repaint();\
    }\
    void P##Q::setMinimumWidth(int minw) {\
        Q::setMinimumWidth(minw);\
    }\
    void P##Q::setMaximumWidth(int maxw) {\
        Q::setMaximumWidth(maxw);\
    }\
    void P##Q::setMinimumHeight(int minh) {\
        Q::setMinimumHeight(minh);\
    }\
    void P##Q::setMaximumHeight(int maxh) {\
        Q::setMaximumHeight(maxh);\
    }\
    void P##Q::setMinimumSize(int minw, int minh) {\
        Q::setMinimumSize(minw, minh);\
    }\
    void P##Q::setMaximumSize(int maxw, int maxh) {\
        Q::setMaximumSize(maxw, maxh);\
    }\
    void P##Q::setAttribute(int attribute, bool on) { \
        Q::setAttribute(Qt::WidgetAttribute(attribute), on); \
    } \
    void P##Q::setAttribute(int attribute) { \
        Q::setAttribute(Qt::WidgetAttribute(attribute)); \
    } \
    void P##Q::setStyleSheet(QString styleSheet) { \
        Q::setStyleSheet(styleSheet); \
    } \
    void P##Q::setLockParentClassEvents(bool b) {\
        m_lockParentClassEvents = b;\
    }\
    void P##Q::setMouseTracking(bool b) {\
        Q::setMouseTracking(b);\
    }\
    void P##Q::adjustSize() {\
        Q::adjustSize();\
    }\
    QString P##Q::windowTitle() {\
        return Q::windowTitle();\
    }\
    QString P##Q::windowIcon() {\
        return mWindowIconPath;\
    }\
    double P##Q::windowOpacity() {\
        return Q::windowOpacity();\
    }\
    int P##Q::windowState() {\
        return Q::windowState();\
    }\
    int P##Q::windowModality() {\
        return Q::windowModality();\
    }\
    int P##Q::windowFlags() {\
        return Q::windowFlags();\
    }\
    QString P##Q::windowIconText() {\
        return Q::windowIconText();\
    }\
    QRect P##Q::frameGeometry() {\
        return Q::frameGeometry();\
    }\
    QRect P##Q::geometry() {\
        return Q::geometry();\
    }\
    QSize P##Q::frameSize() {\
        return Q::frameSize();\
    }\
    void P##Q::setGeometry(int x, int y, int w, int h) {\
        Q::setGeometry(QRect(x,y,w,h));\
    }\
    void P##Q::setGeometry(const QRect &rect) {\
        Q::setGeometry(rect);\
    }\
    void P##Q::setWindowOpacity(double val) {\
        Q::setWindowOpacity(val);\
    }\
    void P##Q::setWindowState(int i) {\
        Q::setWindowState(Qt::WindowState(i));\
    }\
    void P##Q::setWindowModality(int i) {\
        Q::setWindowModality(Qt::WindowModality(i));\
    }\
    void P##Q::setWindowFlags(int i) {\
        Q::setWindowFlags(Qt::WindowFlags(i));\
    }\
    void P##Q::setWindowTitle(QString text) {\
        Q::setWindowTitle(text);\
    }\
    void P##Q::setWindowIcon(QString iconPath) {\
        mWindowIconPath = iconPath;\
        Q::setWindowIcon(QIcon(iconPath));\
    }\
    void P##Q::setWindowIconText(QString text) {\
        Q::setWindowIconText(text);\
    }\
    void P##Q::setFontFamily(const QString &fontFamily) {\
        QFont font = Q::font();\
        font.setFamily(fontFamily);\
        Q::setFont(font);\
    }\
    void P##Q::setFontItalic(bool italic) {\
        QFont font = Q::font();\
        font.setItalic(italic);\
        Q::setFont(font);\
    }\
    void P##Q::setFontPointSize(double size) {\
        QFont font = Q::font();\
        font.setPointSize(size);\
        Q::setFont(font);\
    }\
    void P##Q::setFontPixelSize(int size) {\
        QFont font = Q::font();\
        font.setPixelSize(size);\
        Q::setFont(font);\
    }\
    void P##Q::setFontUnderline(bool underline) {\
        QFont font = Q::font();\
        font.setUnderline(underline);\
        Q::setFont(font);\
    }\
    void P##Q::setFontWeight(int weight) {\
        QFont font = Q::font();\
        font.setWeight(weight);\
        Q::setFont(font);\
    }\
    QString P##Q::fontFamily() const {\
        return Q::font().family();\
    }\
    bool P##Q::fontItalic() const {\
        return Q::font().italic();\
    }\
    int P##Q::fontPointSize() const {\
        return Q::font().pointSize();\
    }\
    int P##Q::fontPixelSize() const {\
        return Q::font().pixelSize();\
    }\
    bool P##Q::fontUnderline() const {\
        return Q::font().underline();\
    }\
    int	P##Q::fontWeight() const {\
        return Q::font().weight();\
    }\
    void P##Q::mousePressEvent(QMouseEvent *event) {\
        pqMouseClickEvent.insert((int) event->button(), true);\
        emit mousePressed((int)event->x(), (int)event->y(), (int)event->globalX(), (int)event->globalY(), (int)event->button());\
        if(!m_lockParentClassEvents) Q::mousePressEvent(event);\
    }\
    void P##Q::mouseReleaseEvent(QMouseEvent *event) {\
        if(pqMouseClickEvent.contains((int) event->button())) {\
            if(pqMouseClickEvent.value((int) event->button()) == true) {\
                emit mouseClicked();\
            }\
            pqMouseClickEvent.remove((int) event->button());\
        }\
        emit mouseReleased(event->x(), event->y(), event->globalX(), event->globalY(), (int) event->button());\
        if(!m_lockParentClassEvents) Q::mouseReleaseEvent(event);\
    }\
    void P##Q::mouseMoveEvent(QMouseEvent *event) {\
        pqMouseClickEvent.remove((int) event->button());\
        emit mouseMoved(event->x(), event->y(), event->globalX(), event->globalY());\
        if(!m_lockParentClassEvents) Q::mouseMoveEvent(event);\
    }\
    void P##Q::mouseDoubleClickEvent(QMouseEvent *event) {\
        pqMouseClickEvent.remove((int) event->button());\
        emit doubleClicked(event->x(), event->y(), event->globalX(), event->globalY(), (int) event->button());\
        if(!m_lockParentClassEvents) Q::mouseDoubleClickEvent(event);\
    }\
    void P##Q::keyPressEvent(QKeyEvent *event) {\
        emit keyPressed(event->key(), event->text());\
        if(!m_lockParentClassEvents) Q::keyPressEvent(event);\
    }\
    void P##Q::keyReleaseEvent(QKeyEvent *event) {\
        emit keyReleased(event->key(), event->text());\
        if(!m_lockParentClassEvents) Q::keyReleaseEvent(event);\
    }\
    void P##Q::focusInEvent(QFocusEvent *event) {\
        emit on_focusIn();\
        if(!m_lockParentClassEvents) Q::focusInEvent(event);\
    }\
    void P##Q::focusOutEvent(QFocusEvent *event) {\
        emit on_focusOut();\
        if(!m_lockParentClassEvents) Q::focusOutEvent(event);\
    }\
    void P##Q::showEvent(QShowEvent *event) {\
        emit on_show();\
        if(m_useEventListener && m_eventListenerTypes.contains(event->type())) {\
            if(pq_send_event(this, event)) {\
                return; \
            }\
        }\
        Q::showEvent(event);\
    }\
    void P##Q::hideEvent(QHideEvent *event) {\
        emit on_hide();\
        if(m_useEventListener && m_eventListenerTypes.contains(event->type())) {\
            if(pq_send_event(this, event)) {\
                return; \
            }\
        }\
        Q::hideEvent(event);\
    }\
    void P##Q::resizeEvent(QResizeEvent *event) {\
        emit on_resize(event->size().width(), event->size().height(), event->oldSize().width(), event->oldSize().height());\
        if(!m_lockParentClassEvents) Q::resizeEvent(event);\
    }\
    void P##Q::closeEvent(QCloseEvent *event) {\
        emit on_close();\
        if(!m_lockParentClassEvents) Q::closeEvent(event);\
    }\
    void P##Q::contextMenuEvent(QContextMenuEvent *event) {\
        emit on_contextMenu(event->x(), event->y(), event->globalX(), event->globalY());\
        if(!m_lockParentClassEvents) Q::contextMenuEvent(event);\
    }\
    void P##Q::enterEvent(QEvent *event) {\
        if(!m_lockParentClassEvents) Q::enterEvent(event);\
    }\
    void P##Q::leaveEvent(QEvent *event) {\
        emit mouseLeave();\
        if(!m_lockParentClassEvents) Q::leaveEvent(event);\
    }\
    void P##Q::paintEvent(QPaintEvent *event) {\
        emit on_paint();\
        return Q::paintEvent(event);\
    }\
    /*bool P##Q::event(QEvent *event) {\
        if(!mPHPEL.isEmpty()\
            && mPHPEventListenerTypes.contains(event->type())) {\
    qDebug() << "EVENT!";\
            if (pq_callPHPFunction(mPHPEL, this, event)) return true;\
        }\
        \
        return Q::event(event);\
    }*/\
    void P##Q::doubleClicked_pslot(int x, int y, int globalX, int globalY, int button) {\
        QVariantList args; \
        args << x << y << globalX << globalY << button; \
        PHPQt5Connection_invoke(this, "doubleClicked(int,int,int,int,int)", args);\
    }\
    void P##Q::mousePressed_pslot(int x, int y, int globalX, int globalY, int button) {\
        QVariantList args; \
        args << x << y << globalX << globalY << button; \
        PHPQt5Connection_invoke(this, "mousePressed(int,int,int,int,int)", args);\
    }\
    void P##Q::mouseReleased_pslot(int x, int y, int globalX, int globalY, int button) {\
        QVariantList args; \
        args << x << y << globalX << globalY << button; \
        PHPQt5Connection_invoke(this, "mouseReleased(int,int,int,int,int)", args);\
    }\
    void P##Q::mouseMoved_pslot(int x, int y, int globalX, int globalY) {\
        QVariantList args; \
        args << x << y << globalX << globalY; \
        PHPQt5Connection_invoke(this, "mouseMoved(int,int,int,int)", args);\
    }\
    void P##Q::keyPressed_pslot(int keyId, QString text) {\
        QVariantList args; \
        args << keyId << text; \
        PHPQt5Connection_invoke(this, "keyPressed(int,QString)", args);\
    }\
    void P##Q::keyReleased_pslot(int keyId, QString text) {\
        QVariantList args; \
        args << keyId << text; \
        PHPQt5Connection_invoke(this, "keyReleased(int,QString)", args);\
    }\
    void P##Q::mouseEnter_pslot(int x, int y, int globalX, int globalY) {\
        QVariantList args; \
        args << x << y << globalX << globalY; \
        PHPQt5Connection_invoke(this, "mouseEnter(int,int,int,int)", args);\
    }\
    void P##Q::mouseLeave_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "mouseLeave()", args);\
    }\
    void P##Q::mouseClicked_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "mouseClicked()", args);\
    }\
    void P##Q::on_focusIn_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "on_focusIn()", args);\
    }\
    void P##Q::on_focusOut_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "on_focusOut()", args);\
    }\
    void P##Q::on_show_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "on_show()", args);\
    }\
    void P##Q::on_hide_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "on_hide()", args);\
    }\
    void P##Q::on_resize_pslot(int x, int y, int oldX, int oldY) {\
        QVariantList args; \
        args << x << y << oldX << oldY; \
        PHPQt5Connection_invoke(this, "on_resize(int,int,int,int)", args);\
    }\
    void P##Q::on_close_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "on_close()", args);\
    }\
    void P##Q::on_contextMenu_pslot(int x, int y, int globalX, int globalY) {\
        QVariantList args; \
        args << x << y << globalX << globalY; \
        PHPQt5Connection_invoke(this, "on_contextMenu(int,int,int,int)", args);\
    }\
    void P##Q::on_paint_pslot() {\
        QVariantList args; \
        PHPQt5Connection_invoke(this, "on_paint()", args);\
    }\
    P##Q::~P##Q() {}

#endif // PQWIDGET_PRIVATE_H

