#ifndef QSR_RIBBON_CORE_H
#define QSR_RIBBON_CORE_H

#include <QObject>
#include <QToolBar>
#include <QList>
#include <QLabel>
#include <QAction>
#include <QPainter>
#include <QStyleOption>
#include <QAbstractNativeEventFilter>

    

/*
*  当前的程序主要是运行在windows系统下， 如果运行在Linux下还需要进行优化，比如主界面的外框等
*/

// 从大于0的开始， RIBBON开始的是控件，三级的归属于二级
//（暂时还没有使用）
enum RIBBON_OBJECT_TYPE  // RIBBON 对象
{
	RIBBON_OBJECTITEM = 0,
    RIBBON_TITLEBAR_QuickAccessBar,   // 标题栏上左侧的 快捷图标
	RIBBON_TITLEBAR_Title,            // 标题栏的 标题
	RIBBON_TITLEBAR_UserInfo,         // 标题栏上的 用户信息
	RIBBON_TITLEBAR_StanderdButton,   // 标题栏上的 右侧按钮
	RIBBON_TITLEBAR, // 以上是标题栏的内容
	RIBBON_MENUBAR_WidgetActionLeft,  // 比如word中的“文件”按钮
	RIBBON_MENUBAR_WidgetActionRight, // 右侧的按钮
	RIBBON_MENUBAR, // 以上是菜单栏的内容
	RIBBON_TOOLBAR_GroupWidget, // 工具栏的控件容器（如 word中的“段落”为一组）
	RIBBON_TOOLBAR_IconWidget,  // 大图标缩略图
	RIBBON_TOOLBAR_Saperator,   // 工具栏控件容器中的分隔线
	RIBBON_TOOLBAR,// 以上是工具栏的内容
	RIBBON_CONTRAL_Control // 具体的控件
};

#include <QPushButton>

/** @brief   Ribbon操作.
*  @details  一个操作对应一个图标，或者控件
*/
typedef QWidget ribbonAction;


/** @brief   Ribbon Widget 的基类.
*  @details  为了实现Qss对QWidget的重绘
*/
class      RobbonWidget :public QWidget
{
public:
	RobbonWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
	~RobbonWidget();

protected:
	virtual void paintEvent(QPaintEvent *event);

private:

};

//////////////////////////////////////////////////////////////////////////

// 需要自定义一套按钮，用来显示/隐藏 图标、文字， 参考之前实现的那个按钮的代码
/** @brief   RibbonControlBase 控件基类.
*  @details  
*/
class      RibbonControlBase
{
public:
	RibbonControlBase();
	~RibbonControlBase();

	/** @brief   设置控件在GroupWidget中的位置，有两套位置可以设置.
	*   @details 如果只有一种布局则不需要设置index参数.
	*/
	void setGroupPos(QPoint tPos, int index = -1);
	QPoint groupPos(int index);

    virtual void setText(QString &text) {};
    virtual void setIcon(const QIcon &icon) {};
    virtual void setEnabled(bool &tEnabled) {};


private:
	QPoint m_pos0, m_pos1;

};



/** @brief   RibbonPushButton 普通Ribbon按钮类.
*  @details
*/
class      RibbonToolButton : public QPushButton, public RibbonControlBase
{
	Q_OBJECT
public:
	RibbonToolButton(QWidget *parent = Q_NULLPTR);
	RibbonToolButton(const QString &text, QWidget *parent = Q_NULLPTR);
	RibbonToolButton(const QIcon &icon, const QString &text, QWidget *parent = Q_NULLPTR);
	~RibbonToolButton();

	void setTxtVisible(bool tVal);
	bool txtVisible();

	/** @brief   对齐方式. */
	void setAlignment(Qt::Alignment flag);

	/** @brief   设置Action.  //放弃使用： 不再接受从外部赋值 */
    //void setAction(QAction* tAction);
	/** @brief   获取Action. 用于从Ribbon风格切换到传统样式的菜单工具栏等 */
    QAction* getAction();

    virtual void setText(QString &text);
    virtual void setIcon(const QIcon &icon);
    virtual void setEnabled(bool &tEnabled);

private:
	QString m_text;
	bool m_txtVisible;

	/** @brief   Action指针，从外部指定.  */
    QAction* m_action;

// private:
// 	RIBBON_OBJECT_TYPE m_objType;
};

/** @brief   RibbonPushButton 大的Ribbon按钮类.
*  @details
*/
class      RibbonToolButtonBig : public RobbonWidget, public RibbonControlBase
{
	Q_OBJECT
public:
	RibbonToolButtonBig(const QIcon &icon, const QString &text, QWidget *parent = Q_NULLPTR);
	~RibbonToolButtonBig();

	QPushButton* pushButton() const;
	QLabel* label() const;
	void setExtentIconVisible(bool tVal);

    virtual void setText(QString &text) {};
    virtual void setIcon(const QIcon &icon){};
    virtual void setEnabled(bool &tEnabled){};


signals:
    void triggered(bool checked = false);

private:
	QPushButton* m_pushButton;
	QLabel* m_label, *m_label_extent;
};


// class      ribbonAction: public QWidget
// {
// 	Q_OBJECT
// public:
// 	ribbonAction();
// 	~ribbonAction() {};
// 
// private:
// 
// 
// };

//基类
// class      QsrRibbonObject
// {
// public:
// 	QsrRibbonObject() {};
// 	~QsrRibbonObject() {};
// };

class      QsrRibbonQuickAccessToolBar : /*public QsrRibbonObject,*/ public QToolBar
{
	Q_OBJECT
public:
	QsrRibbonQuickAccessToolBar() ;
	~QsrRibbonQuickAccessToolBar() {};
};

/** @brief   标题栏.
*  @details  标题栏的组成(从左到右): 快捷工具栏，标题控件，用户信息控件，系统按钮（放置系统按钮：设置、最小化、最大化、关闭）
*/
class      QsrRibbonTitleBar : /*public QsrRibbonObject ,*/ public RobbonWidget
{
	Q_OBJECT
public:
	QsrRibbonTitleBar();
	~QsrRibbonTitleBar();

	/** @brief  设置窗口标题.
	*
	*  @details 设置窗口标题.
	*  @param   title 窗口的标题.
	*  @return  .
	*/
	void setTitle(QString title);
	QString getTitle();

	/** @brief  设置工具条的文字. */
	void setToolsText(QString txt);

	void addQuickAction(QAction *action);
	void addSysAction(QAction* action);

	void setUserInfo(QString txt);

private:
	QLabel* m_titleLable1, m_ToolsLabel, m_titleLable2;
	QLabel* m_userInfoLabel;
	QsrRibbonQuickAccessToolBar* m_quickAccessToolBar, *m_systemButton;
};


/** @brief   Ribbon 操作组.
*  @details  Ribbon 操作组
*/
#include <QGridLayout>
#include <QActionGroup>
class      QtbGroupWidget :  public RobbonWidget
{
	Q_OBJECT
public:
	QtbGroupWidget();
	~QtbGroupWidget();

	void setTitle(QString tTitle);
	void addAction(ribbonAction* rAct, int row, int col, int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = Qt::Alignment());
	void addAction(RibbonToolButton* rAct, int row, int col, int rowSpan /*= 1*/, int columnSpan /*= 1*/, Qt::Alignment alignment /*= Qt::Alignment()*/);

    QActionGroup* getActionGroup() const;
protected:
	virtual void paintEvent(QPaintEvent *event);
private:
	QGridLayout* m_gridLayout;
	QLabel* m_groupTitleLabel;

    QActionGroup* m_actionGroup;
};

/** @brief   Ribbon菜单栏.
*  @details  Ribbon菜单栏
*/
#include <QMap>
#include <QHBoxLayout>
#include <QTabBar>
#include <QTabWidget>
#include <QStackedWidget>
class      QtbMenuBar : /*public QsrRibbonObject ,*/ public RobbonWidget
{
	Q_OBJECT
public:
	QtbMenuBar();
	~QtbMenuBar();

	/** @brief   增加操作按钮.  */
	void addAction(ribbonAction* tAction,int tIndex);
	/** @brief   增加菜单. menuName是唯一的，也是显示的 */
	void addMenu(QString menuName);

	/** @brief   增加扩展型菜单. menuName是全局唯一的，showName是显示的可以重复 */
//     void addExtendedMenu(QString menuName, QString showName);
	void setMenuVisible(QString menuName, bool tIsVisible);
	bool isMenuVisible(QString menuName);

	QtbGroupWidget* addGroup(QString menuName, QString txtGroupTitle);
    void menuReady(QString menuName);

	void setExtentBtnIcon(QIcon icoExtent, QIcon icoHide);

	bool isToolBarVisible();
public slots:
	void setToolBarVisible(bool tVal);

private slots:
    /** @brief   Ribbon工具栏折叠/展开按钮的操作.  */
	void onExtentToggled();
	void onCurrentTabChenged(int index);

protected:
	virtual void enterEvent(QEvent *event);
	virtual void leaveEvent(QEvent *event);

private:
    /** @brief   菜单栏的TabBar.  */
    QTabBar* m_menuTabBar;
    QTabBar* m_ExtentedMenuTabBar;
    /** @brief   Ribbon菜单的主layout.  */
	QHBoxLayout* m_layout;
    /** @brief   Ribbon菜单的主layout.  */
	QMap<QString, RobbonWidget*> m_StaWidMap;

    /* 暂时不提供扩展型的可变菜单*/
//     QHBoxLayout* m_layoutExtented;
//     /** @brief   Ribbon扩展菜单的按钮.  */
//     QMap<QString, QPushButton*> m_extentedBtnMap;
//     QWidget* m_extentedWidget;

	QStackedWidget* m_toolBarStackedWid;

	/** @brief   折叠按钮.  */
	RibbonToolButton* m_extentBtn; 

	bool m_toolBarVisible;

	QIcon m_icoExtent, m_icoHide;

};

/** @brief   Ribbon工具栏.
*  @details  Ribbon工具栏.
*/
class      QtbToolBar : /*public QsrRibbonObject ,*/ public QTabWidget
{
	Q_OBJECT
public:
	QtbToolBar();
	~QtbToolBar();

	void addMenu(QString txt);
private:
// 	QTabBar m_menuTabBar;
// 	QHBoxLayout m_layout;
// 	QMap<QString, RobbonWidget*> m_menuLabelMap;
//	QTabWidget* m_toolTabWidget;
};



/** @brief   主窗口.
*  @details  
*/
#include <QDragMoveEvent>
class QsfWorkWindow;
class QDockWidget;
//#include "SgfParamManager.h"
class      QtbMainWindow :  public RobbonWidget //, public SgfParamManager
{
	Q_OBJECT
public:
	QtbMainWindow(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
	~QtbMainWindow();

	QsrRibbonTitleBar* titleBar();
	QtbMenuBar* menuBar();

	/** @brief 创建DockWidget. */
	QDockWidget* createDockWidget(QString title, QString name, Qt::DockWidgetArea area);

	/** @brief 创建工作页Widget. */
	QWidget* createWorkWidget(QString title, QString name);
	/** @brief 添加已有的widget作为工作页Widget. */
    void addWorkWidget(QWidget* tWidget);


private:
	QsrRibbonTitleBar* m_titleBar;
	QtbMenuBar* m_menuBar;

protected:

	/** @brief  标题范围. */
	QRect m_titleRect;

	/** @brief  工作窗口. */
	QsfWorkWindow* m_workWindow;


	/** @brief  鼠标上一次的位置. */
	QPoint oldMousePos;
	/** @brief  鼠标单击. */
	void mousePressEvent(QMouseEvent *event);
	/** @brief  鼠标上双击. */
	void mouseDoubleClickEvent(QMouseEvent * event);
	/** @brief  鼠标拖动. */
	void mouseMoveEvent(QMouseEvent *event);

	virtual void resizeEvent(QResizeEvent *event);

    virtual void paintEvent(QPaintEvent *event);


public slots:
	void onSkin();
};

/** @brief   主窗口借助dwmapi实现在windows下的拖动
*  @details  Linux下的暂时没有做实现。次出应当用宏来统一windows和linux
*/
#include <windowsx.h>
#include <dwmapi.h>
class NativeEventFilter : public QAbstractNativeEventFilter
{
public:
    bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) Q_DECL_OVERRIDE
    {
#ifdef Q_OS_WIN
        if (eventType != "windows_generic_MSG")
            return false;

        MSG* msg = static_cast<MSG*>(message);
        QWidget* widget0 = QWidget::find(reinterpret_cast<WId>(msg->hwnd));
        if (widget0 == NULL)
            return false;

        QtbMainWindow* widget = static_cast<QtbMainWindow*>(widget0);
        if (!widget)
            return false;

        if (widget->isMaximized())
            return false;

        switch (msg->message) 
        {
        //         case WM_NCCALCSIZE: {  // 如果处理该消息，dock窗口或子窗口会有问题
        //             *result = 0;
        //             return true;
        //         }

            case WM_NCHITTEST: {
                const LONG borderWidth = 9;
                RECT winrect;
                GetWindowRect(msg->hwnd, &winrect);
                long x = GET_X_LPARAM(msg->lParam);
                long y = GET_Y_LPARAM(msg->lParam);

                // bottom left
                if (x >= winrect.left && x < winrect.left + borderWidth &&
                    y < winrect.bottom && y >= winrect.bottom - borderWidth)
                {
                    *result = HTBOTTOMLEFT;
                    return true;
                }

                // bottom right
                if (x < winrect.right && x >= winrect.right - borderWidth &&
                    y < winrect.bottom && y >= winrect.bottom - borderWidth)
                {
                    *result = HTBOTTOMRIGHT;
                    return true;
                }

                // top left
                if (x >= winrect.left && x < winrect.left + borderWidth &&
                    y >= winrect.top && y < winrect.top + borderWidth)
                {
                    *result = HTTOPLEFT;
                    return true;
                }

                // top right
                if (x < winrect.right && x >= winrect.right - borderWidth &&
                    y >= winrect.top && y < winrect.top + borderWidth)
                {
                    *result = HTTOPRIGHT;
                    return true;
                }

                // left
                if (x >= winrect.left && x < winrect.left + borderWidth)
                {
                    *result = HTLEFT;
                    return true;
                }

                // right
                if (x < winrect.right && x >= winrect.right - borderWidth)
                {
                    *result = HTRIGHT;
                    return true;
                }

                // bottom
                if (y < winrect.bottom && y >= winrect.bottom - borderWidth)
                {
                    *result = HTBOTTOM;
                    return true;
                }

                // top
                if (y >= winrect.top && y < winrect.top + borderWidth)
                {
                    *result = HTTOP;
                    return true;
                }

                return false;
            }
            default:
                break;
        }

        return false;
#else
        return false;
#endif
    }
};






























#endif //QSF_TITLEBAR_H
