#pragma once
#include "DummyProjCreation.h"
//for debug
// #include <iostream>


namespace DESpot

{	

	Des& DummyProject::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 low level
	DummyProject::DummyProject(const DesSubsystem* in_subsystem,TupleMap in_tuple,const DesHierProject* in_project):m_ErrorSubSystem(in_subsystem)
	{			
		std::wstring name(L"DummyProj");
		DummyProjPtr = new DesFlatProject(name);
		// Setting the trace file
		DummyProjPtr->setFileName(in_project->getFileName());
		int i=0;
		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());
					DummyProjPtr->addPlantDes(tmpPlant);

					if(!in_tuple.empty()) {
					  SimulationErrorTuple[tmpPlant]=const_cast<DesState*>(&(tmpPlant->getState(in_tuple[plantDesIt->currentItem().getName()])));
					}
				}		
	
			//Add SubSystem's supervisors 
			DesSubsystem::DesIteratorPtr SupDesIt = m_ErrorSubSystem->createDesIterator(eSupervisorDes);
				for(SupDesIt->first(); SupDesIt->notDone(); SupDesIt->next(),i++)
				{
				        tmpSup = &clone(SupDesIt->currentItem());
					DummyProjPtr->addSupDes(tmpSup);
					if(!in_tuple.empty()) {
					  SimulationErrorTuple[tmpSup]=const_cast<DesState*>(&(tmpSup->getState(in_tuple[SupDesIt->currentItem().getName()])));
					}
				}	

			//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());
						DummyProjPtr->addSupDes(tmpIntfDES);
						if(!in_tuple.empty()) {
						  SimulationErrorTuple[tmpIntfDES]=const_cast<DesState*>(&(tmpIntfDES->getState(in_tuple[iDesIt->currentItem().getName()])));
						}

					}			
			DummyProjPtr->getRootSubsys().SetDummyCreationFlag(false);	 
	}
	//==============================================================================================================
	// For high level
	DummyProject::DummyProject(const DesSubsystem* in_subsystem,
							   const DesHierProject* in_project,
							   TupleMap in_tuple):
	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;	
		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());
					DummyProjPtr->addPlantDes(tmpPlant);

					if(!in_tuple.empty()) {
					  SimulationErrorTuple[tmpPlant]=const_cast<DesState*>(&(tmpPlant->getState(in_tuple[plantDesIt->currentItem().getName()])));
					}
				}		
	
			//Add SubSystem's supervisors 
			DesSubsystem::DesIteratorPtr SupDesIt = m_ErrorSubSystem->createDesIterator(eSupervisorDes);				
				for(SupDesIt->first(); SupDesIt->notDone(); SupDesIt->next(),i++)
				{
				        tmpSup = &clone(SupDesIt->currentItem());
					DummyProjPtr->addSupDes(tmpSup);

					if(!in_tuple.empty()) {
					  SimulationErrorTuple[tmpSup]=const_cast<DesState*>(&(tmpSup->getState(in_tuple[SupDesIt->currentItem().getName()])));
					}
				}	

			//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());
							DummyProjPtr->addSupDes(tmpIntfDES);

							if(!in_tuple.empty()) {
							  SimulationErrorTuple[tmpIntfDES]=const_cast<DesState*>(&(tmpIntfDES->getState(in_tuple[iDesIt->currentItem().getName()])));
							}
						}
			
				}			
			DummyProjPtr->getRootSubsys().SetDummyCreationFlag(false);
	 
	}
	//==============================================================================================================

	DummyProject::DummyProject(const DesProject* in_project,TupleMap in_tuple)
	{		
		int i=0;
		DesProject::DesIteratorPtr DesIt = in_project->createDesIterator(ePlantDes);
				for(DesIt->first(); DesIt->notDone(); DesIt->next(),i++)
				{
					if(!in_tuple.empty())
					SimulationErrorTuple[&DesIt->currentItem()]=const_cast<DesState*>(&(DesIt->currentItem().getState(in_tuple[DesIt->currentItem().getName()])));
				}
		DesProject::DesIteratorPtr SupIt = in_project->createDesIterator(eSupervisorDes);
				for(SupIt->first(); SupIt->notDone(); SupIt->next(),i++)
				{	
					if(!in_tuple.empty())			
					SimulationErrorTuple[&SupIt->currentItem()]=const_cast<DesState*>(&(SupIt->currentItem().getState(in_tuple[SupIt->currentItem().getName()])));
				}
	}
	//===================================================================================================================

	DesProject* DummyProject::GetDummyProject()
	{
		 return (DesProject*)DummyProjPtr;
	}
	//==============================================================================================================

	DummyProject::~DummyProject()
	{
	}
}

