//////////////////////////////////////////////////////////////////////////////
//
// Asura_CommandConsole.h
//
// Copyright (c) 2001-2003 Rebellion. All rights reserved.
//
// This module should be initialised early in core engine code so that other
// engine components can add commands, etc. Each individual project should
// Update() and Render() as required, ideally once per frame.
//
// The module should only be used if ASURA_SUPPORT_COMMAND_CONSOLE is defined
// in Asura_EngineConfiguration.h.
//
// How to add console commands:
//
//    1. Create a null-terminated string holding the name of the new command.
//
//    2. Create the function that will be called by the new command.        
//       This function must have one of the following six signatures:
//        
//           bool CmdFn(                                                    bool bHelp )
//           bool CmdFn( bool bIn,                       bool bInterrogate, bool bHelp )
//           bool CmdFn( int iIn,                        bool bInterrogate, bool bHelp )
//           bool CmdFn( u_int uIn,                      bool bInterrogate, bool bHelp )
//           bool CmdFn( float fIn,                      bool bInterrogate, bool bHelp )
//           bool CmdFn( const Asura_Char* szIn,         bool bInterrogate, bool bHelp )
//           bool CmdFn( const Asura_UnicodeChar* wszIn, bool bInterrogate, bool bHelp )
//
//       The function should output a description of how to use the command if
//       bHelp is true. If bInterrogate is true then no parameter was
//       provided and the command may either display a description of current
//       state or regard this as an error and just display the help text.
//       Note that void function types only take a help parameter.
//       All functions types should return true iff the command executed
//       correctly.
//
//    3. Call Asura_CommandConsole::AddCmd( <cmd name>, FnName );
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_COMMANDCONSOLE_H___
#define ___ASURA_COMMANDCONSOLE_H___

#if defined(ASURA_DEBUG_VARIABLE_SYSTEM) && !defined(ASURA_SUPPORT_COMMAND_CONSOLE)
#error ASURA_DEBUG_VARIABLE_SYSTEM not supported without ASURA_SUPPORT_COMMAND_CONSOLE
#endif

#ifdef ASURA_SUPPORT_COMMAND_CONSOLE

// I N C L U D E S ///////////////////////////////////////////////////////////

// Stdlib independent.
#include <float.h>
#include <limits.h>

// Engine independent.
#include "Core/Asura_Handle.h"
#include "Core/Asura_UserInput.h"
#include "Core/Asura_HashTree.h"

// Engine platform-specific.
#include "Core/Asura_PlatformBasics.h"

// M A C R O S ///////////////////////////////////////////////////////////////

// You can override all the values below in your Asura_EngineConfiguration.h.

#ifndef ASURA_COMMAND_CONSOLE_CURSOR_PROMPT
    #define ASURA_COMMAND_CONSOLE_CURSOR_PROMPT L"> " // Don't put brackets round this if you override it.
#endif
#ifndef ASURA_COMMAND_CONSOLE_INPUT_BUFFER_SIZE
    #define ASURA_COMMAND_CONSOLE_INPUT_BUFFER_SIZE (128) // Must be <= ASURA_COMMAND_CONSOLE_MAX_LINE_LENGTH,
#endif                                                    // unless your Asura_CommandConsole_IO implementation
                                                          // archives output itself.

// The following two are only relevant if the Asura_CommandConsole_IO
// implementation you're using doesn't archive output itself.
#ifndef ASURA_COMMAND_CONSOLE_MAX_LINES
    #define ASURA_COMMAND_CONSOLE_MAX_LINES (64)
#endif
#ifndef ASURA_COMMAND_CONSOLE_MAX_LINE_LENGTH
    #define ASURA_COMMAND_CONSOLE_MAX_LINE_LENGTH (128)
#endif

// F O R W A R D   D E C L A R A T I O N S ///////////////////////////////////

class Asura_CommandConsole;
class Asura_CommandConsole_IO;
class Asura_ControlMap;

// C L A S S E S /////////////////////////////////////////////////////////////

class Asura_CommandConsole
{

    public:

        // T Y P E S /////////////////////////////////////////////////////////

        enum REMOVE
        {
            REMOVE_AT_SHUTDOWN,
            REMOVE_AT_RESET,
            REMOVE_DEFAULT = REMOVE_AT_RESET,
        };

        // C L A S S   M E T H O D S /////////////////////////////////////////

        static void EarlyInitialise( void );
        static void LateInitialise( void );
        static void Reset( void );
        static void Shutdown( void );

        static void Update( void );
        static void Render( void );
        
        static void SetConsoleEnabled( bool bEnable );
        static bool IsConsoleEnabled( void );
        static bool IsConsoleDown( void );
		static bool IsHandlingInput( void );	// returns true is either console is down or DVS is open
        static bool Hide( bool bForce, bool bInstant );	// (MH - 06.03.2007) was private - but DVS command wants access.
		static bool CanBeHidden();


#ifndef ASURA_COMMAND_CONSOLE_READONLY

        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(                                bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(bool,                     bool, bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(int,                      bool, bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(u_int,                    bool, bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(float,                    bool, bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(const Asura_Char*,        bool, bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddCmd( const Asura_UnicodeChar* wszCmd, bool(*pfnCmdFn)(const Asura_UnicodeChar*, bool, bool), REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool RemoveCmd( const Asura_UnicodeChar* wszCmd );
		static bool CmdExists( const Asura_UnicodeChar* wszCmd );
        
        static bool AddVar( const Asura_UnicodeChar* wszVar, bool* pbData, REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddVar( const Asura_UnicodeChar* wszVar, int* piData, int iLowerLimit = INT_MIN, int iUpperLimit = INT_MAX, REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddVar( const Asura_UnicodeChar* wszVar, u_int* puData, u_int uLowerLimit = 0, u_int uUpperLimit = INT_MAX, REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddVar( const Asura_UnicodeChar* wszVar, float* pfData, float fLowerLimit = FLT_MIN, float fUpperLimit = FLT_MAX, REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool AddVar( const Asura_UnicodeChar* wszVar, Asura_UnicodeChar* wszData, u_int uBfrSize, REMOVE eRemove = REMOVE_DEFAULT, u_int uRestrictions = 0 );
        static bool RemoveVar( const Asura_UnicodeChar* wszVar, const bool bRemoveChildren = false );
		static bool VarExists( const Asura_UnicodeChar* wszVar );

		static bool SetVarHelpText( const Asura_UnicodeChar* wszVar, const char* szDesc );
		static bool MakeVarReadOnly( const Asura_UnicodeChar* wszVar );	// use this to specify that a variable can only be looked at, not modified.
		static bool SetPointerToModifiedFlag( const Asura_UnicodeChar* wszVar, bool* pbModified );	// use this to have a bool set to true when the var changes

		// when exposing status vars for the GUIMenu system you often want them read-only and don't care about the range.
		// AddReadOnlyVar() allows easy addition of read-only vars with optional help text. 
		// Is may be desirable in the future to add an extra option for eRemove (would need a SetVarRemoveType() 
		// function which would call SetRemoveType() on the internal Var).
		template<typename T>
		static bool AddReadOnlyVar( const Asura_UnicodeChar* wszVar, T* pxData, const char* szHelpText = NULL )
		{
			bool bOK = AddVar( wszVar, pxData );
			MakeVarReadOnly( wszVar );
			if (szHelpText)
			{
				SetVarHelpText( wszVar, szHelpText );
			}
			return bOK;
		}

#endif

        static void Printf( const Asura_Char* szFormat, ... );
        static void Printf( const Asura_UnicodeChar* wszFormat, ... );
		static void PrintRaw( const Asura_UnicodeChar* wszString );

        //Displays a single line of the output buffer for the specified duration  , without bringing the console
        //fully down. If multiple calls are made , then multiple lines will be shown.
        static void TimedShowOutputLine(float fDuration);

        static void SetFontScale( float fFontScale );
        static float GetFontScale( void );

        static void GetInputBfrInfo( const Asura_UnicodeChar** pwszBfr, u_int* puCursorPos );
        static void GetOutputBfrInfo( const Asura_UnicodeChar* const ** ppwszBfr, u_int* puStart, u_int* puCount, u_int* puCurPos=NULL );

        // Returns true iff the specified string evaluated to a valid command
        // or variable. Pass NULL for the output callback function pointer
        // argument to disable output in response to the execution. The
        // default behaviour is to output to the command console as usual.
        static bool Execute( const Asura_UnicodeChar* wszCommand,
                             bool* pbReturnValue = NULL,
                             void(*pfnOutputCallback)(const Asura_UnicodeChar*) = DefaultExecuteOutputCallback );


        //get the current botttom position of the console
        static float GetBottomY();

        static bool Project_CheckRestrictions( u_int uRestrictions, bool bIsCmd );

    private:

        // F R I E N D S /////////////////////////////////////////////////////
        friend class Asura_CommandConsole_IO;


        // C L A S S   M E T H O D S /////////////////////////////////////////

        static void Platform_Initialise( void );
        static Asura_CommandConsole_IO* PlatformProject_CreateIO( void );

        // Currently just for use by Platform_Initialise() and internal commands
        // so not exposed publically.
        static void SetBorderX( float fBorderX );
        static void SetTexture( int iTextureID );
        static void SetBackgroundColour( u_int uColour );
        static void SetFont( const char* szFontName );
        static void SetFont( Asura_Handle iHandle );
#ifdef ASURA_DEBUG_VARIABLE_SYSTEM
		static void SetDVSBorder( float fBorder );
		static bool ConsoleCmd_SetDVSBorder( float fBorder, bool bInterrogate, bool bHelp );
#endif

        static bool ConsoleCmd_SetBorder( float fBorder, bool bInterrogate, bool bHelp );
        static bool ConsoleCmd_SetFont( int iFont, bool bInterrogate, bool bHelp );

#ifdef ASURA_SUPPORT_COMMAND_CONSOLE_QUIT
        // Should return true iff user was permitted to quit and the process
        // of doing so has been initiated.
        static bool Project_RequestQuit( void );

        static bool ConsoleCmd_Quit( bool bHelp );
#endif

        // (MP - 17.03.2003) Project-specific code can return false to
        // suppress the event.
        static bool Project_OnConsoleUp( void );
        static bool Project_OnConsoleDown( void );

#ifndef ASURA_COMMAND_CONSOLE_READONLY
        static void ProcessAsuraInput( void );
        static void KeyPressedCallback( ASURA_KEYID eKey );
        static bool KeyPressOverride( ASURA_KEYID eKey );
#endif
        
        static void DefaultExecuteOutputCallback( const Asura_UnicodeChar* wszOutput );

        static bool Project_IsConsoleToggled();

        static void UpdateLineTimers();
        static void ResetLineTimers();
};

class Asura_CommandConsole_CmdList
{

public:

    // T Y P E S /////////////////////////////////////////////////////////

    enum CMDTYPE
    {
        CMDTYPE_VOID,
        CMDTYPE_BOOL,
        CMDTYPE_INT,
        CMDTYPE_UINT,
        CMDTYPE_FLOAT,
        CMDTYPE_STRING,
        CMDTYPE_WSTRING,
    };

    struct CmdFn
    {
        union
        {
            bool(*pfnVoid)   (                                bool);
            bool(*pfnBool)   (bool,                     bool, bool);
            bool(*pfnInt)    (int,                      bool, bool);
            bool(*pfnUint)   (u_int,                    bool, bool);
            bool(*pfnFloat)  (float,                    bool, bool);
            bool(*pfnString) (const Asura_Char*,        bool, bool);
            bool(*pfnWString)(const Asura_UnicodeChar*, bool, bool);
        };
    };

    class Node
    {
		public:
			Node( const Asura_UnicodeChar* wszName,const CMDTYPE eType,const CmdFn xCmdFn );
			~Node();

			const Asura_UnicodeChar* GetName() const {return m_wszName;}
	
			CMDTYPE GetType() const								{ return m_eType; }
			const CmdFn& GetCommand() const							{ return m_xCmdFn; }	
			Asura_CommandConsole::REMOVE GetRemoveType() const	{ return m_eRemove; }
			u_int GetRestrictions() const						{ return m_uRestrictions; }
			const Node* GetNext() const							{ return m_pxNext; }
			Node* GetNext()										{ return m_pxNext; }
			
			void SetRemoveType( Asura_CommandConsole::REMOVE eRemoveType )	{ m_eRemove = eRemoveType; }
			void SetRestrictions( u_int uRestrict )							{ m_uRestrictions = uRestrict; }
			void SetNext( Node* pxNext )									{ m_pxNext = pxNext; }

		private:
			const Node& operator=( const Node& );

			CMDTYPE m_eType;
			CmdFn m_xCmdFn;
			Asura_CommandConsole::REMOVE m_eRemove;
			u_int m_uRestrictions;
			Node* m_pxNext;

			Asura_UnicodeChar* m_wszName;
    };

    // C L A S S   M E T H O D S /////////////////////////////////////////

    static void Initialise( void );
    static void Reset( void );
    static void Shutdown( void );

    static bool Add( const Asura_UnicodeChar* wszCmdName, CMDTYPE eType, const CmdFn& xCmdFn, Asura_CommandConsole::REMOVE eRemove, u_int uRestrictions );
    static bool Remove( const Asura_UnicodeChar* wszCmdName );
	static bool Remove( Node* const pxNodeToRemove );
    static bool Exec( const Asura_UnicodeChar* wszCmdName, const Asura_UnicodeChar* wszParameter, bool bHelpReq, bool* pbReturnValue );
    static const Node* Find( const Asura_UnicodeChar* wszCmdName, bool bAcceptPrefixMatches = false );
    static const Node* GetRootNode( void ) { return s_pxRoot; }

private:

    // S T A T E /////////////////////////////////////////////////////////

    static Node* s_pxRoot;
	static Asura_TemplateHashTree<Node*>	s_xNodeTree;

};
// End class Asura_CommandConsole_CmdList.

class Asura_CommandConsole_VarRepository
{

public:

    // T Y P E S /////////////////////////////////////////////////////////

    class Var
    {
	public:
        enum TYPE
        {
			TYPE_INVALID	= -1,
            TYPE_BOOL		= 0,
            TYPE_INT		= 1,
            TYPE_FLOAT		= 2,
            TYPE_STRING		= 3,
        };

        struct Data
        {
            union
            {
                u_int              uPtrVal;
                bool*              pbData;
                int*               piData;
                float*             pfData;
                Asura_UnicodeChar* wszData;
            };

            union
            {
                int   iLowerLimit;
                float fLowerLimit;
            };

            union
            {
                int   iUpperLimit;
                float fUpperLimit;
                u_int uBfrSize;
            };

            u_int uRestrictions;
        };

		// Constructor/destructor.
		Var( Asura_UnicodeChar* wszName, const char* szDesc, bool bReadOnly, bool* pbModified, TYPE eType, Asura_CommandConsole::REMOVE eRemove, Data xData );
		~Var();
    
        Asura_UnicodeChar* m_wszName;
		const char* m_szDesc;
		bool m_bReadOnly;
		bool* m_pbModified;
        TYPE m_eType;
        Asura_CommandConsole::REMOVE m_eRemove;
        Data m_xData;
		Var* m_pxNext;

		// Accessor functions...
		void	SetData(bool* pbData);
		void	SetData(int* piData);
		void	SetData(u_int* puData);
		void	SetData(float* pfData);
		void	SetData(Asura_UnicodeChar* wszData);
    };

    // C L A S S   M E T H O D S /////////////////////////////////////////

    static void Initialise( void );
    static void Reset( void );
    static void Shutdown( void );

    static bool Add( const Asura_UnicodeChar* wszVarName, Var::TYPE eType, const Var::Data& xData, Asura_CommandConsole::REMOVE eRemove, bool bConsoleVarEntity = false );
    static bool Remove( const Asura_UnicodeChar* wszVarName, const bool bRemoveChildren = false );
	static bool SetHelpText( const Asura_UnicodeChar* wszVarName, const char* szVarDesc );
	static bool MakeVarReadOnly( const Asura_UnicodeChar* wszVarName );	// use this to specify that a variable can only be looked at, not modified.
	static bool SetPointerToModifiedFlag( const Asura_UnicodeChar* wszVar, bool* pbModified );	// use this to have a bool set to true when the var changes
	static bool IsVarReadOnly( const Asura_UnicodeChar* wszVarName );
	static inline const Var* GetRootNode( void ) { return s_pxRoot; }

    // functions to set/return value of named variable. They don't assert and return 
	// a default value (or false) if var not found or if it's the wrong type.
	static bool GetBoolValue( const char* szVarName );
	static bool GetBoolValue( const Asura_Hash_ID uHash );
	static int GetIntValue( const char* szVarName );
	static int GetIntValue( const Asura_UnicodeChar* wszVarName );
	static int GetIntValue( const Asura_Hash_ID uHash );
	static float GetFloatValue( const char* szVarName );
	static float GetFloatValue( const Asura_Hash_ID uHash );

	static const Asura_UnicodeChar* GetUnicodeStringValue( const char* szVarName );
	static const Asura_UnicodeChar* GetUnicodeStringValue( const Asura_Hash_ID uHash );
	
	static bool SetBoolValue( const char* szVarName, bool bValue );
	static bool SetIntValue( const char* szVarName, int iValue );
	static bool SetFloatValue( const char* szVarName, float fValue );
	static bool SetUnicodeStringValue( const char* szVarName, const Asura_UnicodeChar* wszValue );

	// ReportValue() prints the value to the command console
    static bool ReportValue( const Asura_UnicodeChar* wszVarName );

	// ReportRange() prints the values of min and max to the command console
    static bool ReportRange( const Asura_UnicodeChar* wszVarName );

	// SetValue() sets the value from the command console input.
    static bool SetValue( const Asura_UnicodeChar* wszVarName, const Asura_UnicodeChar* wszValue, bool* pbReturnValue );
    static bool SetValue( const char* szVarName, const Asura_UnicodeChar* wszValue, bool* pbReturnValue );

    static Var* Find( const Asura_UnicodeChar* wszVarName );
    static Var* Find( const char* szVarName );
	static Var* Find( const Asura_Hash_ID uVarNameHash );

private:

    // C L A S S   M E T H O D S /////////////////////////////////////////
	static void UnlinkVar(Var& xVarToUnlink);

    // S T A T E /////////////////////////////////////////////////////////

	static Var* s_pxRoot;
	static Asura_TemplateHashTree<Var*>	s_xVarTree;
};
// End class Asura_CommandConsole_VarRepository

#ifdef ASURA_DEBUG_VARIABLE_SYSTEM
#define ASURA_DEBUG_VARIABLE_SYSTEM_MAX_CATEGORY_LEVELS 20

class Asura_DebugVariableSystem
{

public:

    enum KEYMAP
    {
        KEYMAP_MOVERIGHT = 0,
        KEYMAP_MOVELEFT,
        KEYMAP_MOVEUP,
        KEYMAP_MOVEDOWN,
        KEYMAP_INCREASEVALUE,
        KEYMAP_DECREASEVALUE,
        KEYMAP_INCREASEVALUEINCREMENT,
        KEYMAP_DECREASEVALUEINCREMENT,
        KEYMAP_CLOSE,

        KEYMAP_NUMMAPPINGS,
    };

	class DVS_Item
	{
	public:
		DVS_Item( Asura_UnicodeChar* wszName, Asura_CommandConsole_VarRepository::Var* pxVariable, Asura_CommandConsole_CmdList::Node* pxCommand );
		~DVS_Item();

		Asura_UnicodeChar* m_wszName;
		Asura_CommandConsole_VarRepository::Var* m_pxVariable;//null for commands
		Asura_CommandConsole_CmdList::Node* m_pxCommand;//null for variables
		DVS_Item* m_pxNext;
	};

    static void EarlyInitialise();
    static void LateInitialise();
	static void Shutdown();

    static Asura_ControlMap& GetControlMap() { return s_xControlMap; }//MKR 30/10/06: use this to customize the control mapping for a particular project

    static void Update();
	static void SetOpen(const bool bOpen)	{ s_bShowDVS = bOpen; }	// ART 24/10/06 - Much easier to tell the DVS to open than for it to query whether it should open.
    static bool IsOpen() { return s_bShowDVS; }//MKR 30/10/06: use this to check if the DebugVar system is on, in which case a project could ignore its game input

    static const Asura_UnicodeChar* GetSelectedPath() { return s_wszSelectedPath; } 
    static void GetIncrementValues(unsigned int& uIntIncrement, float& fFloatIncrement) { uIntIncrement = s_uIntIncrement; fFloatIncrement = s_fFloatIncrement; }

    static unsigned int* GetDebugVarCategoryLevelScrollY() { return s_auDebugVarCategoryLevelScrollY; }
    static float& GetDebugVarScrollX() { return s_fDebugVarScrollX; }
        
	static void OpenDisplayDVS( void);
	static void CloseDisplayDVS( void);

	static void AddVar(const Asura_UnicodeChar* wszName, Asura_CommandConsole_VarRepository::Var* pxVariable);
	static void AddCmd(const Asura_UnicodeChar* wszName, Asura_CommandConsole_CmdList::Node* pxCmd);
	static void DelVar(const Asura_UnicodeChar* wszName);
	static void DelCmd(const Asura_UnicodeChar* wszName);
	static DVS_Item* FindItem(const Asura_UnicodeChar* wszName);
	static DVS_Item* FindItem(const Asura_Hash_ID uHash);
	static DVS_Item* RootItem() { return s_pxRootDVSItem; }
	static Asura_UnicodeChar* ConvertName(const Asura_UnicodeChar* wszName);

	static void GetVariableValue(const Asura_CommandConsole_VarRepository::Var* pxVariable, Asura_UnicodeChar* wszBuffer, u_int uBufferSize);

private:    
    
    static unsigned int s_auDebugVarCategoryLevelScrollY[];
    static float s_fDebugVarScrollX;
    static Asura_UnicodeChar s_wszSelectedPath[];
    static bool s_bShowDVS;
    static float s_fFloatIncrement;
    static int s_iFloatMagnitude;
    static unsigned int s_uIntIncrement;
    static Asura_ControlMap s_xControlMap;
	static float s_fRepeatDelayFirst;
	static float s_fRepeatDelay;
	static float s_fRepeatTimer;
	static KEYMAP s_eRepeatingKey;
	static u_int s_uLastFrameKeys;

    static void Platform_InitialiseDefaultControlMapping( void );

    static bool Project_ShouldOpen( void );
    static bool Project_ShouldClose( void );

	static KEYMAP UpdateRepeatedKeys();
    static void MoveRight();
    static void MoveLeft();
    static void MoveUp();
    static void MoveDown();
    
    static void IncreaseValue();
    static void DecreaseValue();
    static void IncreaseValueIncrement();
    static void DecreaseValueIncrement();

	static DVS_Item* s_pxRootDVSItem;
	static Asura_TemplateHashTree<DVS_Item*> s_xItemTree;

};
// End class Asura_DebugVariableSystem

#endif//#ifdef ASURA_DEBUG_VARIABLE_SYSTEM


// T Y P E S /////////////////////////////////////////////////////////////////

enum INPUT_HISTORY_DELTA
{
    INPUT_HISTORY_DELTA_FORWARD = -1,
    INPUT_HISTORY_DELTA_BACK    = +1,
};

#else // not #ifdef ASURA_SUPPORT_COMMAND_CONSOLE

// minimal class for when console is not defined. This allows code to check
// e.g. is console is handling input without lots of #ifdefs everywhere.
class Asura_CommandConsole
{
public:
	static bool IsHandlingInput() { return false; }
};

#endif // end else not #ifdef ASURA_SUPPORT_COMMAND_CONSOLE

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////


#endif // #ifndef ___ASURA_COMMANDCONSOLE_H___

