/*	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 <QMenuBar>
#include <QToolBar>
#include <QIcon>
#include <QStatusBar>
#include <QMessageBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QInputDialog>

#include "CommonDefinitions.h"
#include "ProjectEditor.h"
#include "MainForm.h"
#include "EventPoolForm.h"
#include "ProjectWorkspace.h"
#include "ProjStructureUiPart.h"
#include "DesEditor.h"
#include "NameValidator.h"
#include "MeetAlgo.h"
#include "SyncAlgo.h"
#include "CtrlStdAlgo.h"
#include "OutputUiPart.h"
#include "ProjectPrinter.h"
#include "ProjIntegrityAlgo.h"
#include "WaitCursor.h"
#include "NonBlockingAlgo.h"
#include "MultiCtrlAlgo.h"
#include "MultiNonBlockingAlgo.h"

#include "GedDesEditor.h"
#include "SimConfig.h"
//test
#include <iostream>

#ifdef _WIN32
#include <time.h>
#include <sys/types.h>
#else
#include <sys/time.h>
#endif

#include "DistributedConfigDialog.h"
#include "Instantiation.h"
//add by bini
//#include "InstantiateTemplate.h"

namespace DESpot
{
//modified by bini
ProjectEditor::ProjectEditor(MainForm* pMainForm, FormType formType) :
			DespotForm(pMainForm, this, pMainForm, formType),
			m_pWorkspace(null), m_pCrtDes(null),m_pCrtInst(null)
{
	//set form attributes
	setAttribute(Qt::WA_DeleteOnClose);

	m_pEventPoolForm = null;
	m_pProject = null;
}

//_________________________________________________________________________________________________
//modified by bini
ProjectEditor::ProjectEditor(DesProject* project, MainForm* pMainForm, FormType formType) :
		DespotForm(pMainForm, this, pMainForm, formType),
		m_pProject(project), m_pWorkspace(null), m_pCrtDes(null), m_pCrtInst(null)
{
	//set form attributes
	setAttribute(Qt::WA_DeleteOnClose);
	//MainpProjectEditor->
	m_pEventPoolForm = null;
}
//_________________________________________________________________________________________________

ProjectEditor::~ProjectEditor(void)
{
	if (m_pWorkspace)
	{
		delete m_pWorkspace;
		m_pWorkspace = null;
	}
}
//_________________________________________________________________________________________________

DesProject* ProjectEditor::project()
{
	return m_pProject;
}

//_________________________________________________________________________________________________

QString ProjectEditor::getDocName()
{
	return QString::fromStdWString(m_pProject->getName());
}

//_________________________________________________________________________________________________

QString ProjectEditor::getDocFileName()
{
	return QString::fromStdWString(m_pProject->getFileName());
}

//_________________________________________________________________________________________________
bool ProjectEditor::eventFilter(QObject* target, QEvent* event)
{
	if (event->type() == QEvent::Destroy)
	{
		if (target == (QObject*)m_pEventPoolForm)
		{
			//the event pool is being destroyed; release the pointer
			m_pEventPoolForm = null;
		}
	}

	return QMainWindow::eventFilter(target, event);
}

//_________________________________________________________________________________________________

void ProjectEditor::closeEvent(QCloseEvent *event)
{
	if (m_pProject->isModified())
	{
		QString msg = STR_SAVE_MODIFIED_PROJECT(QString::fromStdWString(m_pProject->getName()));
		switch (QMessageBox::question(this, STR_DESPOT, msg, QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel))
		{
			case QMessageBox::Yes:
				if (attemptSaveProject())
				{
					event->accept();
				}
				else
				{
					event->ignore();
					return;
				}
				break;

			case QMessageBox::Cancel:
				event->ignore();
				return;

			case QMessageBox::No:
				event->accept();
				break;

                        default:
                                event->ignore();
                                break;

		}
	}
	else
	{
		event->accept();
	}

	if (onCloseForm() == false)
	{
		event->ignore();
		return;
	}

}

//_________________________________________________________________________________________________
OutputUiPart& ProjectEditor::output()
{
	return m_pWorkspace->outputUiPart();
}

//_________________________________________________________________________________________________

UpdateProgressInterface* ProjectEditor::progressInterface()
{
	return static_cast<UpdateProgressInterface*>(m_pWorkspace->progressWidget());
}

//_________________________________________________________________________________________________
//add by bini
void ProjectEditor::setupConnections()
{
	connect(&m_pWorkspace->projStructureUiPart(), SIGNAL(onChangedCurrentDes(Des* , Des*)),
			this, SLOT(onChangedCurrentDes(Des* , Des*)));
	connect(&m_pWorkspace->projStructureUiPart(),SIGNAL(onChangedCurrentInst(Instantiation*,Instantiation*)),
			this,SLOT(onChangedCurrentInst(Instantiation*,Instantiation*)));
}

//_________________________________________________________________________________________________

void ProjectEditor::updateWindowTitle()
{
	QString projName = QString::fromStdWString(m_pProject->getName());
	QString projFileName = QString::fromStdWString(m_pProject->getFileName());
	QString windowTitle;

	if (projFileName.isEmpty())
	{
		windowTitle = projName + "*" + STR_DESPOT;
	}
	else
	{
		QFileInfo fileInfo(projFileName);

		windowTitle = projName + " - " + fileInfo.fileName() + " - " + fileInfo.path();
	}
	setWindowTitle(windowTitle);
}

//_________________________________________________________________________________________________

bool ProjectEditor::attemptSaveProject()
{
	//If the project has never been saved before run Save As to have the use select a file name
	if (m_pProject->isNew())
		return attemptSaveProjectAs();

	//before saving the project make sure all DES in the project are saved as the project
	//references those DES
	if (saveProjectDes() == false)
	{
		//the user canceled the save process
		return false;
	}

	m_pProject->save();

	return true;
}

//_________________________________________________________________________________________________

bool ProjectEditor::attemptSaveProjectAs()
{
	QString absoluteFileName = m_pProject->isNew()? QString::fromStdWString(m_pProject->getName()) : QString::fromStdWString(m_pProject->getFileName()); 
	if (MainForm::getSaveFileName(this, STR_SAVE_PROJ_AS_DLG_TITLE, STR_PROJ_FILE_DLG_FILTER, absoluteFileName) == false)
	{
		//user canceled the save as
		return false;
	}

	NameValidator fileNameValidator(new AlphaNumValidator(new WordSepValidator(new DotValidator())));
	std::wstring fileName = QFileInfo(absoluteFileName).fileName().toStdWString();
	if (fileNameValidator.validate(fileName) == false)							  
	{
		std::wstring message = L"Invalid project file name (";
		message += fileName;
		message += L"). Use an alpha-numeric string (a-z;A-Z;0-9;.-_)";
		throw message;
	}

	//before saving the project make sure all DES in the project are saved as the project
	//references those DES
	if (saveProjectDes() == false)
	{
		//the user canceled the save process
		return false;
	}

	m_pProject->save(absoluteFileName.toStdWString());

	return true;
}

//_________________________________________________________________________________________________

bool ProjectEditor::saveProjectDes()
{
	//count the modified DES that need to be saved

	int totalModifiedDes = 0;
	DesProject::DesIteratorPtr desIt = m_pProject->createDesIterator();
	for (desIt->first(); desIt->notDone(); desIt->next())
	{
		if (desIt->currentItem().isModified())
		{

			if(desIt->currentItem().isInstantiation())
			{

			}			
		
			else
			{
				totalModifiedDes++;
			
			}
		}
	}
	DesProject::DesIteratorPtr templateIt=m_pProject->createDesIterator(eTemplateDes);
	for (templateIt->first(); templateIt->notDone(); templateIt->next())
	{
		if (templateIt->currentItem().isModified())
		{	
			totalModifiedDes++;
		}
	}

	/*if(m_pProject->getType()==eHierProject)
	{
		HierDesProject::InterfIteratorPtr interfIt = m_pProject->createInterfIterator();
		DesInterface::DesIteratorPtr tempIt = interfITcreateDesIterator(eTemplateDes);
		for(interfIt->first(); interfIt->notDone(); interfIt->next())
		{
			const DesInterface& crtInterf = interfIt->currentItem();
			DesInterface::DesIteratorPtr tempIt = crtInterf.createDesIterator(eTemplateDes);
			for(tempIt->first();tempIt->notDone();tempIt->next())
			{
				if (templateIt->currentItem().isModified())
				{	
					totalModifiedDes++;
				}
			}
		}
	}*/
			
	//check to see if any DES need to be modified
	if (totalModifiedDes == 0)
	{
		return true;
	}

	//setup the defaults that the user can modify in the process of answering the confirmation question
	bool askForConfirmation = true;
	QMessageBox::StandardButton defaultUserAnswer = QMessageBox::Yes;

	//go through each modified des and save them
	desIt = m_pProject->createDesIterator();
	for (desIt->first(); desIt->notDone(); desIt->next())
	{
		Des& crtDes = desIt->currentItem();
		
		if (crtDes.isModified())
		{
			if (crtDes.isInstantiation())
			{
				//mark the project as modified since this DES is new and even if nothing else
				//was modified on the project since opening this DES doesn't have a file and the file
				//will be provided upon saving the DES. However if the project is not set as modified
				//the DES file name will not be saved in the project file
				continue;
			}
			else 
			{
				m_pProject->setModified();
			}
			
			//a DES editor is not opened so manually ask for confirmation
			QMessageBox::StandardButton userAnswer = defaultUserAnswer;
			
			if (askForConfirmation)
			{
				//ask the user if they want to save the DES and save it if they agree
				//get confirmation from the user on saving all modified DES or one-by-one. Note that there could be 
				//a lot of DES that need to be saved.
				QString msg = STR_SAVE_MODIFIED_DES(QString::fromStdWString(crtDes.getName()));		
				msg += STR_SAVE_MODIFIED_DES_REMAINING(totalModifiedDes - 1);
				userAnswer = QMessageBox::question(this, STR_DESPOT_WARNING, msg, 
																  QMessageBox::Yes | QMessageBox::YesToAll | 
																  QMessageBox::No | QMessageBox::NoToAll | 
																  QMessageBox::Cancel, 
																  QMessageBox::Cancel);
			}

			switch(userAnswer)
			{
				case QMessageBox::Yes:	
				{
					DesEditor* pDesEditor = null;
					if (mainForm()->editorOpened(&crtDes, pDesEditor))
					{			
						//this will save without asking for confirmation if the des is not NEW. If the des is new
						//the save as dialog will be displayed
						pDesEditor->onSaveDes();						
					}
					else
					{				
						DesEditor::onAttemptSaveDes(&crtDes, this);						
					}
					break;
				}

				case QMessageBox::YesToAll:
				{
					DesEditor* pDesEditor = null;
					if (mainForm()->editorOpened(&crtDes, pDesEditor))
					{			
						//this will save without asking for confirmation if the des is not NEW. If the des is new
						//the save as dialog will be displayed
						pDesEditor->onSaveDes();						
					}
					else
					{				
						DesEditor::onAttemptSaveDes(&crtDes, this);						
					}
					defaultUserAnswer = QMessageBox::Yes;
					askForConfirmation = false;
					break;
				}

				case QMessageBox::No:
					//go to the next DES
					break;

				case QMessageBox::NoToAll:
					defaultUserAnswer = QMessageBox::No;
					askForConfirmation = false;
					break;

				case QMessageBox::Cancel:
                                        return false;

                                default:
                                        return false;
			}

			totalModifiedDes--;
		}
	}

templateIt=m_pProject->createDesIterator(eTemplateDes);
for (templateIt->first(); templateIt->notDone(); templateIt->next())
	{
		Des& crtDes = templateIt->currentItem();
		
		if (crtDes.isModified())
		{
			if (crtDes.isNew())
			{
				//mark the project as modified since this DES is new and even if nothing else
				//was modified on the project since opening this DES doesn't have a file and the file
				//will be provided upon saving the DES. However if the project is not set as modified
				//the DES file name will not be saved in the project file
				m_pProject->setModified();
			}
			
			//a DES editor is not opened so manually ask for confirmation
			QMessageBox::StandardButton userAnswer = defaultUserAnswer;
			
			if (askForConfirmation&&m_pProject->isModified())
			{
				//ask the user if they want to save the DES and save it if they agree
				//get confirmation from the user on saving all modified DES or one-by-one. Note that there could be 
				//a lot of DES that need to be saved.
				QString msg = STR_SAVE_MODIFIED_DES(QString::fromStdWString(crtDes.getName()));		
				msg += STR_SAVE_MODIFIED_DES_REMAINING(totalModifiedDes - 1);
				userAnswer = QMessageBox::question(this, STR_DESPOT_WARNING, msg, 
																  QMessageBox::Yes | QMessageBox::YesToAll | 
																  QMessageBox::No | QMessageBox::NoToAll | 
																  QMessageBox::Cancel, 
																  QMessageBox::Cancel);
			}

			switch(userAnswer)
			{
				case QMessageBox::Yes:	
				{
					DesEditor* pDesEditor = null;
					if (mainForm()->editorOpened(&crtDes, pDesEditor))
					{			
						//this will save without asking for confirmation if the des is not NEW. If the des is new
						//the save as dialog will be displayed
						pDesEditor->onSaveDes();						
					}
					else
					{				
						DesEditor::onAttemptSaveDes(&crtDes, this);						
					}
					break;
				}

				case QMessageBox::YesToAll:
				{
					DesEditor* pDesEditor = null;
					if (mainForm()->editorOpened(&crtDes, pDesEditor))
					{			
						//this will save without asking for confirmation if the des is not NEW. If the des is new
						//the save as dialog will be displayed
						pDesEditor->onSaveDes();						
					}
					else
					{				
						DesEditor::onAttemptSaveDes(&crtDes, this);						
					}
					defaultUserAnswer = QMessageBox::Yes;
					askForConfirmation = false;
					break;
				}

				case QMessageBox::No:
					//go to the next DES
					break;

				case QMessageBox::NoToAll:
					defaultUserAnswer = QMessageBox::No;
					askForConfirmation = false;
					break;

				case QMessageBox::Cancel:
                                        return false;

                                default:
                                        return false;
			}

			totalModifiedDes--;
		}
	}

	//we have saved all DES that the user wanted to save
	return true;
}

//_________________________________________________________________________________________________

void ProjectEditor::onChangedCurrentDes(Des* pCrtDes, Des* pOldCrtDes)
{
	//Remove unused warning in release
	pOldCrtDes = pOldCrtDes;

	//change the current component. The old current component should match with what the editor
	//had as the current componenent
	//assert(m_pCrtDes == pOldCrtDes);
	m_pCrtDes = pCrtDes;
}
//_________________________________________________________________________________________________
//add by bini
void ProjectEditor::onChangedCurrentInst(Instantiation* pCrtInst, Instantiation* pOldCrtInst)
{
	//Remove unused warning in release
	pOldCrtInst = pOldCrtInst;

	//change the current component. The old current component should match with what the editor
	//had as the current componenent
	//assert(m_pCrtInst == pOldCrtInst);
	m_pCrtInst = pCrtInst;
}

//_________________________________________________________________________________________________

void ProjectEditor::onSaveProject()
{
	try
	{
		if (attemptSaveProject())
		{
			updateWindowTitle();
		}
	}
	catch_display_xml_ex()
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onSaveProjectAs()
{
	try
	{
		if (attemptSaveProjectAs())
		{	
			updateWindowTitle();
		}
	}
	catch_display_xml_ex()
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onDisplayEventPool()
{
	if (m_pEventPoolForm == null)
	{
		m_pEventPoolForm = new EventPoolForm(m_pMainForm, this);
		m_pEventPoolForm->installEventFilter(this);
	}

	m_pEventPoolForm->open();
}

//_________________________________________________________________________________________________

void ProjectEditor::onProjectSetName()
{
	try
	{
		QString projName = QInputDialog::getText(this, STR_PROJ_NAME_DLG_TITLE,
						STR_PROJ_NAME_DLG_LABEL, QLineEdit::Normal,
						QString::fromStdWString(m_pProject->getName()));

		//empty project names are not allowed. If the user has left the name empty put the default name
		if (projName.isEmpty() == false)
		{
			//change the name of the project. If use has not supplied a name change it to the default name
			m_pProject->setName(projName.toStdWString());

			//update the title of the window
			updateWindowTitle();
		}
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onPrintProject()
{
	try
	{
		QString absoluteFileName;
		if (m_pProject->isNew())
		{
			absoluteFileName = QString::fromStdWString(m_pProject->getName()) + ".txt";
		}
		else
		{
			QFileInfo projFileInfo(QString::fromStdWString(m_pProject->getFileName()));
			absoluteFileName = projFileInfo.absolutePath() + "/" + projFileInfo.completeBaseName() + ".txt";
		}

		if (MainForm::getSaveFileName(this, STR_PRINT_TO_FILE_PROJ_DLG_TITLE, STR_TXT_FILE_DLG_FILTER, absoluteFileName))
		{

		  //getSaveFileName  is adding the .desp extension, so we need
		  // to remove that
		  if (absoluteFileName.endsWith(".desp",Qt::CaseInsensitive)) 
		    {
		      absoluteFileName.remove((absoluteFileName.length()-5), 5);
		    }

			ProjectPrinter printer(*m_pProject);
			printer.print(absoluteFileName.toStdWString());
		}
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onCloseProject()
{
	close();
}

//_________________________________________________________________________________________________

void ProjectEditor::onAddDes()
{
	//Implemented in specific project editors (flat or HISC)
}

//_________________________________________________________________________________________________

void ProjectEditor::onEditDes()
{
	try
	{
		if (m_pCrtDes)
		{

			if (m_pWorkspace->useGraphEditor())
			{
				GedDesEditor* pDesEditor = null;

				//if (mainForm()->editorOpened(m_pCrtDes, pDesEditor) == false)
				//{
					//create an editor that will load the DES from the selected file
					pDesEditor = new GedDesEditor(m_pCrtDes, this, mainForm());
					if(m_pCrtDes->isInstantiation())
					{
						emit setInstMode();
					}
				//}

				//display the DES to the user
				pDesEditor->open();
			}
			else
			{
				DesEditor* pDesEditor = null;
				if (mainForm()->editorOpened(m_pCrtDes, pDesEditor) == false)
				{
					//create an editor that will load the DES from the selected file
					pDesEditor = new DesEditor(m_pCrtDes, this, mainForm());
				}

				//display the DES to the user
				pDesEditor->open();
			}
		}
		else
		{
			//this handler shoudn't be called if no component is selected - it's corresponding action
			//should have been disabled
			assert(false);
		}
	}
	catch_display_xml_ex()
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRemoveDes()
{
	try
	{
		if (m_pCrtDes)
		{
			std::wstring crtDesName = m_pCrtDes->getName();

			// added to make sure a template is not
			// deleted if it still has instantiations.
			// Instantiations must first be deleted 
			// separately.
			if (m_pCrtDes->isInstantiated()) {
                           QMessageBox::critical(this, STR_DESPOT_ERROR, tr("This template DES still contains an instantiation.  You must delete the instantiation first.")); 
			   return;
			}


			//ask the user for confirmation
			QString delDesWarning = STR_DELETE_DES_FROM_PROJ(QString::fromStdWString(crtDesName));
			if (QMessageBox::question(this, STR_DESPOT, delDesWarning, 
				QMessageBox::Yes|QMessageBox::No) == QMessageBox::No)
			{
				return; //the user canceled the operation
			}

			Des* removedDes = m_pCrtDes;
            if(m_pProject->getType()==eFlatProject)
            {
                m_pProject->deleteDes(crtDesName);
            }
            else
            {
                   DesHierProject* hp=(DesHierProject*) m_pProject;
                   if(m_pCrtDes->getType()==eSubsystemDes)
                   {
                        hp->deleteDes(crtDesName,*(m_pCrtDes->getSubsystemOwner()));
                   }
                   else
                   {
                        hp->deleteDes(crtDesName,*(m_pCrtDes->getInterfaceOwner()));
                   }
            }

			//make sure the current DES doesn't point to the one that we've just deleted
			if (m_pCrtDes == removedDes)
			{
				assert(m_pCrtDes != removedDes); //the current des should have been changed by the deletion notification)
				m_pCrtDes = null;
			}
		}
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________
//add by bini
void ProjectEditor::onInstantiateTemplate()
{


}


//_________________________________________________________________________________________________
//add by bini
void ProjectEditor::onDeleteInstantiation(bool askConfirm)
{


}


//_________________________________________________________________________________________________
//add by bini
void ProjectEditor::onRegenerateInstantiation()
{


}


//_________________________________________________________________________________________________

//add by bini
void ProjectEditor::onEditInst()
{

}


//_________________________________________________________________________________________________
void ProjectEditor::onCheckProjectIntegrity()
{
	//this should be implemented in sub-classes so they can create the proper algorithm
	//Derived classes can call the overload that receives the integrity algorithm as a parameter
	//If a derived class doesn't implement this it will display as not implemented
	QMessageBox::information(this, "DESpot","Feature not implemented yet in this editor.");
}

//_________________________________________________________________________________________________

void ProjectEditor::onCleanProject()
{
	try
	{
		m_pProject->clean();
		QMessageBox::information(this, STR_DESPOT, STR_PROJECT_CLEANED);
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onCheckProject()
{
	//this should be implemented in sub-classes so they can create the proper algorithm
	//Derived classes can call the overload that receives the integrity algorithm as a parameter
	//If a derived class doesn't implement this it will display as not implemented
	QMessageBox::information(this, "DESpot","Feature not implemented yet in this editor.");
}

//_________________________________________________________________________________________________

void ProjectEditor::onCheckProjectIntegrity(ProjIntegrityAlgo& integAlgo)
{
	try
	{
		WaitCursor wait(this);

		integAlgo.provideProgress(progressInterface());

		m_pProject->checkIntegrity(integAlgo);

		output().show(integAlgo);
	}
	catch(const std::wstring& e)
	{
		output().show(OutputUiPart::eProjectIntegrityCheck, L"An error occurred while checking the project integrity", e);
	}
	catch_display_all()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRunMeetTool()
{
	try
	{
		WaitCursor wait(this);

		MeetAlgo meetAlgo(m_pProject->createDesIterator());
		if (meetAlgo.runEx(progressInterface()))
		{
			Des* resultDes = meetAlgo.returnResult();

			//create an editor that will load the DES from the selected file
			DesEditor* pDesEditor = new DesEditor(resultDes, mainForm());

			//display the DES to the user
			pDesEditor->open();

		}
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRunSyncProductTool()
{
	try
	{
		WaitCursor wait(this);

		SyncAlgo syncAlgo(m_pProject->createDesIterator());
		if (syncAlgo.runEx(progressInterface()))
		{
			Des* resultDes = syncAlgo.returnResult();

			//create an editor that will load the DES from the selected file
			DesEditor* pDesEditor = new DesEditor(resultDes, mainForm());

			//display the DES to the user
			pDesEditor->open();
		}
	}
	catch_display_ex()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRunNonBlockingTool()
{
	try
	{
		WaitCursor wait(this);







      /*
		//check each DES in the flat project to make sure it is valid
		//make sure that all input DES are valid
		const DesProject::DesIteratorPtr desIterator = m_pProject->createDesIterator();
		for(desIterator->first(); desIterator->notDone(); desIterator->next())
		{
			const Des& crtDes = desIterator->currentItem();
			if (crtDes.getIntegrity() != eIntegYes)
			{
				QMessageBox::critical(this, STR_DESPOT_ERROR, STR_INPUT_DES_INVALID(QString::fromStdWString(crtDes.getName())));
				return;
			}
		}
		*/

		MultiNonBlockingAlgo flatNonBlock;
/*
	DesSubsystem::DesIteratorPtr hDesIt = m_pProject->createDesIterator();
	for(hDesIt->first(); hDesIt->notDone(); hDesIt->next())
	{
		const Des& hDes = hDesIt->currentItem();

		if (hDes.getIntegrity() != eIntegYes)
		{
			throw EX("The DES need to be varified to be valid");
		}
		flatNonBlock.addInputDes(&hDes);
	}

*/

			DesSubsystem::DesIteratorPtr hDesIt = m_pProject->createDesIterator();
	for(hDesIt->first(); hDesIt->notDone(); hDesIt->next())
	{
		const Des& hDes = hDesIt->currentItem();

		flatNonBlock.addInputDes(&hDes);
	}





	        flatNonBlock.provideProgress(NULL);


		time_t tstart;
		time(&tstart);

		m_pProject->checkNonBlocking(flatNonBlock);

		time_t tend;
		time(&tend);

		//output().showMeasurements(&m_pProject->getFlatSystemDes());
		output().show(flatNonBlock);
		output().showTime(tend - tstart);
	}
	catch(const std::wstring& e)
	{
		output().show(OutputUiPart::eNonBlockingCheck, L"An error occurred while running the nonblocking algorithm", e);
	}
	catch_display_all()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRunMultiCtrlTool()
{
	try
	{
		WaitCursor wait(this);

		MultiCtrlAlgo ctrlAlgo(m_pProject->createDesIterator(ePlantDes), m_pProject->createDesIterator(eSupervisorDes));	

		ctrlAlgo.provideProgress(NULL);

		time_t tstart;
		time(&tstart);

		m_pProject->checkControllable(ctrlAlgo);

		time_t tend;
		time(&tend);

		output().show(ctrlAlgo);
		output().showTime(tend - tstart);

	}
	catch(const std::wstring& e)
	{
		output().show(OutputUiPart::eControllabilityCheck, L"An error occurred while running the controllability algorithm", e);
	}
	catch_display_all()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRunCtrlTool()
{
	try
	{
		WaitCursor wait(this);
		//SyncAlgo plantSyncAlgo(m_pProject->createDesIterator(ePlantDes));	
		//plantSyncAlgo.runEx(progressInterface());

		//SyncAlgo supSyncAlgo(m_pProject->createDesIterator(eSupervisorDes));
		//supSyncAlgo.runEx(progressInterface());

		//MultiCtrlAlgo ctrlAlgo(plantSyncAlgo.getOutputDes(), supSyncAlgo.getOutputDes());

		
		
		MultiCtrlAlgo ctrlAlgo(m_pProject->createDesIterator(ePlantDes),m_pProject->createDesIterator(eSupervisorDes));
		ctrlAlgo.provideProgress(NULL);

		time_t tstart;
		time(&tstart);

		m_pProject->checkControllable(ctrlAlgo);

		time_t tend;
		time(&tend);

		output().show(ctrlAlgo);
		output().showTime(tend - tstart);

	}
	catch(const std::wstring& e)
	{
		output().show(OutputUiPart::eControllabilityCheck, L"An error occurred while running the controllability algorithm", e);
	}
	catch_display_all()
}

//_________________________________________________________________________________________________

void ProjectEditor::onRunSynthesisTool()
{
	try
	{
		QMessageBox::information(this, "DESpot","Feature not implemented yet.");
	}
	catch_display_ex()
}

// Add by XMA, Jul/10/08. To add entry to simulation tool
void ProjectEditor::onRunSimTool()
{
	try
	{
		if (m_pProject->getIntegrity() != eIntegYes){
			QMessageBox::information(this, "DESpot","Project is invalid or has not been validated yet.");
			return;
		}
			

		SimConfig* pSimConfig = new SimConfig(m_pProject, m_pMainForm, this,DespotForm::eSimConfig);
		//SimConfig* pSimConfig = new SimConfig(m_pProject, this, DespotForm::eSimConfig);

		pSimConfig->open();
		pSimConfig->initSimConfig();
	}
	catch_display_ex()
}

//Added by Zain to load counter example in the simulator
/*******************************************************************/
void ProjectEditor::onRunCounterExampleTool()
{
	try
	{
		if (m_pProject->getIntegrity() != eIntegYes)
		{
			QMessageBox::information(this, "DESpot","Project is invalid or has not been validated yet.");
			return;
		}

	  switch(m_pProject->getDebugMode())
	  {
		case DesProject::CounterExample:		
		//counter example loading
		{
			SimConfig* pSimConfig = new SimConfig(m_pProject->getDummyProject(), m_pMainForm, this,DespotForm::eSimConfig);
			pSimConfig->open();		
			pSimConfig->CounterExampleConfig(m_pProject->getCounterExample());
			break;
		}		
		
		case DesProject::ErrorTuple:
		{
			SimConfig* pSimConfig = new SimConfig(m_pProject->getDummyProject(), m_pMainForm, this,DespotForm::eSimConfig);		
			pSimConfig->open();
			pSimConfig->ErrorStateConfig(m_pProject->getSimulationErrorTuple());
			break;
		}

		case DesProject::Uninitialized:
		{
			QMessageBox::information(this, "DESpot","No algorithm has been run yet. You need to run some algorithm first.");
			return;
		}
		case DesProject::Reset:
		{
			QMessageBox::information(this, "DESpot","The previous algorithm either did not generate any errors or it is not supported.");
			return;
		}
	  }
	}
	catch_display_ex()
}

//Added by Zain to load error state tuple in the simulator
/*******************************************************************/
/*
void ProjectEditor::onRunErrorStateTool()
{
	try
	{
		if (m_pProject->getIntegrity() != eIntegYes){
			QMessageBox::information(this, "DESpot","Project is invalid or has not been validated yet.");
			return;
		}	
		
		SimConfig* pSimConfig = new SimConfig(m_pProject, m_pMainForm, this,DespotForm::eSimConfig);		
		pSimConfig->open();
		pSimConfig->ErrorStateConfig(m_pProject->getSimulationErrorTuple());
		
	}
	catch_display_ex()
}
*/
/**********************************************************************/
//#ifdef __ENABLE_BDD__

void ProjectEditor::onRunBddMeetTool()
{
	try
	{
		QMessageBox::information(this, "DESpot","Feature not implemented yet.");
	}
	catch_display_ex()
}

/* Removed by Adam. no longer used in flat only hisc (moved to HierProjectEditor.cpp)

void ProjectEditor::onRunBddMultiCtrlTool()
{
	try
	{
		QMessageBox::information(this, "DESpot","Feature not implemented yet.");
	}
	catch_display_ex()
}
*/
void ProjectEditor::onRunBddSyncProductTool()
{
	try
	{
		QMessageBox::information(this, "DESpot","Feature not implemented yet.");
	}
	catch_display_ex()
}
/* Removed by Adam. no longer used in flat only hisc (moved to HierProjectEditor.cpp)
void ProjectEditor::onRunBddNonBlockingTool()
{
	try
	{
		QMessageBox::information(this, "DESpot","Feature not implemented yet.");
	}
	catch_display_ex()
}
*/
void ProjectEditor::onRunBddSynthesisTool()
{
	try
	{
		QMessageBox::information(this, "DESpot","Feature not implemented yet.");
	}
        catch_display_ex()
}
//#endif

// Added by David for Distributed tools

void ProjectEditor::onRunConfigDist()
{
	try
	{
		DistributedConfigDialog distConfig(this);
		distConfig.exec();

		//QMessageBox::information(this, "DESpot","Config not implemented yet.");
	}
    catch_display_ex()
}
} //end of namespace DESpot
