#include "peviewqt.h"

#include "peviewqtprivate.h"

#include <QMouseEvent>

PEViewQt::PEViewQt(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_PaintOnScreen);

    HWND hwnd = (HWND)this->winId();
    VsInital(hwnd);
    VsSetActiveWindow(hwnd);

    mView = new PEViewQtPrivate(hwnd);

    mTimer.setInterval(40);
    mTimer.start();

    connect(&mTimer, &QTimer::timeout, this, &PEViewQt::updateFrame);
}

PEViewQt::~PEViewQt()
{
    delete mView;
    mView = nullptr;
}

QPaintEngine *PEViewQt::paintEngine() const
{
    return nullptr;
}

void PEViewQt::updateFrame()
{
    DWORD t = VsGetTickCount();
    mView->m_tEventMgr.Tick(t);
}

UINT PEViewQt::qtButtonToWin32Button(Qt::MouseButtons mbs)
{
    UINT nFlags = 0;
    if (mbs & Qt::LeftButton)
    {
        nFlags |= MK_LBUTTON;
    }
    if (mbs & Qt::RightButton)
    {
        nFlags |= MK_RBUTTON;
    }
    if (mbs & Qt::MidButton)
    {
        nFlags |= MK_MBUTTON;
    }
    //    if (KEY_ISPRESSED_SHIFT) {
    //        nFlags |= MK_SHIFT;
    //    }
    //    if (KEY_ISPRESSED_CTRL) {
    //        nFlags |= MK_CONTROL;
    //    }
    //    if (KEY_ISPRESSED_ALT) {

    //    }

    return nFlags;
}

UINT PEViewQt::qtButtonToWin32Button(Qt::MouseButton mb)
{
    UINT nFlags = 0;
    if (mb == Qt::LeftButton)
    {
        nFlags |= MK_LBUTTON;
    }
    else if (mb == Qt::RightButton)
    {
        nFlags |= MK_RBUTTON;
    }
    else if (mb == Qt::MidButton)
    {
        nFlags |= MK_MBUTTON;
    }
    else if (mb == Qt::SHIFT)
    {
        nFlags |= MK_SHIFT;
    }
    else if (mb == Qt::CTRL)
    {
        nFlags |= MK_CONTROL;
    }
    else if (mb == Qt::ALT)
    {
    }

    return nFlags;
}

void PEViewQt::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint qpt = event->globalPos();
    POINT pt;
    pt.x = qpt.x();
    pt.y = qpt.y();
    mView->OnContextMenu(pt);
}

void PEViewQt::mousePressEvent(QMouseEvent *event)
{
    QPoint qpt = event->pos();
    POINT pt;
    pt.x = qpt.x();
    pt.y = qpt.y();

    Qt::MouseButtons mbs = event->buttons();
    UINT nFlags = qtButtonToWin32Button(mbs);

    if (mbs == Qt::LeftButton)
    {
        mView->OnLButtonDown(nFlags, pt);
    }
    else if (mbs == Qt::RightButton)
    {
        mView->OnRButtonDown(nFlags, pt);
    }
    else if (mbs == Qt::MidButton)
    {
        mView->OnMButtonDown(nFlags, pt);
    }

    QWidget::mousePressEvent(event);
}

void PEViewQt::mouseReleaseEvent(QMouseEvent *event)
{
    QPoint qpt = event->pos();
    POINT pt;
    pt.x = qpt.x();
    pt.y = qpt.y();
    Qt::MouseButton mb = event->button();
    UINT nFlags = qtButtonToWin32Button(mb);

    if (mb == Qt::LeftButton)
    {
        mView->OnLButtonUp(nFlags, pt);
    }
    else if (mb == Qt::RightButton)
    {
        mView->OnRButtonUp(nFlags, pt);
    }
    else if (mb == Qt::MidButton)
    {
        mView->OnMButtonUp(nFlags, pt);
    }

    VsInvalidate();

    QWidget::mouseReleaseEvent(event);
}

void PEViewQt::mouseDoubleClickEvent(QMouseEvent *event)
{
    QPoint qpt = event->pos();
    POINT pt;
    pt.x = qpt.x();
    pt.y = qpt.y();
    Qt::MouseButton mb = event->button();
    UINT nFlags = qtButtonToWin32Button(mb);

    if (mb == Qt::LeftButton)
    {
        mView->OnLButtonDblClk(nFlags, pt);
    }
    else if (mb == Qt::RightButton)
    {
        // mView->OnRButtonDblClk(nFlags, pt);
    }
    else if (mb == Qt::MidButton)
    {
        mView->OnMButtonDblClk(nFlags, pt);
    }

    VsInvalidate();

    QWidget::mouseDoubleClickEvent(event);
}

void PEViewQt::mouseMoveEvent(QMouseEvent *event)
{
    QPoint qpt = event->pos();
    POINT pt;
    pt.x = qpt.x();
    pt.y = qpt.y();
    UINT nFlags = qtButtonToWin32Button(event->buttons());

    mView->OnMouseMove(nFlags, pt);

    VsInvalidate();

    QWidget::mouseMoveEvent(event);
}

void PEViewQt::wheelEvent(QWheelEvent *event)
{
    QPoint qpt = event->pos();
    POINT pt;
    pt.x = qpt.x();
    pt.y = qpt.y();
    UINT nFlags = qtButtonToWin32Button(event->buttons());

    mView->OnMouseWheel(nFlags, event->delta(), pt);

    VsInvalidate();

    QWidget::wheelEvent(event);
}

void PEViewQt::keyPressEvent(QKeyEvent *event)
{
    UINT nChar = event->nativeVirtualKey();
    UINT nRepCnt = event->count();
    UINT nFlags = 0;

    mView->OnKeyDown(nChar, nRepCnt, nFlags);

    QWidget::keyPressEvent(event);
}

void PEViewQt::keyReleaseEvent(QKeyEvent *event)
{
    UINT nChar = event->nativeVirtualKey();
    UINT nRepCnt = event->count();
    UINT nFlags = 0;

    mView->OnKeyUp(nChar, nRepCnt, nFlags);

    QWidget::keyReleaseEvent(event);
}
