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

namespace DESpot
{

	typedef DesSubsystem::Dependency SubsysDepend;


	class SubsysDependsIterator: public Iterator<SubsysDepend&, const SubsysDepend&>
	{
		public:
			SubsysDependsIterator(const std::map<DesInterface*, DesSubsystem*>& dependsMap):
						m_dependsMap(dependsMap)
			{
			}
			
			virtual ~SubsysDependsIterator(void)
			{
			}

		//Iterator operations
		public:
			virtual void first() const
			{
				m_dependIt = m_dependsMap.begin();
			}
			
			virtual void next() const
			{
				if (m_dependIt == m_dependsMap.end())
					throw EX("Iteration already at the end. Call isDone() before calling next()")

				m_dependIt++;
			}
			
			virtual bool isDone() const
			{
				return (m_dependIt == m_dependsMap.end());
			}
			
			virtual SubsysDepend& currentItem()
			{
				if (isDone())
					throw EX("Iteration already at the end. Call isDone() before calling currentItem()")

				m_crtDepend.interface = m_dependIt->first;
				m_crtDepend.subsystem = m_dependIt->second;

				return m_crtDepend;
			}
			
			virtual const SubsysDepend& currentItem() const
			{
				if (isDone())
					throw EX("Iteration already at the end. Call isDone() before calling currentItem()")

				m_crtDepend.interface = m_dependIt->first;
				m_crtDepend.subsystem = m_dependIt->second;

				return m_crtDepend;
			}

		//Interdict copying
		private:
			SubsysDependsIterator(const SubsysDependsIterator& other): m_dependsMap(other.m_dependsMap) {}
			SubsysDependsIterator& operator=(const SubsysDependsIterator& /*other*/) {return *this;}
		
		private:
                        typedef std::map<DesInterface*, DesSubsystem*> SubsysDependsMap; // a map store the Interface and subsystem dependency , the interface is the key
                        typedef SubsysDependsMap::const_iterator SubsysDependsMapIt;     // a iterator for the dependency map

		private:
			const SubsysDependsMap& m_dependsMap;

			mutable SubsysDependsMapIt	m_dependIt;

			//the current dependency returned by the iterator
			mutable SubsysDepend    m_crtDepend;
	};

} //end of namespace DESpot
