/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright(C) 2009,...,2018 Filippo Rusconi
 *
 * http://www.msxpertsuite.org
 *
 * This file is part of the msXpertSuite project.
 *
 * The msXpertSuite project is the successor of the massXpert project. This
 * project now includes various independent modules:
 *
 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * END software license
 */



#pragma once



/////////////////////// Qt includes
#include <QObject>
#include <QMainWindow>
#include <QHash>
#include <QMap>


/////////////////////// Local includes
#include <minexpert/nongui/globals.hpp>

#include <minexpert/gui/AnalysisPreferencesDlg.hpp>
#include <minexpert/gui/AnalysisPreferencesDlg.hpp>

#include <minexpert/gui/AbstractPlotWidget.hpp>

#include <minexpert/gui/ConsoleWnd.hpp>
#include <minexpert/gui/ScriptingWnd.hpp>
#include <minexpert/gui/TicChromWnd.hpp>
#include <minexpert/gui/DriftSpecWnd.hpp>
#include <minexpert/gui/MassSpecWnd.hpp>
#include <minexpert/gui/ColorMapWnd.hpp>
#include <minexpert/gui/XicExtractionWnd.hpp>
#include <minexpert/gui/MzIntegrationParamsWnd.hpp>
#include <minexpert/nongui/MassSpecDataSet.hpp>
#include <minexpert/gui/OpenSpectraDlg.hpp>
#include <minexpert/nongui/MassSpecDataFileLoaderSqlite3.hpp>
#include <minexpert/gui/DataPlotWidgetRelation.hpp>
#include <minexpert/gui/SqlMassDataSlicerWnd.hpp>


namespace msXpSmineXpert
{


	class MainWindow : public QMainWindow
	{
		Q_OBJECT

		private:

			//! The name of the module, at the moment massXpert or mineXpert.
			QString m_moduleName;

			bool m_isScriptedOperation = false;

		public:

			//! DataPlotWidgetRelationer instance responsible for maintaining plot widget relations.
			DataPlotWidgetRelationer m_dataPlotWidgetRelationer;

			//! Dialog window where to configure the data analysis options.
			AnalysisPreferencesDlg *mp_analysisPrefDlg = Q_NULLPTR;

			//! TIC chromatogram window where all the TIC data are to be displayed.
			TicChromWnd *mp_ticChromWnd = Q_NULLPTR;

			//! Mass spectrum window where all the mass spectra are to be displayed.
			MassSpecWnd *mp_massSpecWnd = Q_NULLPTR;

			//! Drift spectrum window where all the drift spectra are to be displayed.
			DriftSpecWnd *mp_driftSpecWnd = Q_NULLPTR;

			//! Color map window where all the mz=f(dt) color maps are to be displayed.
			ColorMapWnd *mp_colorMapWnd = Q_NULLPTR;

			//! Console window where the feedback messages are to be printed.
			ConsoleWnd *mp_consoleWnd = Q_NULLPTR;

			//! Scripting window where all the scripting activity is performed.
			ScriptingWnd *mp_scriptingWnd = Q_NULLPTR;

			//! XIC extraction configuration window.
			XicExtractionWnd* mp_xicExtractionWnd = Q_NULLPTR;

			//! Mz integration configuration window
			MzIntegrationParamsWnd *mp_mzIntegrationParamsWnd = Q_NULLPTR;

			//! Sql data slicer configuration window.
			SqlMassDataSlicerWnd *mp_sqlMassDataSlicerWnd = Q_NULLPTR;


			// Dialog window displaying all the currently opened data files in a list widget.
			/*!

				The dialog window has a drop down menu allowing to take actions against
				the items in the list widget, like hiding, showing, closing.

*/
			OpenSpectraDlg *mp_openSpectraDlg = Q_NULLPTR;

			//! Minimum value of the progress bar in the status bar.
			int m_progressFeedbackStartValue = -1;
			//! Maximum value of the progress bar in the status bar.
			int m_progressFeedbackEndValue = -1;

			//! Progress bar that is shown in the status bar.
			QProgressBar *mp_statusBarProgressBar = Q_NULLPTR;

			//! Click on that button to let the program know that the running operation should be cancelled.
			QPushButton *mp_statusBarCancelPushButton = Q_NULLPTR;

			//! Label that is shown in the status bar.
			QLabel *mp_statusBarLabel = Q_NULLPTR;

			//! Tell if the running operation should be cancelled.
			bool m_isOperationCancelled = false;

			//! Analysis preferences.
			AnalysisPreferences *mpa_analysisPreferences = Q_NULLPTR;

			//! File in which to record the analysis steps.
			QFile m_analysisFile;

			//! List of colors that might be used to plot graphs.
			QList<QColor *> m_colorList;
			//! List of colors already used to plot graphs.
			QList<QColor *> m_usedColorList;
			//! Index of the last color used.
			int m_lastUsedColorIndex = -1;

			QMenu *m_fileMenu;
			QMenu *m_plotMenu;
			QMenu *m_windowsMenu;
			QMenu *m_dataProcessingMenu;
			QMenu *m_helpMenu;

			QAction *m_openFullMsFileAct;
			QAction *m_openStreamedMsFileAct;
			QAction *m_openMsClipboardAct;

			QAction *m_analysisPrefsAct;
			QAction *m_quitAct;
			QAction *m_clearPlotsAct;
			QAction *m_aboutAct;
			QAction *m_aboutQtAct;
			QAction *m_showTicChromWndAct;
			QAction *m_showMassSpecWndAct;
			QAction *m_showDriftSpecWndAct;
			QAction *m_showColorMapWndAct;
			QAction *m_showOpenSpectraDlgAct;
			QAction *m_showConsoleWndAct;
			QAction *m_showScriptingWndAct;
			QAction *m_showXicExtractionWndAct;
			QAction *m_showMzIntegrationParamsWndAct;
			QAction *m_showSqlMassDataSlicerWndAct;

			QAction *m_showAllWindowsAct;
			QAction *m_saveWorkspaceAct;


			// Construction/destruction
			MainWindow(const QString &moduleName);
			~MainWindow();

			const OpenSpectraDlg *openSpectraDlg() const;

			void createMenusAndActions();

			void showMzIntegrationParamsHelp(double smallestStepMedian);

			void writeSettings();
			void readSettings();

			Q_INVOKABLE void about();
			Q_INVOKABLE void quit();

			void concludeFileLoading();

			void seedInitialPlots(MassSpecDataSet *massSpecDataSet);

			Q_INVOKABLE void clearPlots();

			void closeEvent(QCloseEvent *event);

			bool setupWindow();

			bool initialize();

			void initializeScripting();

			void recyclePlottingColor(QColor color);
			bool isPlottingColorUsed(const QColor &color) const;

			void loadChromatogram(
					const QString & = QString("total ion current chromatogram"));

			void logConsoleMessage(QString msg, const QColor &color = QColor(), bool overwrite = false);

			void updateStatusBar(QString msg);

			void dataLoadMessage(QString message, int logType);

			void statusBarMessage(QString msg);
			void statusBarProgress(int value);

			void createMassSpectrumFromClipboard();
			Q_INVOKABLE void jsCreateMassSpectrumFromClipboard();

			void openMassSpectrometryFile(const QString &fileName = QString(), bool isStreamed = false);
			Q_INVOKABLE void jsOpenMassSpectrometryFile(const QString &fileName = QString(), bool isStreamed = false);

			void openMassSpectrometryFiles(const QStringList &fileList,
					bool isStreamed);
			Q_INVOKABLE void jsOpenMassSpectrometryFiles(const QStringList &fileList,
					bool isStreamed);

			void openMassSpectrometryFileSqlite3(QString fileName, bool isStreamed = false);
			void openMassSpectrometryFilePwiz(QString fileName, int format, bool isStreamed = false);
			void openMassSpectrometryFileDx(QString fileName, bool isStreamed = false);
			void openMassSpectrometryFileMs1(QString fileName, bool isStreamed = false);
			void openMassSpectrometryFileBrukerXy(QString fileName, bool isStreamed = false);
			void openMassSpectrometryFileXy(QString fileName);

			void makeLoaderConnections(MassSpecDataFileLoader *loader);

			void xicExtraction();

			void analysisPrefDlg();
			void showTicChromWnd();
			void showMassSpecWnd();
			void showDriftSpecWnd();
			void showColorMapWnd();
			void showOpenMassSpectraDlg();
			void showConsoleWnd();
			void showScriptingWnd();
			void showXicExtractionWnd();
			void showMzIntegrationParamsWnd();
			void showSqlMassDataSlicerWnd();

			void showAllWindows();
			void saveWorkspace();

			void destroyAlsoAllTargetPlotWidgets(AbstractPlotWidget *originPlotWidget);

			// Multigraph graph visibility toggling.
			void toggleMultiGraph(AbstractPlotWidget *widget, bool recursive);

			void cancelPushButtonClicked();

			public slots:
				void openFullMassSpectrometryFileDlg();
			void openStreamedMassSpectrometryFileDlg();

			void updateFeedback(QString msg, int currentValue = -1,
					bool setVisible = true, int logType = LogType::LOG_TO_CONSOLE,
					int startValue = -1, int endValue = -1);

			void initialTicDone(AbstractPlotWidget *widget,
					const MassSpecDataSet *massSpecDataSet, QColor color);

			void initialColorMapDone(AbstractPlotWidget *widget, AbstractPlotWidget *originWidget,
					const MassSpecDataSet *massSpecDataSet, QColor color);

signals:
			void cancelOperationSignal();
	};

} // namespace msXpSmineXpert


