/*	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 "CommonDefinitions.h"
#include "DesSubsystem.h"


namespace DESpot
{
	//The subsysace iterator can iterate through the subsysaces in a project
	class SubsystemIterator : public Iterator<DesSubsystem&, const DesSubsystem&>
	{
		public:
			SubsystemIterator(const std::map<std::wstring, DesSubsystem*>& subsysMap):
						m_subsysMap(subsysMap)
			{
			}
		
			virtual ~SubsystemIterator(void)
			{
			}
	
		public:
                        virtual void first() const
			{
				m_crtSubsysIt = m_subsysMap.begin();
			}
			
			virtual void next() const
			{
				m_crtSubsysIt++;
			}
			
			virtual bool isDone() const
			{
				return (m_crtSubsysIt == m_subsysMap.end());
			}
			
			virtual DesSubsystem& currentItem()
			{
				if (m_crtSubsysIt == m_subsysMap.end())
					throw EX("Iterator is already done. Call isDone() before.")

                                return const_cast<DesSubsystem&>(*(m_crtSubsysIt->second));  //remove the const property from the object
			}
			
			virtual const DesSubsystem& currentItem() const
			{
				if (m_crtSubsysIt == m_subsysMap.end())
					throw EX("Iterator is already done. Call isDone() before.")

				return *(m_crtSubsysIt->second);
			}


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

		private:
                        typedef std::map<std::wstring, DesSubsystem*> SubsystemMap;  // a map store the DES subsystem
                        typedef SubsystemMap::const_iterator SubsystemMapIt;         // a iterator for the DES subsystem map

		private:
			const SubsystemMap m_subsysMap;
                        mutable SubsystemMapIt m_crtSubsysIt; //can be modify by a const member function
	};

} //end of namespaces DESpot
