/*************************************************************************
 * This file is part of Graphic des EDitor project
 *
 * Project created in conformity with the requirements for the Degree of
 * Master of Engineering in Software Engineering, Computing and Software
 * Department, McMaster University 2004 - 2008
 *
 * Author:	Xiao Ma
 * Supervisor: Dr. Ryan Leduc
*************************************************************************/

/*
 NAME
   GedDesEditor.h - Ged DES editor main form.
 FUNCTION
   Graphic editor main form
 NOTES
   Inital version adoped from DesEditor.h by Magdin Stoica
 MODIFIED
   xma	    09/01/07 - CREATION. Adopted from DesEditor.h by Magdin Stoica
*/

#pragma once

#include <QMainWindow>
#include <string>
#include <QCloseEvent>

#include "DespotForm.h"
#include "Des.h"
#include "TransRecorder.h"

class QMenu;
class QToolBar;
class QAction;
class QStatusBar;
class QActionGroup;

namespace DESpot
{

class MainForm;
class ProjectEditor;
class GedDesWorkspace;
class Des;
class DesState;
class DesEvent;
class DesTransition;
class GedDesEditorOutputUiPart;
class ReachabilityAlgo;
class CoreachabilityAlgo;
class NonBlockingAlgo;
class DesIntegrityAlgo;
class UpdateProgressInterface;

class GedDesEditor: public QMainWindow, public DespotForm
{
	Q_OBJECT

	public:
		GedDesEditor(MainForm* pMainForm);
        GedDesEditor(const std::wstring& desName, DesType desType, MainForm* pMainForm);
		GedDesEditor(const QString& fileName, MainForm* pMainForm);
		GedDesEditor(Des* pDes, ProjectEditor* projEditorOwner, MainForm* pMainForm);
		virtual ~GedDesEditor(void);

	public:
		Des* des();

		bool ownedByProject();
		ProjectEditor* projEditorOwner();

		void saveAsPs();
		void saveAsPng();

		TransRecorder& getTransRecorder();

		virtual QString getDocName();
		virtual QString getDocFileName();

		void onAttemptSaveDes(Des* des, QWidget* callerWindow = null);

		std::wstring getFilePath();

	signals:
		void setInstMode();


	public slots:
		//#pragma region DES slots
		//DES Slots
		//void onNewDes();
		//void onOpenDes();
		//void onOpenDes(const QString& fileName);
		void onSaveDes();
		void onSaveDesAs();
		void onRevertToFile();
		void onDesSetName();
		void onDesSetType();
		void onPrintDes();
		void onClose();
		//#pragma endregion

		//#pragma region State slots
		//State Slots
		void onAddState();
		void onChangeState();
		void onDeleteState();
		void onToggleMarkedState();
		void onMarkAllStates();
		void onUnmarkAllStates();
		void onToggleInitialState();

		#ifdef __ENABLE_NEXT_VERSION__
			void onSortStatesByName();
			void onSortStatesByCreation();
			void onSortStatesByUserDefined();
		#endif

		//#pragma endregion

		//#pragma region Event slots
		//Event Slots
		void onAddEvent();
		void onChangeEvent();
		void onDeleteEvent();
		void onToggleEventCtrl();
		void onSetEventTypeDefault();
		void onSetEventTypeAnswer();
		void onSetEventTypeRequest();
		void onSetEventTypeLData();
		void onClearEventType();

		#ifdef __ENABLE_NEXT_VERSION__
			void onSortEventsByName();
			void onSortEventsByCtrl();
			void onSortEventsByType();
			void onSortEventsByCreation();
			void onSortEventsByUserDefined();
		#endif

		//#pragma endregion

		//#pragma region Transitions slots
		//Transition operations
		void onAddTransition();
		bool onAddTransition(const DesTransition& newTrans);
		void onAddSelfTransition();
		void onChangeTransition();
		void onDeleteTransition();
		void onDeleteSelfTransition();
		void onRecordTransitions();

		#ifdef __ENABLE_NEXT_VERSION__
			void onFilterTransByFromState();
			void onFilterTransByToState();
			void onFilterTransByAnyState();
			void onFilterTransByEventName();
			void onFilterTransByEventType();
			void onFilterTransByEventCtrl();
			void onRemoveTransFilter();

			void onSortTransByFromState();
			void onSortTransByToState();
			void onSortTransByEventName();
			void onSortTransByEventType();
			void onSortTransByEventCtrl();
			void onSortTransByCreation();
			void onSortTransByUserDefined();
		#endif
		//#pragma endregion

		//#pragma region Tools Operations slots
		//Tools operations
		void onCheckDesIntegrity();
		void onRunReachableTool();
		void onRunCoreachableTool();
		void onRunNonBlockTool();

		#ifdef __ENABLE_NEXT_VERSION__
			void onRunIsomorphTool();
			void onRunMultiTools();
		#endif

		//#pragma endregion

		#ifdef __ENABLE_NEXT_VERSION__
			//User Defined Order operations
			void onMoveItemFirst();
			void onMoveItemUp();
			void onMoveItemDown();
			void onMoveItemLast();
		#endif

		//#pragma region DES slots
		//Events received from the edited DES
		void onChangedCurrentState(const DesState* pNewCurrentState, const DesState* pOldCurrentState);
		void onChangedCurrentEvent(const DesEvent* pNewCurrentEvent, const DesEvent* pOldCurrentEvent);
		void onChangedCurrentTrans(const DesTransition* pNewCurrentTrans, const DesTransition* pOldCurrentTrans);
		void onChangedCurrentSelfTrans(const DesEvent* pNewCurrentSelfTrans, const DesEvent* pOldCurrentSelfTrans);
		//#pragma endregion

	//Overridables__________________________________
	protected:
		virtual void resizeEvent(QResizeEvent* event);
		virtual void closeEvent(QCloseEvent *event);

	//Implementation Methods _______________________
	private:
		void initEditor();
	    void updateWindowTitle();
		GedDesEditorOutputUiPart& output();

		void showOutput(DesIntegrityAlgo& integAlgo);
		void showOutput(ReachabilityAlgo& reachAlgo);
		void showOutput(CoreachabilityAlgo& coreachAlgo);
		void showOutput(NonBlockingAlgo& nonBlockAlgo);

		UpdateProgressInterface* progressInterface();

		void exportAs(const QString& format);

	private:
		//The user interface workspace
		GedDesWorkspace* m_pWorkspace;

		//The DES being edited
		Des* m_pDes;

		//The state currently selected in the editor
		const DesState* m_pCrtSelState;

		//The event currently selected in the editor
		const DesEvent* m_pCrtSelEvent;

		//The transtion currently selected in the editor
		const DesTransition* m_pCrtSelTrans;

		//The self-transition currently selected in the editor (identified by the event that is self-looped)
		const DesEvent* m_pCrtSelfTrans;

		//true if the editor owns the DES and has to destroy when closed
		bool m_editorOwnsDes;

		//true if the editor is recording transitions
		TransRecorder m_transRecorder;
};

} //end of namespace DESpot
