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

#include <QMenuBar>
#include <QToolBar>
#include <qevent.h>
#include <QHeaderView>

#include "HierProjectWorkspace.h"
#include "CommonDefinitions.h"
#include "HierProjectEditor.h"
#include "DesHierProject.h"
#include "HierProjStructureUiPart.h"
#include "HierProjSummaryUiPart.h"
#include "DesViewUiPart.h"
#include "OutputUiPart.h"


namespace DESpot
{

HierProjectWorkspace::HierProjectWorkspace(HierProjectEditor* pHierProjectEditor, DesHierProject* pProject) : 
	ProjectWorkspace(pHierProjectEditor, pProject)
{
	//configure the form to use the HierProjectEditor.ui
	setupUi(pHierProjectEditor);

	//call the base class to set the title of the window given the fact that this is flat project
	//the base class will compose the full title and set it
	setProjectEditorTitle(STR_HIER_PROJ_EDITOR, pProject->getName());

	createActions();

	//create the UI Parts of a flat project
	createUiParts(pProject);

	//setup menu, toolbar and status bar	
	setupMenu();
	setupToolBar();
	setupStatusBar();

	//setup event filters for child controls
	setupEventFilters();

	//setup connections between widgets, workspace and editors
	setupConnections();

	//set the spliter position
	positionSplitters();

	m_projDetailsTabWidg->setCurrentIndex(0);
	m_projDetailsTabWidg->removeTab(2);
	m_projDetailsTabWidg->removeTab(1);

	pHierProjectEditor->resize(740, 660);

}

//_________________________________________________________________________________________________

HierProjectWorkspace::~HierProjectWorkspace(void)
{
}

//_________________________________________________________________________________________________

HierProjStructureUiPart& HierProjectWorkspace::hierProjStructureUiPart()
{
	return dynamic_cast<HierProjStructureUiPart&>(projStructureUiPart());
}

//_________________________________________________________________________________________________

HierProjSummaryUiPart&   HierProjectWorkspace::hierProjSummaryUiPart()
{
	return dynamic_cast<HierProjSummaryUiPart&>(projSummaryUiPart());
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::selectDefaults()
{
	//select the default items
	hierProjStructureUiPart().selectDefaults();
}

//_________________________________________________________________________________________________

ProgressWidget* HierProjectWorkspace::progressWidget()
{
	return m_progressWidget;
}

//_________________________________________________________________________________________________

HierProjectEditor* HierProjectWorkspace::hierProjectEditor()
{
	return dynamic_cast<HierProjectEditor*>(projectEditor());
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::setupEventFilters()
{
	centralWidget->installEventFilter(this);
	m_projDetailsTabWidg->installEventFilter(this);
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::setupConnections()
{
	ProjectWorkspace::setupConnections();

	connect(&hierProjStructureUiPart(), SIGNAL(onChangedCurrentSubsys(const DesSubsystem*, const DesSubsystem*)), 
			this, SLOT(onChangedCurrentSubsys(const DesSubsystem*, const DesSubsystem*)));

	connect(&hierProjStructureUiPart(), SIGNAL(onChangedCurrentSubsys(const DesSubsystem*, const DesSubsystem*)), 
			m_pDesViewUiPart, SLOT(onChangedCurrentSubsys(const DesSubsystem*, const DesSubsystem*)));

	connect(&hierProjStructureUiPart(), SIGNAL(onChangedCurrentInterf(const DesInterface*, const DesInterface*)), 
			this, SLOT(onChangedCurrentInterf(const DesInterface*, const DesInterface*)));

	connect(&hierProjStructureUiPart(), SIGNAL(onChangedCurrentInterf(const DesInterface*, const DesInterface*)), 
			m_pDesViewUiPart, SLOT(onChangedCurrentInterf(const DesInterface*, const DesInterface*)));
}

//_________________________________________________________________________________________________

bool HierProjectWorkspace::eventFilter(QObject* target, QEvent* event)
{	
	if (target == centralWidget && event->type() == QEvent::Resize)
	{
		QResizeEvent* resizeEvent = dynamic_cast<QResizeEvent*>(event);
		m_mainSplitterWidg->resize(resizeEvent->size() - QSize(20, 22));
	}		
	else if (target == m_projDetailsTabWidg && event->type() == QEvent::Resize)
	{
		QResizeEvent* resizeEvent = dynamic_cast<QResizeEvent*>(event);
		
		const QSize cLayoutOffset(18,50);		
		m_summaryPageLayout->resize(resizeEvent->size() - cLayoutOffset);
		m_nonBlockPageLayout->resize(resizeEvent->size() - cLayoutOffset);
		m_ctrlPageLayout->resize(resizeEvent->size() - cLayoutOffset);
		m_outputPageLayout->resize(resizeEvent->size() - cLayoutOffset);
		m_desDetailsLayoutWidg->resize(resizeEvent->size() - cLayoutOffset);
	}
	
	return ProjectWorkspace::eventFilter(target, event);
}


//_________________________________________________________________________________________________

//Arrange the position of all splitters to have the following arrangement:
//		- Project Structure area occupies ~30% of the horizontal space
//		- Des Details occupies the rest of ~70 of the horizontal space
//		- Project hierarchy and level viewer split the project structure space 50-50
void HierProjectWorkspace::positionSplitters()
{
	const int cProjectLevelRatio = 2;
	QSize projectStructSplitterSize = m_hViewSplitterWidg->size();
	int   projectHierAreaHeight = projectStructSplitterSize.height() / cProjectLevelRatio;
	int   levelAreaHeight = projectStructSplitterSize.height() - projectHierAreaHeight; // the rest of the vertical space
	
	//Arange the splitter to have the above sizes
	QList<int> projectSplitterSizeList;
	projectSplitterSizeList.push_back(projectHierAreaHeight);
	projectSplitterSizeList.push_back(levelAreaHeight);
	m_hViewSplitterWidg->setSizes(projectSplitterSizeList);
	

	//Calculate the 40/60 width sizes for the main splitter
	const float cProjectStructRatio = 2.60f;
	QSize mainSplitterSize   = m_mainSplitterWidg->size();
        int   projStructAreaWidth = (int)(mainSplitterSize.width() / cProjectStructRatio);
	int   desDetailsAreaWidth = mainSplitterSize.width() - projStructAreaWidth; // the rest of the splitter;

	//arrange the main spliter to have the above sizes
	QList<int> mainSplitterSizeList;
	mainSplitterSizeList.push_back(projStructAreaWidth);
	mainSplitterSizeList.push_back(desDetailsAreaWidth);
	m_mainSplitterWidg->setSizes(mainSplitterSizeList);
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::createUiParts(DesHierProject* pProject)
{
	//create the UI Parts of a HISC project
	m_pProjStructUiPart = new HierProjStructureUiPart(this, pProject, m_addHighLvlSubsysAct);

	m_pSummaryUiPart = new HierProjSummaryUiPart(this, pProject);
	
	m_pDesViewUiPart = new DesViewUiPart(this, pProject);
	
	m_pOutputUiPart	= new OutputUiPart(this, pProject);
	m_pOutputUiPart->setOwnerTabWidget(m_projDetailsTabWidg);
}	

//_________________________________________________________________________________________________

void HierProjectWorkspace::createActions()
{
	ProjectWorkspace::createActions();

	m_addHighLvlSubsysAct = new QAction(QIcon(":resources/addHighLevel.png"), tr("&High Level Subsystem"), this);
	m_addHighLvlSubsysAct->setToolTip(tr("Add high-level Subsystem"));
	m_addHighLvlSubsysAct->setStatusTip(tr("Add high-level subsystem to project"));
	connect(m_addHighLvlSubsysAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onAddHighLevelSubsystem()));

	m_addInterfaceAct = new QAction(QIcon(":resources/addInterfaceLevel.png"), tr("&Interface"), this);
	m_addInterfaceAct->setToolTip(tr("Add Interface"));
	m_addInterfaceAct->setStatusTip(tr("Add interface to project"));
	connect(m_addInterfaceAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onAddInterface()));

	m_addLowLvlSubsysAct = new QAction(QIcon(":resources/addLowLevel.png"), tr("&Low Level Subsystem"), this);
	m_addLowLvlSubsysAct->setToolTip(tr("Add Low Level Subsystem"));
	m_addLowLvlSubsysAct->setStatusTip(tr("Add low-level subsystem to project"));
	connect(m_addLowLvlSubsysAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onAddLowLevelSubsystem()));

	m_projCompRenameAct = new QAction(tr("&Rename"), this);
	m_projCompRenameAct->setToolTip(tr("Rename Subsystem / Interface"));
	m_projCompRenameAct->setShortcut(tr("F2"));
	m_projCompRenameAct->setStatusTip(tr("Renames the selected subsystem or interface"));
	m_projCompRenameAct->setEnabled(false);
	connect(m_projCompRenameAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onProjCompRename()));
	
	m_projCompDeleteAct = new QAction(tr("&Delete"), this);
	m_projCompDeleteAct->setToolTip(tr("Delete Subsystem / Interface"));
	m_projCompDeleteAct->setShortcut(tr("Ctrl+Del"));
	m_projCompDeleteAct->setStatusTip(tr("Deletes the selected subsystem or interface"));
	m_projCompDeleteAct->setEnabled(false);
	connect(m_projCompDeleteAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onProjCompDelete()));
	
	m_addNewSubsystemDesAct = new QAction(QIcon(":resources/newHighLevelDes.png"), tr("&Subsystem DES"), this);
	m_addNewSubsystemDesAct->setToolTip(tr("Add new high-level DES"));
	m_addNewSubsystemDesAct->setStatusTip(tr("Adds a new high-level DES to the project"));
	connect(m_addNewSubsystemDesAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onAddNewHighLevelDes()));
	
	m_addNewInterfaceDesAct = new QAction(QIcon(":resources/newInterfaceDes.png"), tr("&Interface DES"), this);
	m_addNewInterfaceDesAct->setToolTip(tr("Add new interface DES"));
	m_addNewInterfaceDesAct->setStatusTip(tr("Adds a new interface DES to the project"));
	connect(m_addNewInterfaceDesAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onAddNewInterfaceDes()));

	m_runContextSync = new QAction(QIcon(":/resources/syncProduct.png"), tr("&Sync"), this);
	m_runContextSync->setToolTip(tr("Create sync product of the selected item"));
	m_runContextSync->setStatusTip(tr("Creates the sync product of the selected item. Works with subsystems, plants and supervisor as well as interfaces."));
	connect(m_runContextSync, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunContextSyncProductTool()));

	m_runCheckInterfToolAct = new QAction(QIcon(":/resources/checkInterface.png"), tr("&Check LD Interface"), this);
	m_runCheckInterfToolAct->setToolTip(tr("Check LD Interface"));
	m_runCheckInterfToolAct->setStatusTip(tr("Verifies if the current interface is an LD-interface"));
	m_runCheckInterfToolAct->setEnabled(false);
	connect(m_runCheckInterfToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunCheckInterfTool()));

	m_runSubsysIConsistToolAct = new QAction(QIcon(":/resources/checkSubsysIConsist.png"), tr("&Check Subsystem LD I-Consist"), this);
	m_runSubsysIConsistToolAct->setToolTip(tr("Check LD Interface Consistency"));
	m_runSubsysIConsistToolAct->setStatusTip(tr("Verifies if the current subsystem is LD interface consistent"));
	m_runSubsysIConsistToolAct->setEnabled(false);
	connect(m_runSubsysIConsistToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunSubsysIConsistTool()));

	m_runProjIConsistToolAct = new QAction(QIcon(":/resources/checkIConsist.png"), tr("&LD Interface Consistent"), this);
	m_runProjIConsistToolAct->setToolTip(tr("Check LD Interface Consistency"));
	m_runProjIConsistToolAct->setStatusTip(tr("Verifies if the project is LD interface consistent"));
	connect(m_runProjIConsistToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunProjIConsistTool()));

	m_runLevelWiseNonBlockAct = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("LD Level-Wise Non&blocking"), this);
	m_runLevelWiseNonBlockAct->setToolTip(tr("Check LD level-wise nonblocking"));
	m_runLevelWiseNonBlockAct->setStatusTip(tr("Verifies if the project is LD level-wise nonblocking"));
	connect(m_runLevelWiseNonBlockAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunLevelWiseNonblockingTool()));

	m_runSubsysNonBlockAct = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("Check Subsystem LD Non&blocking"), this);
	m_runSubsysNonBlockAct->setToolTip(tr("Check level-wise LD nonblocking"));
	m_runSubsysNonBlockAct->setStatusTip(tr("Verifies if the current subsystem is LD level-wise nonblocking"));
	m_runSubsysNonBlockAct->setEnabled(false);
	connect(m_runSubsysNonBlockAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunSubsysNonblockingTool()));

	m_runLevelWiseCtrlAct = new QAction(QIcon(":/resources/checkControllability.png"), tr("LD &Level-Wise Contro&llability"), this);
	m_runLevelWiseCtrlAct->setToolTip(tr("Check LD level-wise controllability"));
	m_runLevelWiseCtrlAct->setStatusTip(tr("Verifies if the project is LD level-wise controllable"));
	connect(m_runLevelWiseCtrlAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunLevelWiseCtrlTool()));

	m_runSubsysCtrlAct = new QAction(QIcon(":/resources/checkControllability.png"), tr("&Check Subsystem LD Controllable"), this);
	m_runSubsysCtrlAct->setToolTip(tr("Check LD level-wise controllability"));
	m_runSubsysCtrlAct->setStatusTip(tr("Verifies if the current subsystem is LD level-wise controllable"));
	m_runSubsysCtrlAct->setEnabled(false);
	connect(m_runSubsysCtrlAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunSubsysCtrlTool()));
	
	//Added by Zain for subsystem simulation
	m_runSubsysSimulationAct = new QAction(QIcon(":/resources/debug_button.png"), tr("&Subsystem Simulation"), this);
	m_runSubsysSimulationAct->setToolTip(tr("Simulate the subsystem for loading previously saved debug simulations"));
	m_runSubsysSimulationAct->setStatusTip(tr("Simulates the subsystem by making a dummy project"));
	m_runSubsysSimulationAct->setEnabled(false);
	connect(m_runSubsysSimulationAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunSubsysSimulationActTool()));

	m_runLevelWiseSynthesisAct = new QAction(QIcon(":/resources/supcon.png"), tr("&Level-Wise &Synthesis"), this);
	m_runLevelWiseSynthesisAct->setToolTip(tr("Runs level-wise sythesis for HISC project"));
	m_runLevelWiseSynthesisAct->setStatusTip(tr("Constructs supremal, controllable, nonblocking level-wise supervisors for project"));
	connect(m_runLevelWiseSynthesisAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunLevelWiseSynthesisTool()));

	//Added by Adam for BDDExport
	m_exportToBDDhiscAct = new QAction(tr("Export to BDDhisc"), this);
	m_exportToBDDhiscAct->setToolTip(tr("Export to BDDhisc"));
	m_exportToBDDhiscAct->setStatusTip(tr("Export to BDDhisc"));
	connect(m_exportToBDDhiscAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onExportToBDDhisc()));

#ifdef __ENABLE_BDD__

	m_runBddNonblockToolAct = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("&Nonblocking"), this);
	m_runBddNonblockToolAct->setToolTip(tr("Check non-blocking (automata algorithm)"));
	m_runBddNonblockToolAct->setStatusTip(tr("Verifies if the project is non-blocking using BDD algorithms"));
	connect(m_runBddNonblockToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddNonBlockingTool()));

	m_runBddCtrlToolAct = new QAction(QIcon(":/resources/checkControllability.png"), tr("&Controllability"), this);
	m_runBddCtrlToolAct->setToolTip(tr("Check controllability. Fast version."));
	m_runBddCtrlToolAct->setStatusTip(tr("Verifies if the project is controllable with BDD algorithms."));
	connect(m_runBddCtrlToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddMultiCtrlTool()));

	m_runBddCheckInterfToolAct = new QAction(QIcon(":/resources/checkInterface.png"), tr("&Check Interface (BDD)"), this);
	m_runBddCheckInterfToolAct->setToolTip(tr("Check LD-Interface (BDD)"));
	m_runBddCheckInterfToolAct->setStatusTip(tr("Verifies if the current interface is an LD-interface using BDD algorithms"));
	m_runBddCheckInterfToolAct->setEnabled(false);
	connect(m_runBddCheckInterfToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddCheckInterfTool()));

	m_runBddSubsysIConsistToolAct = new QAction(QIcon(":/resources/checkSubsysIConsist.png"), tr("&Check Subsystem I-Consist (BDD)"), this);
	m_runBddSubsysIConsistToolAct->setToolTip(tr("Check Subsystem Interface Consistency"));
	m_runBddSubsysIConsistToolAct->setStatusTip(tr("Verifies if the current subsystem is interface consistent using BDD algorithms"));
	m_runBddSubsysIConsistToolAct->setEnabled(false);
	connect(m_runBddSubsysIConsistToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddSubsysIConsistTool()));

	m_runBddCheckAllToolAct = new QAction(QIcon(":/resources/checkProject.png"), tr("Check &All"), this);
	m_runBddCheckAllToolAct->setToolTip(tr("Check All (BDD)"));
//	m_runBddCheckAllToolAct->setStatusTip(tr("using BDD algorithms"));
	connect(m_runBddCheckAllToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddCheckAllTool()));

	m_runBddProjIConsistToolAct = new QAction(QIcon(":/resources/checkIConsist.png"), tr("&Interface Consistent"), this);
	m_runBddProjIConsistToolAct->setToolTip(tr("Check Interface Consistency"));
	m_runBddProjIConsistToolAct->setStatusTip(tr("Verifies if the project is interface consistent using BDD algorithms"));
	connect(m_runBddProjIConsistToolAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddProjIConsistTool()));

	m_runBddLevelWiseNonBlockAct = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("Level-Wise Non&blocking"), this);
	m_runBddLevelWiseNonBlockAct->setToolTip(tr("Check level-wise nonblocking"));
	m_runBddLevelWiseNonBlockAct->setStatusTip(tr("Verifies if the project is level-wise nonblocking using BDD algorithms"));
	connect(m_runBddLevelWiseNonBlockAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddLevelWiseNonblockingTool()));

	m_runBddSubsysNonBlockAct = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("Check Subsystem Non&blocking (BDD)"), this);
	m_runBddSubsysNonBlockAct->setToolTip(tr("Check level-wise nonblocking"));
	m_runBddSubsysNonBlockAct->setStatusTip(tr("Verifies if the current subsystem is level-wise nonblocking using BDD algorithms"));
	m_runBddSubsysNonBlockAct->setEnabled(false);
	connect(m_runBddSubsysNonBlockAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddSubsysNonblockingTool()));

	m_runBddLevelWiseCtrlAct = new QAction(QIcon(":/resources/checkControllability.png"), tr("&Level-Wise Contro&llability"), this);
	m_runBddLevelWiseCtrlAct->setToolTip(tr("Check level-wise controllability"));
	m_runBddLevelWiseCtrlAct->setStatusTip(tr("Verifies if the project is level-wise controllable using BDD algorithms"));
	connect(m_runBddLevelWiseCtrlAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddLevelWiseCtrlTool()));

	m_runBddSubsysCtrlAct = new QAction(QIcon(":/resources/checkControllability.png"), tr("&Check Subsystem Controllable (BDD)"), this);
	m_runBddSubsysCtrlAct->setToolTip(tr("Check subsystem level-wise controllability"));
	m_runBddSubsysCtrlAct->setStatusTip(tr("Verifies if the current subsystem is level-wise controllable using BDD algorithms"));
	m_runBddSubsysCtrlAct->setEnabled(false);
	connect(m_runBddSubsysCtrlAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddSubsysCtrlTool()));

	m_runSubsysLWSynAct = new QAction(QIcon(":/resources/supcon.png"), tr("&Subsystem Level-Wise Synthesis (BDD)"), this);
	m_runSubsysLWSynAct->setToolTip(tr("Runs level-wise synthesis (BDD) on current subsystem"));
	m_runSubsysLWSynAct->setStatusTip(tr("Constructs supremal, controllable, nonblocking level-wise supervisor for subsystem using BDD algorithms"));
	m_runSubsysLWSynAct->setEnabled(false);
	connect(m_runSubsysLWSynAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBDDSubsysLWSynTool()));

	m_runBddLevelWiseSynthesisAct = new
	QAction(QIcon(":/resources/supcon.png"), tr("&Level-Wise &Synthesis"), this);
	m_runBddLevelWiseSynthesisAct->setToolTip(tr("Runs level-wise sythesis for HISC project"));
	m_runBddLevelWiseSynthesisAct->setStatusTip(tr("Constructs supremal, controllable, nonblocking level-wise supervisors for project using BDD algorithms"));
	connect(m_runBddLevelWiseSynthesisAct, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunBddLevelWiseSynthesisTool()));
#endif

	//Added by David for Distributed tools
	m_runDistCheckAll = new QAction(QIcon(":/resources/checkProject.png"), tr("Check All"), this);	
	connect(m_runDistCheckAll, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistCheckAll()));

	m_runDistNB = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("Level-Wise Non&blocking"), this);	
	connect(m_runDistNB, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistLWNB()));
	
	m_runDistCtrl = new QAction(QIcon(":/resources/checkControllability.png"), tr("&Level-Wise Contro&llability"), this);	
	connect(m_runDistCtrl, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistLWCtrl()));

	m_runDistIConsist = new QAction(QIcon(":/resources/checkIConsist.png"), tr("&Interface Consistent"), this);	
	connect(m_runDistIConsist, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistIConsist()));

	m_runDistBDDCheckAll = new QAction(QIcon(":/resources/checkProject.png"), tr("Check All (BDD)"), this);	
	connect(m_runDistBDDCheckAll, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistBDDCheckAll()));

	m_runDistBDDNB = new QAction(QIcon(":/resources/checkNonBlocking.png"), tr("Level-Wise Non&blocking (BDD)"), this);	
	connect(m_runDistBDDNB, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistBDDLWNB()));

	m_runDistBDDCtrl = new QAction(QIcon(":/resources/checkControllability.png"), tr("&Level-Wise Contro&llability (BDD)"), this);	
	connect(m_runDistBDDCtrl, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistBDDLWCtrl()));

	m_runDistBDDIConsist = new QAction(QIcon(":/resources/checkIConsist.png"), tr("&Interface Consistent (BDD)"), this);	
	connect(m_runDistBDDIConsist, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistBDDIConsist()));

	m_runDistBDDSynth = new QAction(QIcon(":/resources/supcon.png"), tr("&Level-Wise &Synthesis (BDD)"), this);	
	connect(m_runDistBDDSynth, SIGNAL(triggered()), hierProjectEditor(), SLOT(onRunDistBDDSynth()));

	#ifndef __ENABLE_DIST__
		m_runDistCheckAll->setDisabled(true);
		m_runDistNB->setDisabled(true);
		m_runDistCtrl->setDisabled(true);
		m_runDistIConsist->setDisabled(true);

		m_runDistBDDCheckAll->setDisabled(true);
		m_runDistBDDNB->setDisabled(true);
		m_runDistBDDCtrl->setDisabled(true);
		m_runDistBDDIConsist->setDisabled(true);

		m_runDistBDDSynth->setDisabled(true);
	#endif
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::setupMenu()
{
	ProjectWorkspace::setupMenu();

	//setup the "Levels" menu which is specific to HISC project editors
	m_subsysMenu = new QMenu(tr("&Subsystems"));
	m_addSubSysMenu = m_subsysMenu->addMenu(tr("Add"));
	{
		m_addSubSysMenu->addAction(m_addHighLvlSubsysAct);
		m_addSubSysMenu->addAction(m_addInterfaceAct);
		m_addSubSysMenu->addAction(m_addLowLvlSubsysAct);
	}
	m_subsysMenu->addAction(m_projCompRenameAct);
	m_subsysMenu->addAction(m_projCompDeleteAct);
	
	//insert the menu right after the Project menu and before DES menu	
	hierProjectEditor()->menuBar()->insertMenu(m_desMenu->menuAction(), m_subsysMenu);

	//add HISC project specific tools in the tool menu
	m_toolsMenu->addSeparator();
	m_toolsMenu->addAction(m_runCheckInterfToolAct);
	m_toolsMenu->addAction(m_runSubsysIConsistToolAct);
	m_toolsMenu->addAction(m_runSubsysNonBlockAct);
	m_toolsMenu->addAction(m_runSubsysCtrlAct);
	//Added by Zain
	m_toolsMenu->addAction(m_runSubsysSimulationAct);
	m_toolsMenu->addSeparator();
	m_toolsMenu->addAction(m_runProjIConsistToolAct);
	m_toolsMenu->addAction(m_runLevelWiseNonBlockAct);
	m_toolsMenu->addAction(m_runLevelWiseCtrlAct);
	m_toolsMenu->addAction(m_runLevelWiseSynthesisAct);
	

	//Added by Adam for BDDExport
	m_projectMenu->insertAction(m_projectSetNameAct, m_exportToBDDhiscAct);
	m_projectMenu->insertSeparator(m_projectSetNameAct);

#ifdef __ENABLE_BDD__
	//add HISC project specifric BDD tools in the tool menu
	m_bddToolsMenu->insertAction(m_runBddMeetToolAct, m_runBddNonblockToolAct);
	m_bddToolsMenu->insertAction(m_runBddMeetToolAct, m_runBddCtrlToolAct);
	m_bddToolsMenu->insertSeparator(m_runBddMeetToolAct);
	m_bddToolsMenu->addSeparator();
	m_bddToolsMenu->addAction(m_runBddCheckInterfToolAct);
	m_bddToolsMenu->addAction(m_runBddSubsysIConsistToolAct);
	m_bddToolsMenu->addAction(m_runBddSubsysNonBlockAct);
	m_bddToolsMenu->addAction(m_runBddSubsysCtrlAct);
	m_bddToolsMenu->addAction(m_runSubsysLWSynAct);	
	m_bddToolsMenu->addSeparator();
	m_bddToolsMenu->addAction(m_runBddCheckAllToolAct);
	m_bddToolsMenu->addAction(m_runBddProjIConsistToolAct);
	m_bddToolsMenu->addAction(m_runBddLevelWiseNonBlockAct);
	m_bddToolsMenu->addAction(m_runBddLevelWiseCtrlAct);
	m_bddToolsMenu->addSeparator();
	m_bddToolsMenu->addAction(m_runBddLevelWiseSynthesisAct);
#endif
		
	//setup the context menu of the project structure UI Part
	{
		QMenu& hViewProjCtxtMenu  = hierProjStructureUiPart().accessHViewProjCtxtMenu();		
		hViewProjCtxtMenu.addAction(m_projCompRenameAct);
		hViewProjCtxtMenu.addAction(m_projCompDeleteAct);
		hViewProjCtxtMenu.addAction(m_addDesAct);
		hViewProjCtxtMenu.addAction(m_runContextSync);
		hViewProjCtxtMenu.addSeparator();
		hViewProjCtxtMenu.addAction(m_runCheckInterfToolAct);
		hViewProjCtxtMenu.addSeparator();
		hViewProjCtxtMenu.addAction(m_runSubsysIConsistToolAct);
		hViewProjCtxtMenu.addAction(m_runSubsysNonBlockAct);
		hViewProjCtxtMenu.addAction(m_runSubsysCtrlAct);
		//Added by Zain
		hViewProjCtxtMenu.addAction(m_runSubsysSimulationAct);
		hViewProjCtxtMenu.addSeparator();
		hViewProjCtxtMenu.addAction(m_runBddCheckInterfToolAct);
		hViewProjCtxtMenu.addSeparator();
		hViewProjCtxtMenu.addAction(m_runBddSubsysIConsistToolAct);
		hViewProjCtxtMenu.addAction(m_runBddSubsysNonBlockAct);
		hViewProjCtxtMenu.addAction(m_runBddSubsysCtrlAct);
		hViewProjCtxtMenu.addAction(m_runSubsysLWSynAct);
		
		
		QMenu& hViewDesCtxMenu = hierProjStructureUiPart().accessHViewDesCtxtMenu();
		hViewDesCtxMenu.addAction(m_addDesAct);
		hViewDesCtxMenu.addAction(m_editDesAct);
		hViewDesCtxMenu.addAction(m_removeDesAct);
//add by bini
		hViewDesCtxMenu.addAction(m_instantiateDesAct);
		hViewDesCtxMenu.addAction(m_editInstAct);
		hViewDesCtxMenu.addAction(m_deleteInstantiationAct);
		hViewDesCtxMenu.addAction(m_regenerateInstantiationAct);

		hViewDesCtxMenu.addSeparator();
		hViewDesCtxMenu.addAction(m_runContextSync);

		QMenu& lViewCtxtMenu  = hierProjStructureUiPart().accessLViewCtxtMenu();		
		lViewCtxtMenu.addAction(m_projCompRenameAct);
		lViewCtxtMenu.addAction(m_projCompDeleteAct);
		lViewCtxtMenu.addAction(m_runContextSync);
		lViewCtxtMenu.addSeparator();
		lViewCtxtMenu.addAction(m_addDesAct);
		lViewCtxtMenu.addAction(m_editDesAct);
		lViewCtxtMenu.addAction(m_removeDesAct);

//add by bini
		lViewCtxtMenu.addAction(m_instantiateDesAct);
		lViewCtxtMenu.addAction(m_editInstAct);
		lViewCtxtMenu.addAction(m_deleteInstantiationAct);
		lViewCtxtMenu.addAction(m_regenerateInstantiationAct);
		
		lViewCtxtMenu.addSeparator();
		lViewCtxtMenu.addAction(m_runCheckInterfToolAct);
		lViewCtxtMenu.addSeparator();
		lViewCtxtMenu.addAction(m_runSubsysIConsistToolAct);
		lViewCtxtMenu.addAction(m_runSubsysNonBlockAct);
		lViewCtxtMenu.addAction(m_runSubsysCtrlAct);
		//Added by Zain
		lViewCtxtMenu.addAction(m_runSubsysSimulationAct);
		lViewCtxtMenu.addSeparator();
		lViewCtxtMenu.addAction(m_runBddCheckInterfToolAct);
		lViewCtxtMenu.addSeparator();
		lViewCtxtMenu.addAction(m_runBddSubsysIConsistToolAct);
		lViewCtxtMenu.addAction(m_runBddSubsysNonBlockAct);
		lViewCtxtMenu.addAction(m_runBddSubsysCtrlAct);
		lViewCtxtMenu.addAction(m_runSubsysLWSynAct);
	}

	//Added by David for distributed tools
	m_distToolsMenu->addAction(m_runDistCheckAll);
	m_distToolsMenu->addAction(m_runDistNB);
	m_distToolsMenu->addAction(m_runDistCtrl);
	m_distToolsMenu->addAction(m_runDistIConsist);
	m_distToolsMenu->addSeparator();
	m_distToolsMenu->addAction(m_runDistBDDCheckAll);
	m_distToolsMenu->addAction(m_runDistBDDNB);
	m_distToolsMenu->addAction(m_runDistBDDCtrl);
	m_distToolsMenu->addAction(m_runDistBDDIConsist);
	m_distToolsMenu->addSeparator();
	m_distToolsMenu->addAction(m_runDistBDDSynth);
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::setupToolBar()
{
	ProjectWorkspace::setupToolBar();

	//add the subsytem actions in the project toolbar
	m_projectToolBar->insertAction(m_addDesAct, m_addHighLvlSubsysAct);
	m_projectToolBar->insertAction(m_addDesAct, m_addInterfaceAct);
	m_projectToolBar->insertAction(m_addDesAct, m_addLowLvlSubsysAct);
	m_projectToolBar->insertSeparator(m_addDesAct);

	//add HISC project specific tools in the tool menu
	m_toolsToolBar->addSeparator();
	m_toolsToolBar->addAction(m_runProjIConsistToolAct);
	m_toolsToolBar->addAction(m_runLevelWiseNonBlockAct);
	m_toolsToolBar->addAction(m_runLevelWiseCtrlAct);
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::setupStatusBar()
{
	ProjectWorkspace::setupStatusBar();
}


//_________________________________________________________________________________________________

void HierProjectWorkspace::onChangedCurrentSubsys(const DesSubsystem* pNewCrtSubsys, const DesSubsystem* pOldCrtSubsys)
{
	if (pNewCrtSubsys)
	{
		//a current Subsys was established so configure the actions related with the current Subsys
		m_projCompRenameAct->setEnabled(true);
		m_projCompDeleteAct->setEnabled(true);
		m_runContextSync->setEnabled(true);
		
		m_runSubsysIConsistToolAct->setEnabled(true);
		m_runSubsysNonBlockAct->setEnabled(true);
		m_runSubsysCtrlAct->setEnabled(true);
		
		m_runBddSubsysIConsistToolAct->setEnabled(true);
		m_runBddSubsysNonBlockAct->setEnabled(true);
		m_runBddSubsysCtrlAct->setEnabled(true);
		m_runSubsysLWSynAct->setEnabled(true);
		m_runSubsysSimulationAct->setEnabled(true);

		
		if (pOldCrtSubsys == null)
		{					
			//the keyboard signal was disconnected so connect it back
			connect(m_pProjStructUiPart, SIGNAL(onCurrentSubsystemDeleted()), projectEditor(), SLOT(onProjCompDelete()));
		}		
	}
	else
	{
		if (hierProjStructureUiPart().hasCurrentProjComp() == false)
		{
			//there is no current interface OR subsystem so disable actions related to them
			m_projCompRenameAct->setEnabled(false);			
			m_projCompDeleteAct->setEnabled(false);
		}

		if (hierProjStructureUiPart().hasCurrentSubsys() == false)
		{
			m_runSubsysIConsistToolAct->setEnabled(false);
			m_runSubsysNonBlockAct->setEnabled(false);
			m_runSubsysCtrlAct->setEnabled(false);

			m_runBddSubsysIConsistToolAct->setEnabled(false);
			m_runBddSubsysNonBlockAct->setEnabled(false);
			m_runBddSubsysCtrlAct->setEnabled(false);
			m_runSubsysSimulationAct->setEnabled(false);
			m_runSubsysLWSynAct->setEnabled(false);
		}

		disconnect(m_pProjStructUiPart, SIGNAL(onCurrentSubsystemDeleted()), projectEditor(), SLOT(onProjCompDelete()));
	}
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::onChangedCurrentInterf(const DesInterface* pNewCrtInterf, const DesInterface* pOldCrtInterf)
{
	if (pNewCrtInterf)
	{
		//a current interface was established so configure the actions related with the current interface
		m_projCompRenameAct->setEnabled(true);
		m_projCompDeleteAct->setEnabled(true);
		m_runContextSync->setEnabled(true);
		
		m_runCheckInterfToolAct->setEnabled(true);
		m_runBddCheckInterfToolAct->setEnabled(true);
		
		if (pOldCrtInterf == null)
		{		
			//the keyboard signal was disconnected so connect it back
			connect(m_pProjStructUiPart, SIGNAL(onCurrentInterfaceDeleted()), projectEditor(), SLOT(onProjCompDelete()));
		}		
	}
	else
	{
		if (hierProjStructureUiPart().hasCurrentProjComp() == false)
		{
			//there is no current interface OR subsystem so disable actions related to them
			m_projCompRenameAct->setEnabled(false);			
			m_projCompDeleteAct->setEnabled(false);
			m_runContextSync->setEnabled(false);
		}

		if (hierProjStructureUiPart().hasCurrentInterf() == false)
		{
			m_runCheckInterfToolAct->setEnabled(false);
			m_runBddCheckInterfToolAct->setEnabled(false);
		}

		disconnect(m_pProjStructUiPart, SIGNAL(onCurrentInterfaceDeleted()), projectEditor(), SLOT(onProjCompDelete()));
	}
}

//_________________________________________________________________________________________________

void HierProjectWorkspace::onChangedCurrentDes(Des* pNewCrtDes, Des* pOldCrtDes)
{
	ProjectWorkspace::onChangedCurrentDes(pNewCrtDes, pOldCrtDes);

	//only enable subsytem/interface rename and delete actions if no DES is selected
	if (pNewCrtDes != null)
	{
		m_projCompRenameAct->setEnabled(false);
		m_projCompDeleteAct->setEnabled(false);
		m_runContextSync->setEnabled(false);
	}
	else
	{
		m_runContextSync->setEnabled(true);
	}
}

} //end of namespace DESpot
