package com.indindi.StateMachine
{
	import flash.display.MovieClip;
	
	public class StateMachine extends MovieClip
	{
		private var currentState:IState;
		private var previousState:IState;
		private var nextState:IState;
		
		public function StateMachine()
		{
			currentState = null;
			previousState = null;
			nextState = null;
		}
		
		// Initialise le premier état
		public function SetInitState(s:IState):void
		{
			if(!currentState)
			{
				currentState = s;
				currentState.Enter();
			}
			else 
			{
				trace("SetInitState appelé alors qu'un état est en traitement");
			}
		}
		
		// Empilement d'un état qui sera exécuté aprés l'état actuel
		public function SetNextState(s:IState):void
		{
			if(currentState)
			{
				nextState = s;
			}
			else
			{
				trace("SM non initialisée. Utiliser SetInitState(s:IState)");				
			}
		}
		
		// Boucle de l'état courant ; 
		// time est la périodicité de l'état
		public function Update(time:int):void
		{
			if(currentState)
			{
				currentState.Update(time);
			}
			else
			{
				trace("aucun état dans la machine");
			}
		}
		
		// Passe à un autre état (sous entend d'avoir memorisé tous les etats dans un tableau tiers
		// dans la classe instanciatrice de la StateMachine)
		public function ChangeState(s:IState):void
		{
			if(currentState)
			{			
				currentState.Exit();
				previousState = currentState;
				currentState = s;
				currentState.Enter();
			}
			else
			{
				trace("SM non initialisée. Utiliser SetInitState(s:IState)");
			}
		}
		
		// Retour à l'état précédent
		public function GotoPreviousState():void
		{
			if(previousState)
			{
				ChangeState(previousState);
			}
			else
			{
				trace("Référence à l'état précédent inexistant...");
			}
		}
		
		// Etat suivant
		public function GotoNextState():void
		{
			if(nextState)
			{
				ChangeState(nextState);
			}
			else
			{
				trace("Référence à l'état suivant inexistant");
			}
		}
		
		// Clear de tous les états 
		public function ClearStates():void
		{
			if(currentState)
			{			
				currentState.Exit();
				previousState = null;
				currentState = null;
			}			
		}
		
		// Get current state class
		public function getCurrentStateName():String
		{
			return currentState.getName();
		}

		// Get current state class
		public function getPreviousStateName():String
		{
			return previousState.getName();
		}

	}
}