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

namespace DESpot
{
	class ListIterator : public DESpot::Iterator<DesState*, const DesState*>
	{
		public:
			ListIterator(std::list<const DesState*>& elemList) : m_elemList(elemList)
			{
			}

			virtual ~ListIterator(void)
			{
			}

	public:
		virtual void first() const 
		{
			//start with the first element 
			m_crtElemIt = m_elemList.begin();
		}

		virtual void next() const
		{
			if (isDone())
				throw EX("Iteration already at the end. Cannot go even further")

			//Advance the iterator to the next state
			++m_crtElemIt;
		}
		
		virtual bool isDone() const
		{
			return m_crtElemIt == m_elemList.end();
		}
		
		virtual DesState* currentItem()
		{
			if (isDone())
				throw EX("Iteration already at the end.  Cannot return item")
			
			return const_cast<DesState*>(*m_crtElemIt);
		}

		virtual const DesState*  currentItem() const
		{
			if (isDone())
				throw EX("Iteration already at the end.  Cannot return item")

			return *m_crtElemIt;
		}

		private:
			//disallow copying
			ListIterator(const ListIterator& other) : m_elemList(other.m_elemList){}
			ListIterator& operator= (const ListIterator&) {return *this;}

		private:
			const std::list<const DesState*>& m_elemList;
			mutable std::list<const DesState*>::const_iterator m_crtElemIt;		
	};

} //end of namespace DESpot
