#pragma once

#include <map>
#include "Iterator.h"
#include "CommonDefinitions.h"
#include "Des.h"
//#include "InstantiateTemplate.h"
//#include "Instantiation.h"


namespace DESpot
{
	class Instantiation;
	class InstMapIterator : public Iterator<Instantiation&, const Instantiation&>
	{
		public:
			InstMapIterator(const std::map<std::wstring, Instantiation*>& instMap):
						m_InstMap(instMap)
			{
			}
		
			virtual ~InstMapIterator(void)
			{
			}
	
		public:
			virtual void first() const
			{
				m_crtInstMapIt = m_InstMap.begin();
			}
			
			virtual void next() const
			{
				m_crtInstMapIt++;
			}
			
			virtual bool isDone() const
			{
				return (m_crtInstMapIt == m_InstMap.end());
			}
			
			virtual Instantiation& currentItem()
			{
				if (m_crtInstMapIt == m_InstMap.end())
					throw EX("Iterator is already done. Call isDone() before.")

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

				return *(m_crtInstMapIt->second);
			}


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

		private:
			typedef std::map<std::wstring, Instantiation*> InstMap;
			typedef InstMap::const_iterator InstMapIt;

		private:
			const InstMap m_InstMap;
			mutable InstMapIt m_crtInstMapIt;
	};
}
