
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_StateMachine.h
// Author : Andy Tate
// Date   : 12-Mar-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __AVP_STATEMACHINE_H__
#define __AVP_STATEMACHINE_H__


//#define AVP_STATEMACHINE_LOGGING		// switch for state machine log file output


////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////

class AVP_State;


////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_StateMachine
// Author       : Andy Tate
// Date         : 12-Mar-2007
//
// Description  : Class to handle the states used by AvP.
////////////////////////////////////////////////////////////////////////////////

class AVP_StateMachine
{
public:
	// Public functions...
	// State registration functions...
	bool RegisterState(const u_int uState, AVP_State* pxState);

	// State change functions...
	bool ChangeState(const u_int uNewState);

	// State manipulation functions...
	virtual void Initialise() {}
	virtual void Update(void);
	virtual void Shutdown() {}

	virtual void Render(void) const;

	// Accessor functions...
	u_int GetCurrentState(void) const		{ return m_uCurrentState; }
	float GetTimeInCurrentState(void) const	{ return m_fTimeInCurrentState; }

	// Debug
	static void LogInitialise(void);

protected:
	// Protected functions...
	AVP_StateMachine(u_int uNumStates);
	virtual ~AVP_StateMachine();

	AVP_State* GetCurrentStateObject() { return m_ppxStates[m_uCurrentState]; }
	const AVP_State* GetCurrentStateObject() const { return m_ppxStates[m_uCurrentState]; }

	// Protected variables...
#ifdef AVP_STATEMACHINE_LOGGING
	virtual const char* GetStateMachineName() = 0;
#endif //#ifdef AVP_STATEMACHINE_LOGGING

private:
	// Private variables...
	union
	{
		u_int		m_uFlags;				// Single access point for the flags.

		struct
		{
			u_int	m_bHasNewState	: 1,	// Flag to say that we've got a new state to handle.
					m_uCurrentState	: 8,	// The current state being executed.
					m_uNextState	: 8,	// The state to change to.
					m_uNumStates	: 8,	// The total number of available states

									: 0;	// 7 spare-bits.
		};
	};

	float		m_fTimeInCurrentState;		// The number of seconds we've been in this state.
	AVP_State**	m_ppxStates;				// Array of pointers to the states to be executed.

	// Private functions...
	AVP_StateMachine  (const AVP_StateMachine& xOther);

	AVP_StateMachine&	operator=	(const AVP_StateMachine& xOther);

};   // End of class 'AVP_StateMachine'.


#endif   // ifndef __AVP_STATEMACHINE_H__


/// End of file. ///
