/*	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 <QMenu>
#include "DesProjectNotifications.h"
#include "DesProject.h"
//#include "Instantiation.h"

class QTreeWidgetItem;

namespace DESpot
{
	class Instantiation;
	class DespotTreeWidget;
	class DesFlatProject;
	class DesHierProject;

	class ProjStructureUiPart: public QObject, private DesProjectNotifications
	{
		Q_OBJECT

		public:
			ProjStructureUiPart(DesProject* pProject);
			virtual ~ProjStructureUiPart(void);
			
		public:
			//returns the component type of the current item in the out parameter. If it is a supervisor
			//component or it is the root of all supervisor components then it will
			//return eSupervisorDes. If it is a plant or the root of all plant components
			//it will return ePlantDes. If the type cannot be decided the method returns false
			virtual bool getCurrentDesLevel(DesLevel& out_compLevel);

			//returns the context menu for this UI Part
			QMenu& accessContextMenu();

		//Signals_______________________________________
		signals:
			void onChangedCurrentDes(Des* pNewCurrentDes, Des* pOldCurrentDes);
//add by bini
			
			void onEnterCurrentDes();
			
			void onCurrentDesDeleted();
//add by bini
//this one may be not useful
			void onCurrentTemplateInstantiation();
			void onCurrentInstantiationDelete();
			void onChangeTemplateInstantiate();
			void onCurrentTemplateRegenerate();
			void onEnterCurrentInst();
			void onChangedCurrentInst(Instantiation* pNewCurrentInst, Instantiation* pOldCurrentInst);
			void onChangedDestoInst();
			void onChangedInsttoTemplate();
			void onChangedInsttoDes(bool isInstantiation);
			void onChangedUiItem();
			void onChangedUitoTemplate();
			void onChangedUitoDes(bool isInstantiation);
			void onChangedUitoInst();
			void onConnectEditInst();
			void onConnectEditDes();
			void onDisconnectEditInst();
			void onDisconnectEditDes();

		//Slots_________________________________________
		protected slots:			
			virtual void onChangedCurrentFlatViewItem(QTreeWidgetItem * current, QTreeWidgetItem * previous);
			virtual void onFlatStructItemActivated(QTreeWidgetItem*, int);
			virtual void onFlatStructItemDeleted();
			virtual void resizeProjFlatStructHeaders(int projStructWidgWidth);

		//Notifications comming from the project________
		protected:
			virtual void onProjectNameChanged(const std::wstring& newName, const std::wstring& oldName);
			virtual void onDesAdded(const Des& pDes, DesLevel compType);
//add by bini
			virtual void onInstAdded(Instantiation& inst,const Des& template_crt);
			virtual void onRemovingDes(const Des& des, DesLevel desLevel);
//add by bini
			virtual void onRemovingInstantiation(const Instantiation& inst);
			virtual void onDesNameChanged(const Des& des, const std::wstring& oldName);


								
		//Implementation methods________________________
		protected:
			template<class T>
			void initWidgets(T* pUiContainer);
			
			virtual void setupConnections();

			virtual void setupProjectStructWidget();
//modified by bini
			QTreeWidgetItem* createFlatViewDesItem(const QString& text, const QString& tooltip, 
										  	     QTreeWidgetItem* parent = null,
												 const Des* comp = null);
//add by bini
			QTreeWidgetItem* createFlatViewInstItem(const QString& text, const QString& tooltip, 
QTreeWidgetItem* parent /*= null*/,const Instantiation* inst /*= null*/);

			void fillFlatViewDesItem(QTreeWidgetItem& item, const Des& des);

			//returns the component from a component UI item
			Des& getDesFromFItem(QTreeWidgetItem& desUiItem);

//add by bini
			Instantiation& getInstFromFItem(QTreeWidgetItem& instUiItem);

			//returns true if the given wiget item represents a project component
			bool isDesFlatViewItem(QTreeWidgetItem& desUiItem);

			QTreeWidgetItem& getFViewItemFrom(const Des& des);
//add by bini
			QTreeWidgetItem& getFViewInstItemFrom(const Instantiation& Inst);

			bool searchDesInFViewItem(QTreeWidgetItem& desContainerItem, const Des& des, QTreeWidgetItem*& out_foundItem);

			void removeDesItem(const Des& des, QTreeWidgetItem* desItem, DespotTreeWidget* widget);
//add by bini
			void removeInstantiationItem(const Instantiation& inst,QTreeWidgetItem* instItem,DespotTreeWidget* widget);
			bool searchInstInFViewItem(QTreeWidgetItem& instContainerItem, const Instantiation& Inst, QTreeWidgetItem*& out_foundItem);

			void addSupDesToUiItem(QTreeWidgetItem* item, DesProject::DesIteratorPtr& desIt);
			void addPlantDesToUiItem(QTreeWidgetItem* item, DesProject::DesIteratorPtr& desIt);
//add by bini
			void addTemplateDesToUiItem(QTreeWidgetItem* item, DesProject::DesIteratorPtr& desIt,DesProject::InstIteratorPtr& instIt);
			void addInstToUiItem(QTreeWidgetItem* item,DesProject::InstIteratorPtr& instIt);
//bini


		//Widgets & Menus ________________________________________
		protected:
			DespotTreeWidget* m_fViewProjStructWidg;
			QTreeWidgetItem*  m_fViewRootItem;
			QTreeWidgetItem*  m_flatStructSupUiItem;
			QTreeWidgetItem*  m_flatStructPlantUiItem;
//add by bini
			QTreeWidgetItem*  m_flatStructTemplateUiItem;
			QTreeWidgetItem*  m_flatStructInstUiItem;

//bini
			//the context menu for the project structure widget
			QMenu m_projStructCtxtMenu;

		//Data___________________________________________
		protected:
			//The project that owns the components displayed in this UI Part
			DesProject*   m_pProject;

			Des* m_pCrtDes;

			Instantiation* m_pCrtInst;

			unsigned int m_projListnerId;

		//Constants______________________________________
		private:		
			static const int  cFlatProjStructColCount;
	};

} //end of namespace DESpot
