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

namespace DESpot
{
	class StateTranslator
	{
		public:
			StateTranslator(int desCount = 0);
			virtual ~StateTranslator(void);

			void setDesCount(int desCount);

		//Adding entries to the translator
		public:
			virtual DesState& beginEntry(std::vector<const DesState*>* srcStateTuple);
			
			virtual void endEntry(std::vector<const DesState*>* srcStateTuple, const DesState& outState); //state in the OUT DES

		//Translating between source states and output state	
		public:
			//Translate an output state into a source tuple
			virtual const std::vector<const DesState*>* translate(DesState::ID stateId) const;
			virtual const std::vector<const DesState*>* translate(const DesState* outState) const;

			//Translate a source tuple into an output state
			virtual bool translate(std::vector<const DesState*>* srcStateTuple, DesState::ID& out_outStateID) const;
			virtual bool translate(std::vector<const DesState*>* srcStateTuple, const DesState*& out_outState) const;
	
		protected:
			typedef std::vector<const DesState*> SrcStateTuple;

			struct Entry
			{
				DesState* outState;
				SrcStateTuple*    srcStateTuple;

				Entry()
				{
					outState = null;
					srcStateTuple = null;
				}

				void reset()
				{
					outState = null;
					srcStateTuple = null;
				}
			};

			struct ConstEntry
			{
				const DesState*		outState;
				const SrcStateTuple*  srcStateTuple;

				ConstEntry()
				{
					outState = null;
					srcStateTuple = null;
				}

				ConstEntry(const DesState* outState, const SrcStateTuple* srcStateTuple)
				{
					this->outState = outState;
					this->srcStateTuple = srcStateTuple;
				}
			};

			struct SrcStateTupleLess : public std::binary_function <const SrcStateTuple*, const SrcStateTuple*, bool> 
			{
			  bool operator()(const SrcStateTuple* const & _Left, const SrcStateTuple* const & _Right) const;
			};

			//Source State Tuple -> Output State dictionary. Used to translate a source state tuple into a
			//a state in the output DES
			typedef std::map<const SrcStateTuple*, const DesState*, SrcStateTupleLess> SourceStateDictionary;
			typedef SourceStateDictionary::iterator SourceStateDictIt;
			typedef SourceStateDictionary::const_iterator SourceStateDictCIt;

			//Output State -> Source State Tuple dictionary. The index in the vector represents
			//the state IDs which are sequential since they are automatically generated by the state pool of the 
			//output DES
			typedef std::vector<ConstEntry> OutputStateDictionary;

		protected:
			//The source state dictionary used in translation. A map between the source state tuples and the ouput state
			//This structure optimizes the search of an output state that corresponse to a tuple of source states. 
			//This uses a map to implement a rough TRIE structure implemente using maps and the less<> operator			
			SourceStateDictionary m_srcStateDict;	//Source State Tuple -> Output State

			//The dictionary used to translate an output state into the corresponding source states
			OutputStateDictionary m_outStateDict;   //Output State -> Source State Tuple
			
			//The number of DES that act as source for states in the dictionary			
			int m_desCount;

			//the current entry being added to the dictionary
			DesState m_crtEntryStateTemplate;
	};

} //end of namespace DESpot
