#pragma once
#include "DummyProject_BDD.h"

namespace DESpot

{		
	Des& DummyProject_BDD::clone(Des& existing_des)
	{
		std::wstring desName= existing_des.getName();
		Des* newDes = new Des(desName, eSubsystemDes);
		DesSerializer loader(*newDes, newDes);
		loader.load_and_clone_des(existing_des);
		return *newDes;
	}
	//=======================================================================


  // for flat projects

	DummyProject_BDD::DummyProject_BDD(const DesProject* in_project,BDDSD::SD_ChkInfo& checkInfo):DummyProjPtr(const_cast<DesProject*>(in_project))
	{		
		int i=0;
		DesProject::DesIteratorPtr DesIt = in_project->createDesIterator();
		bool StateFound=false;
		for(DesIt->first(); DesIt->notDone(); DesIt->next(),i++)
		{	
			QString tempName = QString::fromStdWString(DesIt->currentItem().getName());
			std::string DesName=tempName.toStdString();
			DESpot::Des::StateIteratorPtr stateitr = DesIt->currentItem().createStateIterator();
			StateFound=false;
			if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}
					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						SimulationErrorTuple[&DesIt->currentItem()]=const_cast<DesState*>(&(DesIt->currentItem().getState(stateitr->currentItem().getId())));
						StateFound=true;
						break;
						}
					}
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}

		}
		
	}
	
	//==============================================================================================================
  // for Hierarchical projects

	DummyProject_BDD::DummyProject_BDD(const DesProject* in_project,BDDHISC::Hisc_ChkInfo& checkInfo):DummyProjPtr(const_cast<DesProject*>(in_project))
	{		
		int i=0;
		DesProject::DesIteratorPtr DesIt = in_project->createDesIterator();
		bool StateFound=false;
		for(DesIt->first(); DesIt->notDone(); DesIt->next(),i++)
		{	
			QString tempName = QString::fromStdWString(DesIt->currentItem().getName());
			std::string DesName=tempName.toStdString();	
			DESpot::Des::StateIteratorPtr stateitr = DesIt->currentItem().createStateIterator();
			StateFound=false;
			if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}
					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						SimulationErrorTuple[&DesIt->currentItem()]=const_cast<DesState*>(&(DesIt->currentItem().getState(stateitr->currentItem().getId())));
						StateFound=true;
						break;
						}
					}
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}

		}
	}
	
	//==============================================================================================================
  // for low level subsystem

	DummyProject_BDD::DummyProject_BDD(const DesSubsystem* in_subsystem,BDDHISC::Hisc_ChkInfo& checkInfo,DesProject* in_project):m_ErrorSubSystem(in_subsystem)
	{			
		std::wstring name(L"DummyProj");
		DummyProjPtr = new DesFlatProject(name);		
		int i=0;
		// Setting the trace file
		DummyProjPtr->setFileName(in_project->getFileName());
		bool StateFound=false;
		Des* tmpPlant = null;
		Des* tmpSup = null;
		Des* tmpIntfDES = null;

			//Add Subsystem's Plants 
			DesSubsystem::DesIteratorPtr plantDesIt = m_ErrorSubSystem->createDesIterator(ePlantDes);

				for(plantDesIt->first(); plantDesIt->notDone(); plantDesIt->next(),i++)
				{
				        tmpPlant = &clone(plantDesIt->currentItem());
					((DesFlatProject*)DummyProjPtr)->addPlantDes(tmpPlant);
					//((DesFlatProject*)DummyProjPtr)->addPlantDes(&clone(plantDesIt->currentItem()));
					QString tempName = QString::fromStdWString(plantDesIt->currentItem().getName());
					std::string DesName=tempName.toStdString();	
					DESpot::Des::StateIteratorPtr stateitr = tmpPlant->createStateIterator();

					StateFound=false;
					if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
					  {
					    QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					    QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					    QMessageBox::critical(NULL, "DESpot",DesNameErr);	
					  }

					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						  SimulationErrorTuple[tmpPlant]=const_cast<DesState*>(&(tmpPlant->getState(stateitr->currentItem().getId())));

						  StateFound=true;
						  break;
						}
					}
					
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}
				}				
	
			//Add SubSystem's supervisors 
			DesSubsystem::DesIteratorPtr SupDesIt = m_ErrorSubSystem->createDesIterator(eSupervisorDes);
				for(SupDesIt->first(); SupDesIt->notDone(); SupDesIt->next(),i++)
				{
 				        tmpSup = &clone(SupDesIt->currentItem());
					((DesFlatProject*)DummyProjPtr)->addSupDes(tmpSup);
					QString tempName = QString::fromStdWString(SupDesIt->currentItem().getName());
					std::string DesName=tempName.toStdString();
					DESpot::Des::StateIteratorPtr stateitr = tmpSup->createStateIterator();
					StateFound=false;
					if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}

					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						  SimulationErrorTuple[tmpSup]=const_cast<DesState*>(&(tmpSup->getState(stateitr->currentItem().getId())));
						StateFound=true;
						break;
						}
					}
					
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}

				}	

			//Add interfaces
			DummyProjPtr->getRootSubsys().SetDummyCreationFlag(true);					
			DesInterface::DesIteratorPtr iDesIt = m_ErrorSubSystem->getInterface().createDesIterator();			
					for(iDesIt->first(); iDesIt->notDone(); iDesIt->next(),i++)
					{
					        tmpIntfDES = &clone(iDesIt->currentItem());
						((DesFlatProject*)DummyProjPtr)->addSupDes(tmpIntfDES);
						QString tempName = QString::fromStdWString(iDesIt->currentItem().getName());
						std::string DesName=tempName.toStdString();	
						DESpot::Des::StateIteratorPtr stateitr = tmpIntfDES->createStateIterator();
						StateFound=false;
						if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}

					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						  SimulationErrorTuple[tmpIntfDES]=const_cast<DesState*>(&(tmpIntfDES->getState(stateitr->currentItem().getId())));
						StateFound=true;
							break;

						}
					}
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}


					}			
			DummyProjPtr->getRootSubsys().SetDummyCreationFlag(false);	 
	}
	//==============================================================================================================
  //for high level subsystem

	DummyProject_BDD::DummyProject_BDD(const DesSubsystem* in_subsystem,
									   const DesHierProject* in_project,BDDHISC::Hisc_ChkInfo& checkInfo):
										m_ErrorSubSystem(in_subsystem),m_ErrorProject(in_project)
		{				
		std::wstring name(L"DummyProj");
		DummyProjPtr = new DesFlatProject(name);
		// Setting the trace file
		DummyProjPtr->setFileName(in_project->getFileName());
		int i=0;	
		bool StateFound=false;
		Des* tmpPlant = null;
		Des* tmpSup = null;
		Des* tmpIntfDES = null;

			//Add Subsystem's Plants 
			DesSubsystem::DesIteratorPtr plantDesIt = m_ErrorSubSystem->createDesIterator(ePlantDes);

				for(plantDesIt->first(); plantDesIt->notDone(); plantDesIt->next(),i++)
				{
				        tmpPlant = &clone(plantDesIt->currentItem());
					((DesFlatProject*)DummyProjPtr)->addPlantDes(tmpPlant);
					QString tempName = QString::fromStdWString(plantDesIt->currentItem().getName());
					std::string DesName=tempName.toStdString();	
					DESpot::Des::StateIteratorPtr stateitr = tmpPlant->createStateIterator();
					StateFound=false;
					if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}

					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						  SimulationErrorTuple[tmpPlant]=const_cast<DesState*>(&(tmpPlant->getState(stateitr->currentItem().getId())));
						  StateFound=true;
						  break;

						}
					}
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}

				}				
	
			//Add SubSystem's supervisors 
			DesSubsystem::DesIteratorPtr SupDesIt = m_ErrorSubSystem->createDesIterator(eSupervisorDes);
				for(SupDesIt->first(); SupDesIt->notDone(); SupDesIt->next(),i++)
				{
 				        tmpSup = &clone(SupDesIt->currentItem());
					((DesFlatProject*)DummyProjPtr)->addSupDes(tmpSup);
					QString tempName = QString::fromStdWString(SupDesIt->currentItem().getName());
					std::string DesName=tempName.toStdString();
					DESpot::Des::StateIteratorPtr stateitr = tmpSup->createStateIterator();
					StateFound=false;
					if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}

					for(stateitr->first();stateitr->notDone();stateitr->next())
					{	
						if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
						{
						  SimulationErrorTuple[tmpSup]=const_cast<DesState*>(&(tmpSup->getState(stateitr->currentItem().getId())));
						  StateFound=true;
						  break;

						}
					}					
					if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}

				}	


			//Add interfaces
			DummyProjPtr->getRootSubsys().SetDummyCreationFlag(true);						
			DesHierProject::InterfIteratorPtr interfIt = m_ErrorProject->createInterfIterator();
				for(interfIt->first(); interfIt->notDone(); interfIt->next())
				{
					const DesInterface& interf = interfIt->currentItem();		
					DesInterface::DesIteratorPtr iDesIt = interf.createDesIterator();			
						for(iDesIt->first(); iDesIt->notDone(); iDesIt->next(),i++)
						{
						        tmpIntfDES = &clone(iDesIt->currentItem());
							((DesFlatProject*)DummyProjPtr)->addSupDes(tmpIntfDES);
							QString tempName = QString::fromStdWString(iDesIt->currentItem().getName());
							std::string DesName=tempName.toStdString();	
							DESpot::Des::StateIteratorPtr stateitr = tmpIntfDES->createStateIterator();
							StateFound=false;
							if(checkInfo.CE_tuplemap.find(DesName)==checkInfo.CE_tuplemap.end())
				{
					QString Terr ="Fatal Error: The error tuple provided by the algorithm did not have an entry for the DES \"%1\". Please inform DESpot developers.";
					QString DesNameErr=Terr.arg(QString::fromStdString(DesName));
					QMessageBox::critical(NULL, "DESpot",DesNameErr);	
				}
								
								for(stateitr->first();stateitr->notDone();stateitr->next())
								{	
									if(stateitr->currentItem().getName() == checkInfo.CE_tuplemap[DesName])
									{
									  SimulationErrorTuple[tmpIntfDES]=const_cast<DesState*>(&(tmpIntfDES->getState(stateitr->currentItem().getId())));
									  StateFound=true;
									  break;

									}
								}
								if(!StateFound)
						{
							QString tempError = "The current state name \"%1\" was not found in the statepool of \"%2\" DES. Please inform the DESpot developers";
							QString Statename = QString::fromStdWString(checkInfo.CE_tuplemap[DesName]);
							QString DESName	= QString::fromStdString(DesName);
							QString StateLookupError=tempError.arg(Statename,DESName);							
							QMessageBox::critical(NULL, "DESpot",StateLookupError);	
						}

						}
			
				}			
			DummyProjPtr->getRootSubsys().SetDummyCreationFlag(false);
	 
	}
	//==============================================================================================================

	

	DummyProject_BDD::~DummyProject_BDD()
	{
	}
	

DesProject* DummyProject_BDD::GetDummyProject()
	{
		 return DummyProjPtr;
	}


}
