#ifndef FMP_WINDOW_H
#define FMP_WINDOW_H

#include <QWidget>
#include <QJsonObject>
#include <QDesktopWidget>
#include <QPainter>
#include <QStyleOption>
#include <QMap>


#ifdef Q_OS_WIN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <windowsx.h>
#endif

class FMPWindow : public QWidget
{
public:
    explicit FMPWindow(QWidget *parent = 0) : QWidget(parent)
    {
        setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
        setAttribute(Qt::WA_QuitOnClose, false);
        setAttribute(Qt::WA_DeleteOnClose, true);
    }
    virtual  ~FMPWindow() {}

#ifdef Q_OS_WIN

public:
    virtual void    show()
    {
        showNormal();
        ::SetForegroundWindow((HWND)effectiveWinId());

        ::SetWindowPos( (HWND)effectiveWinId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);

        showNormal();
        ::SetForegroundWindow((HWND)effectiveWinId());

        QDesktopWidget w;
        QRect rc = w.availableGeometry();
        setGeometry((rc.width() - width()) / 2, (rc.height() - height()) / 2, width(), height());

        return QWidget::show();
    }

protected:
    bool            nativeEvent(const QByteArray &eventType, void *message, long *result)
    {
        Q_UNUSED(eventType);
        MSG *msg = (MSG*)message;
        //! true indicates the message need to be processed by DefWindowProc
        bool fCallDWP = true;
        bool fMsgDone = false;
        switch (msg->message)  {
        case WM_NCHITTEST:  {
            *result = winNCHitTest(msg);
            if (*result != HTNOWHERE)  {
                // HTMINBUTTON 等消息当作HTCLIENT处理
                switch (*result)  {
                case HTMINBUTTON:
                case HTMAXBUTTON:
                case HTCLOSE:
                    *result = HTCLIENT;
                    break;
                }

                fCallDWP = false;
            }

            break;
        }
        case WM_GETMINMAXINFO:  {
            // 最大化时的处理
            MINMAXINFO *mmi = (MINMAXINFO*) (msg->lParam);

            QDesktopWidget desktopWidget;
            QRect desktop = desktopWidget.availableGeometry();

            mmi->ptMaxSize.x = desktop.width();
            mmi->ptMaxSize.y = desktop.height();

            mmi->ptMaxPosition.x = desktop.x();
            mmi->ptMaxPosition.y = desktop.y();

            mmi->ptMinTrackSize.x = minimumWidth();   // minimum width for your window
            mmi->ptMinTrackSize.y = minimumHeight();   // minimum height for your window

            mmi->ptMaxTrackSize.x = maximumWidth();
            mmi->ptMaxTrackSize.y = maximumHeight();

            *result = 0;
            fMsgDone = true;
            break;
        }

        default:
            break;
        }
        fMsgDone = fMsgDone || !fCallDWP;
        return fMsgDone;
    }

    void            paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
        QStyleOption  opt;
        opt.init(this);
        QPainter  p(this);
        style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    }
protected:
    long            winNCHitTest(MSG *msg)
    {
        // Mouse position
        QPoint mouse_pos(GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam));
        QRect window_rect = geometry();

        // Set default value (HTNOWHERE) (1,1).
        USHORT uRow = 1;
        USHORT uCol = 1;
        bool fOnResizeBorder = false;

        //! Test caption area
        QRegion m_children_region(0, 0, width() - 54, 60);
        QRegion new_region = m_children_region.translated(window_rect.x() , window_rect.y());
        if (new_region.contains(mouse_pos))  {
            //! Title regions contains the mouse position, treat it as caption area
            uRow = 0;
        }

        // Hit test (HTTOPLEFT, ... HTBOTTOMRIGHT)
        LRESULT hitTests[3][3] =
        {
            { HTTOPLEFT,    fOnResizeBorder ? HTTOP : HTCAPTION,    HTTOPRIGHT },
            { HTLEFT,       HTNOWHERE,     HTRIGHT },
            { HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT },
        };

        //! Test borders area
        if (minimumSize() != maximumSize())  {
            //! To be implemented
        }

        return hitTests[uRow][uCol];
    }

#endif
};

#endif // FMP_WINDOW_H
