/*	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 <map>
#include "Iterator.h"
#include "LinkedCompositeIterator.h"
#include "CommonDefinitions.h"
#include "Des.h"


namespace DESpot
{
	//The DES map iterator can iterate through either the supervisor DES or the plant DES
	//of a subsystem. To iterate through both use DesIterator defined in this same file. Teh DesIterator 
	//is a linked composite iterator
	class DesMapIterator : public Iterator<Des&, const Des&>
	{
		public:
			DesMapIterator(const std::map<std::wstring, Des*>& desMap):
						m_desMap(desMap)
			{
			}
		
			virtual ~DesMapIterator(void)
			{
			}
	
		public:
			virtual void first() const
			{
				m_crtDesIt = m_desMap.begin();
			}
			
			virtual void next() const
			{
				m_crtDesIt++;
			}
			
			virtual bool isDone() const
			{
				return (m_crtDesIt == m_desMap.end());
			}
			
			virtual Des& currentItem()
			{
				if (m_crtDesIt == m_desMap.end())
					throw EX("Iterator is already done. Call isDone() before.")

				return const_cast<Des&>(*(m_crtDesIt->second));
			}
			
			virtual const Des& currentItem() const
			{
				if (m_crtDesIt == m_desMap.end())
					throw EX("Iterator is already done. Call isDone() before.")

				return *(m_crtDesIt->second);
			}


		private:
			//no copying allowed
			DesMapIterator(const DesMapIterator& other) : m_desMap(other.m_desMap) {}	 
			DesMapIterator& operator=(const DesMapIterator& /*other*/) { return *this; }

		private:
			typedef std::map<std::wstring, Des*> DesMap;
			typedef DesMap::const_iterator DesMapIt;

		private:
			const DesMap m_desMap;
			mutable DesMapIt m_crtDesIt;
	};

	//_________________________________________________________________________________________________________
	//The DES iterator is simply formed by linking the supervisor iterator with the plant iterator
	class DesIterator : public LinkedCompositeIterator<Des&, const Des&>
	{
		public:
			DesIterator(DesMapIterator* pSupDesIt, DesMapIterator* pPlantDesIt):
						LinkedCompositeIterator<Des&, const Des&>(pSupDesIt, pPlantDesIt)
			{
			}
		
			virtual ~DesIterator(void)
			{
			}
	};
}
