// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2007 Konrad Twardowski

#pragma once

#include "kshutdown.h"

#include <QComboBox>
#include <QGroupBox>
#include <QLCDNumber>
#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>

#ifdef Q_OS_WIN32
	#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
	#include <QWinTaskbarButton>
	#endif // QT_VERSION
#endif // Q_OS_WIN32

#ifdef KS_KF5
	#include <KActionCollection>
#endif // KS_KF5

class BookmarksMenu;
class ProgressBar;
class USystemTray;

class MainWindow final: public QMainWindow {
	friend class Mod;
	friend class TimeOption;
	friend class USystemTray;
	Q_OBJECT
	#ifdef KS_PURE_QT
	// compatible with KDE
	Q_CLASSINFO("D-Bus Interface", "net.sf.kshutdown.MainWindow")
	#endif // KS_PURE_QT
public:
	virtual ~MainWindow();

	InfoWidget *actionInfoWidget() { return m_actionInfoWidget; }
	InfoWidget *triggerInfoWidget() { return m_triggerInfoWidget; }

	QAction *cancelAction() const { return m_cancelAction; }
	QLCDNumber *countdown() const { return m_countdown; }
	Action *getSelectedAction() const;
	Trigger *getSelectedTrigger() const;
	static bool isInstance() { return m_instance != nullptr; }
	QPushButton *okCancelButton() { return m_okCancelButton; }
	std::shared_ptr<ProgressBar> progressBar() { return m_progressBar; }
	static MainWindow *self() {
		if (!m_instance)
			m_instance = new MainWindow();

		return m_instance;
	}
	bool maybeShow(const bool forceShow = false);
	void setProgressWidgetsVisible();
	void setTime(const QString &selectTrigger, const QTime &time);
	void showNotification(const QString &id);
	void showOrHide();
	USystemTray *systemTray() { return m_systemTray; }
	#ifdef Q_OS_WIN32
	#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
	QWinTaskbarButton *winTaskbarButton() { return m_winTaskbarButton; }
	#endif // QT_VERSION
	#endif // Q_OS_WIN32
public slots:
	Q_SCRIPTABLE QStringList actionList(const bool showDescription);
	Q_SCRIPTABLE QStringList triggerList(const bool showDescription);
	Q_SCRIPTABLE bool active() const { return m_active; }
	Q_SCRIPTABLE void setActive(const bool yes);
	Q_SCRIPTABLE void setExtrasCommand(const QString &command);
	Q_SCRIPTABLE void setSelectedAction(const QString &id);
	Q_SCRIPTABLE void setSelectedTrigger(const QString &id);
	Q_SCRIPTABLE void setTime(const QString &trigger, const QString &time);
	Q_SCRIPTABLE void setWaitForProcess(const qint64 pid);
	void writeConfig();
protected:
	virtual void closeEvent(QCloseEvent *e) override;
	#ifdef Q_OS_WIN32
	virtual void showEvent(QShowEvent *e) override;
	#endif // Q_OS_WIN32
private:
	Q_DISABLE_COPY(MainWindow)
#ifdef KS_KF5
	KActionCollection *m_actionCollection;
#endif // KS_KF5
	BookmarksMenu *m_bookmarksMenu;
	bool m_active;
	bool m_forceQuit;
	bool m_showActiveWarning;
	bool m_showMinimizeInfo;
	InfoWidget *m_actionInfoWidget;
	InfoWidget *m_triggerInfoWidget;
	inline static MainWindow *m_instance = nullptr;
	QAction *m_cancelAction;
	QAction *m_confirmLockAction;
	QComboBox *m_actions;
	QComboBox *m_triggers;
	QLCDNumber *m_countdown;
	QPushButton *m_okCancelButton;
	QString m_lastNotificationID = QString();
	QTimer *m_triggerTimer;
	QVBoxLayout *m_actionLayout;
	QVBoxLayout *m_triggerLayout;
	QWidget *m_currentActionWidget = nullptr;
	QWidget *m_currentTriggerWidget = nullptr;
	#ifdef Q_OS_WIN32
	#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
	QWinTaskbarButton *m_winTaskbarButton = nullptr;
	#endif // QT_VERSION
	#endif // Q_OS_WIN32
	std::shared_ptr<ProgressBar> m_progressBar;
	USystemTray *m_systemTray;
	explicit MainWindow();
	QAction *createQuitAction(const bool mainMenu);
	void initFileMenu(QMenu *fileMenu, const bool mainMenu);
	void initMenuBar();
	void initTriggers();
	void initWidgets();
	void onCheckTrigger();
	void readConfig();
	void replaceContainerWidget(Base *base);
	void setActive(const bool yes, const bool needAuthorization);
	void setTitle(const QString &plain, const QString &html);
	void updateWidgets();
private slots:
	void onActionActivated(int index);
#ifdef KS_KF5
	void onConfigureNotifications();
	void onConfigureShortcuts();
#endif // KS_KF5
	void onFocusChange(QWidget *old, QWidget *now);
	void onQuit();
	void onTriggerActivated(int index);
};
