/**
** This file is owned by VisualGear Technology Co., Ltd.
** Unauthorized copying of this file, via any medium is strictly prohibited
** Otherwise VisualGear Technology Co., Ltd. will have the right to pursue
** maximum responsibilities within scope of legal.
**
** Copyright 2018-2025 VisualGear All rights reserved.
**/

#pragma once

#include <QtWidgets/QFrame>
#include <QtWidgets/QWidget>
#include "UIGQWidgetBase.h"
#include "UIGQCheckBox.h"
#include "UIGQComboBox.h"
#include "UIGQLabel.h"
#include "UIGQLineEdit.h"
#include "UIGQProgressBar.h"
#include "UIGQPushButton.h"
#include "UIGQRadioButton.h"
#include "UIGQSpinBox.h"
#include "UIGQSwitch.h"
#include "UIGQTabWidget.h"

namespace Json
{
	class Value;
}

namespace UIGQtLib
{
	class UIGQRibbonBar;
	class UIGQRibbonArea;
	class UIGQRibbonGroup;
	class UIGQRibbonPage;
	class UIGQRibbonPanel;
	class UIGQRibbonBarImpl;

	enum UIG_RIBBON_BUTTON_STYLE
	{
		UIG_COMMON_BTN = 0,
		UIG_SPLIT_BTN,
		UIG_TOGGLE_BTN,
		UIG_PANEL,
		UIG_ROWPANEL,
		UIG_LARGE_BTN,
		UIG_SMALL_BTN
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonPushButton : public UIGQPushButton
	{
	public:
		UIGQRibbonPushButton(QWidget* pParent = nullptr, UIG_RIBBON_BUTTON_STYLE style = UIG_LARGE_BTN);
		~UIGQRibbonPushButton();

		void setRibbonButtonStyle(UIG_RIBBON_BUTTON_STYLE style);
		UIG_RIBBON_BUTTON_STYLE ribbonButtonStyle() const;
		virtual QSize sizeHint() const override;

	private:
		UIG_RIBBON_BUTTON_STYLE _style;
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonRowPanel : public QWidget
	{
	public:
		UIGQRibbonRowPanel(QWidget* pParent = nullptr);
		~UIGQRibbonRowPanel();

		UIGQPushButton* addButton(UIG_RIBBON_BUTTON_STYLE style = UIG_SMALL_BTN);
		virtual QSize sizeHint() const override;

	protected:
		void resizeEvent(QResizeEvent* event) override;

	protected:
		QVector<QWidget*> _panelCtls;
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonPanel : public UIGQRibbonRowPanel
	{
	public:
		UIGQRibbonPanel(QWidget* pParent = nullptr);
		~UIGQRibbonPanel();

		bool isVertical() const;
		UIGQRibbonRowPanel* addRowPanel(int id);
		virtual QSize sizeHint() const override;

		friend class UIGQRibbonGroup;

	private:
		bool _isVertical;
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonGroup : public QFrame
	{
	public:
		UIGQRibbonGroup(const QString& groupName = QString(), QWidget* pParent = nullptr);
		~UIGQRibbonGroup();

		QString groupText() const;
		void setGroupText(const QString& text);
		UIGQRibbonPanel* addPanel(int id);
		UIGQRibbonPanel* addVerticalPanel(int id);
		UIGQPushButton* addButton(const QString& text, UIG_RIBBON_BUTTON_STYLE style = UIG_LARGE_BTN);
		UIGQComboBox* addComboBox(const QStringList& items = QStringList());
		UIGQProgressBar* addProgressBar(int value = 0, int minimum = 0, int maximum = 100);
		UIGQCheckBox* addCheckBox(const QString& text);
		UIGQRadioButton* addRadioButton(const QString& text);
		UIGQLabel* addLabel(const QString& text);
		UIGQLineEdit* addLineEdit(const QString& text = QString());
		UIGQSpinBox* addSpinBox(int value = 0, int minimum = 0, int maximum = 100);
		UIGQSwitch* addSwitch(bool checked = false);
		void addSeparator();
		virtual QSize sizeHint() const override;
		void updateLayout(int rowCount, int contentHeight);

		friend class UIGQRibbonPage;

	protected:
		void paintEvent(QPaintEvent* event) override;
		void resizeEvent(QResizeEvent* event) override;

	private:
		QString _text;
		QVector<QWidget*> _items;
		QVector<UIGQRibbonPanel*> _panels;
		UIGQRibbonPage* _parentPage;
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonPage : public QWidget
	{
	public:
		UIGQRibbonPage(const QString& pageName = QString(), QWidget* pParent = nullptr);
		~UIGQRibbonPage();

		QString pageName() const;
		QString displayName() const;
		void setDisplayName(const QString& displayName);
		int getGroupCount() const;
		UIGQRibbonGroup* getGroup(int index);
		bool removeGroup(UIGQRibbonGroup*);
		UIGQRibbonGroup* addGroup(const QString& groupName);
		void clearGroups();
		void updateLayout();
		virtual QSize sizeHint() const override;

		friend class UIGQRibbonGroup;
		friend class UIGQRibbonArea;

	private:
		QString _name;
		QString _displayName;
		UIGQRibbonArea* _parentArea;
		QVector<UIGQRibbonGroup*> _groups;
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonArea : public QWidget
	{
	public:
		UIGQRibbonArea(QWidget* pParent = nullptr);
		~UIGQRibbonArea();

		UIGQRibbonPage* addPage(const QString& pageName);
		void clearPages();
		UIGQRibbonBar* getRibbonBar() { return _parentRibbon; }
		UIGQRibbonPage* pageAt(int index) const;
		int pageCount() const;
		void setCurrentPage(int index);
		void updateLayout();

		friend class UIGQRibbonBar;
		friend class UIGQRibbonPage;

	protected:
		void paintEvent(QPaintEvent* event) override;
		void resizeEvent(QResizeEvent* event) override;

	private:
		UIGQRibbonBar* _parentRibbon;
		QVector<UIGQRibbonPage*> _pages;
		int _currentPage;
	};

	class UIGEARSQTLIB_EXPORT UIGQRibbonBar : public QWidget, public IUIGQWidgetBase
	{
		Q_OBJECT

	public:
		UIGQRibbonBar(QWidget* pParent = nullptr);
		~UIGQRibbonBar();

		UIG_QT_CTRL_DEF("qtribbonbar", UIGQRibbonBar);

		UIGQRibbonPage* addPage(const QString& pageName);
		void clearPages();
		bool setCurrentPage(int index);
		int currentPage() const;
		void setMinimized(bool minimized);
		bool isMinimized() const;
		bool loadConfigFile(const QString& filePath);
		bool loadConfigJson(const QString& jsonData);
		void updateLayout();

		void paintArea(UIGQRibbonArea* pArea);
		void paintGroup(UIGQRibbonGroup* pGroup);

	Q_SIGNALS:
		void currentPageChanged(int index);
		void minimizedChanged(bool minimized);

	protected:
		void paintEvent(QPaintEvent* event) override;
		void resizeEvent(QResizeEvent* event) override;

	private:
		UIGQRibbonBarImpl* _ctrlImpl;
		UIGQRibbonArea* _ribbonArea;
		UIGQTabWidget* _tabBar;
		QVector<UIGQRibbonPage*> _pages;
		QVector<QWidget*> _topLeftItems;
		QVector<QWidget*> _topRightItems;
		bool _updatingTabSelection;
		bool _minimized;
		bool _showMenuBar;
		int _groupHeight;
		int _groupRowCount;
		int _tabHeight;
		int _tabItemWidth;
		int _topBarHeight;

		friend class UIGQRibbonBarImpl;
		friend class UIGQRibbonArea;
		friend class UIGQRibbonPage;
		friend class UIGQRibbonGroup;

		void clearTopBarItems();
		QWidget* createRibbonItem(const Json::Value& item, QWidget* parent, UIGQRibbonGroup* group = nullptr);
		void loadTopBarItems(const Json::Value& root);

		UIGQT_GET_CONTROLBASE;
	};
}
