/*	Author:		Magdin Stoica
	Supervisor: Dr. Ryan Leduc
	
	Project created in conformity with the requirements for the Degree of Master of Engineering in Software Engineering, 
	Computing and Software Department, 
	McMaster University
	2003 - 2007
*/

#pragma once

#include <QObject>
#include <QMenu>
#include "ui_GedDesEditor.h"
#include "DesTransition.h"
#include "DesNotifications.h"
#include "CommonDefinitions.h"


class QGroupBox;
class QTreeWidget;

namespace DESpot
{

	class DespotTreeWidget;
	class Des;

	class GedTransitionEditorUiPart : public QObject, private DesNotifications
	{
		Q_OBJECT	

		public:
			GedTransitionEditorUiPart(Ui::GedDesEditorUI* pUiContainer, Des* pDes);
			virtual ~GedTransitionEditorUiPart(void);

		public:
			//returns the context menu for this UI Part
			QMenu& getTransContextMenu();
			QMenu& getSelfTransContextMenu();
			DespotTreeWidget* getTransViewWidg()
			    {return m_pTransViewWidg;}
			DespotTreeWidget* getSelfTransViewWidg()
				{return m_pSelfTransViewWidg;}

		//Overridables
		protected:
			virtual bool eventFilter(QObject* target, QEvent* event);

		//Signals_______________________________________
		signals:
			void onChangedCurrentTrans(const DesTransition* newCurrentTrans, const DesTransition* oldCurrentTrans);
			void onCurrentTransChanged(const DesTransition& crtTrans);

			void onChangedCurrentSelfTrans(const DesEvent* newCrtSelfTransEvent, const DesEvent* oldCrtSelfTransEvent);

			void onChangedActiveTrans(const DesTransition* newCurrentTrans, const DesTransition* oldCurrentTrans);
			void onChangedActiveSelfTrans(const DesEvent* newCrtSelfTransEvent, const DesEvent* oldCrtSelfTransEvent);

		//Slots_________________________________________
		private slots:			
			void onChangedCurrentTransItem(QTreeWidgetItem* current, QTreeWidgetItem* previous);
			void onChangedCurrentSelfTransItem(QTreeWidgetItem* current, QTreeWidgetItem* previous);

			void onChangedActiveTransItem(QTreeWidgetItem* current, QTreeWidgetItem* previous);
			void onChangedActiveSelfTransItem(QTreeWidgetItem* current, QTreeWidgetItem* previous);

			void onTransItemChanged(QTreeWidgetItem * item, int column );
			void onTransItemFromStateChanged(QTreeWidgetItem * item, int column );
			void onTransItemEventChanged(QTreeWidgetItem * item, int column );
			void onTransItemToStateChanged( QTreeWidgetItem * item, int column );

			void resizeTransViewHeaders(int transViewWidgWidth);
			void resizeSelfTransViewHeaders(int selfTransViewWidgWidth);

		//Des Notification Handlers_______________________
		private:
			//Notifications received from the contained DES when the its transition change
			virtual void onTransitionAdded(const DesTransition& addedTrans);
			virtual void onGlobalSelfTransitionAdded(const DesEvent& selfTransEvent);
			virtual void onTransitionChanged(const DesTransition& trans, const DesTransition& changedTrans);
			virtual void onRemovingTransition(const DesTransition& removedTrans);
			virtual void onRemovingSelfTransition(const DesEvent& selfTransEvent);
			virtual void onStateChanged(const DesState& changedState);
			virtual void onEventChanged(const DesEvent& changedEvent);


		//Implementation Methods________________________
		private:
			void initTransViewWidget();
			void initSelfTransViewWidget();
			void loadTransitions();
			void loadSelfTransitions();

			QTreeWidgetItem* createUiItemFromTrans(const DesTransition& trans);			
			void fillTransUiItem(QTreeWidgetItem& transUiItem, const DesTransition& trans);			
			const DesTransition& getTransFromUiItem(QTreeWidgetItem& transUiItem);
			QTreeWidgetItem* getUiItemFromTrans(const DesTransition& trans);

			QTreeWidgetItem* createUiItemFromSelfTrans(const DesEvent& selfTransEvent);
			void fillSelfTransUiItem(QTreeWidgetItem& selfTransUiItem, const DesEvent& selfTransEvent);			
			const DesEvent& getSelfTransEventFromUiItem(QTreeWidgetItem& selfTransUiItem);
			QTreeWidgetItem* getUiItemFromSelfTrans(const DesEvent& selfTransEvent);
			bool findSelfTransItem(const DesEvent& selfTransEvent, QTreeWidgetItem*& out_foundItem);


			enum StateValidation
			{
				eStateNameEmtpy = -1,
				eStateNotFound = 0,
				eStateFound = 1
			};
			StateValidation validateStateName(QString newToStateName, const DesState*& pNewToState);

			enum EventValidation
			{
				eEventNameEmtpy = -1,
				eEventNotFound = 0,
				eEventFound = 1
			};
			EventValidation validateEventName(QString newEventName, const DesEvent*& pNewEvent);

			bool changeTransition(const DesTransition& trans, const DesTransition& change);



		private:			
			QWidget*		  m_pTransBoxWidg;
			QSplitter*		  m_pTransSplitterWidg;
			
			DespotTreeWidget* m_pTransViewWidg;
			DespotTreeWidget* m_pSelfTransViewWidg;

			QMenu m_transEditorContextMenu;
			QMenu m_selfTransEditorContextMenu;


			//The Des that owns the event displayed in this UI part
			Des* m_pDes;
			unsigned int m_desListnerId;

		//constants
		private:
			static const short cTransEditorColumnCount;
			static const short cTransFromStateColumnIdx;
			static const short cTransEventColumnIdx;
			static const short cTransToStateColumnIdx;

			static const short cSelfTransEditorColumnCount;
			static const short cSelfTransEventColumnIdx;
			static const short cSelfTransAliasColumnIdx;
	};

} //end of namespace DESpot
