/*	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"

class QTreeWidgetItem;

namespace DESpot
{
	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);
			void onEnterCurrentDes();
			void onCurrentDesDeleted();

		//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);
			virtual void onRemovingDes(const Des& des, DesLevel desLevel);
			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();

			QTreeWidgetItem* createFlatViewDesItem(const QString& text, const QString& tooltip, 
										  	     QTreeWidgetItem* parent = null,
												 const void* comp = null);

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

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

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

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

			void removeDesItem(const Des& des, QTreeWidgetItem* desItem, DespotTreeWidget* widget);

			void addSupDesToUiItem(QTreeWidgetItem* item, DesProject::DesIteratorPtr& desIt);
			void addPlantDesToUiItem(QTreeWidgetItem* item, DesProject::DesIteratorPtr& desIt);


		//Widgets & Menus ________________________________________
		protected:
			DespotTreeWidget* m_fViewProjStructWidg;
			QTreeWidgetItem*  m_fViewRootItem;
			QTreeWidgetItem*  m_flatStructSupUiItem;
			QTreeWidgetItem*  m_flatStructPlantUiItem;

			//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;

			unsigned int m_projListnerId;

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

} //end of namespace DESpot
