///////////////////////////////////////////////////////////////////////////////
//
// File: Asura_ServerEntity_ConsoleVar.h
//
// Created by Martin G.Harris (20/6/2007)
// 
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
// Entity allowing designers to add a run-time console variable in tools and modify
// the value using static messages. This allows easy hooking up of game logic to
// (for example) the HUD system.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_SERVER_ENTITY_CONSOLE_VAR_H__
#define __ASURA_SERVER_ENTITY_CONSOLE_VAR_H__

// Need command console for the console variables.
#ifdef ASURA_SUPPORT_COMMAND_CONSOLE

// Includes
#include "Entity/Asura_Entity.h"
#include "Entity/Intangible/Asura_ClientEntity_ConsoleVar.h"

// Forward declarations
class Asura_Message;

///////////////////////////////////
// Asura_ServerEntity_ConsoleVar //
///////////////////////////////////
class Asura_ServerEntity_ConsoleVar : public Asura_Entity_Server
{
	typedef Asura_Entity_Server PARENT;

public:
	Asura_ServerEntity_ConsoleVar(Asura_Guid uGuid);
	virtual ~Asura_ServerEntity_ConsoleVar();

    virtual bool HandleMessage( const Asura_Message* pxMessage );

#ifdef ASURA_TOOLS
    virtual void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance);
    virtual bool CanBeIncludedInTemplate() const;
#endif // #ifdef ASURA_TOOLS

	virtual bool CanBeSavedToChunk() const { return true; }
    virtual bool IsFilledFromChunkBuffer() const { return false; }
    
	virtual void WriteToChunkStream( Asura_Chunk_Stream& xStream ) const;
    virtual void ReadFromChunkStream( Asura_Chunk_Stream& xStream );

	virtual void Update();

	enum FLAGS
	{
		FLAG_TIME_COUNT_UP = 0x00000001, // For time trigger use time elapsed (rather than remaining).
	};

	bool IsTimeCountUp() const { return (m_uFlags & FLAG_TIME_COUNT_UP) != 0; }

protected:
	const class Asura_CommandConsole_VarRepository::Var* GetVar() const;
	void UpdateFromTrackedEntity();
	
	void SetData(int iData);
	void SetData(float fData, bool bChangesEveryFrame);

	void SendChangeMessage(float fData, bool bGuarantee);

private:
// Private functions...
	Asura_ServerEntity_ConsoleVar(void);
	Asura_ServerEntity_ConsoleVar(const Asura_ServerEntity_ConsoleVar& xOther);
	Asura_ServerEntity_ConsoleVar& operator= (const Asura_ServerEntity_ConsoleVar& xOther);

private:
	enum { CURRENT_CHUNK_VERSION = 1 };

	Asura_ClientEntity_ConsoleVar::TYPE m_eType;

	// If this guid is set, then the console variable is updated from the specified entity.
	Asura_Guid m_uEntityToTrackGuid;
	
	// Misc flags
	u_int m_uFlags;

	float m_fTimeOfLastChangeMessage;

	// Friends
	friend class Tools_Entity_ConsoleVar;
	friend class Asura_ClientEntity_ConsoleVar;

	// Static members
public:
	static Asura_ServerEntity_ConsoleVar* FindEntity( Asura_Guid uGuid ) { return s_xList.FindEntity( uGuid ); }
	static const Asura_Hashed_List<Asura_ServerEntity_ConsoleVar>* GetList() { return &s_xList; }

private:
	static Asura_Hashed_List<Asura_ServerEntity_ConsoleVar> s_xList;
};

/////////////////////////////////////
// Asura_Message_Change_ConsoleVar //
/////////////////////////////////////
// Change value of console variable.
// This message is saved out to static message system, so care needs to be taken about altering it.
struct Asura_Message_Change_ConsoleVar
{
	enum FLAGS
	{
		FLAG_OPERATION_SET				= 0x00000000,
		FLAG_OPERATION_ADD				= 0x00000001,
		FLAG_OPERATION_MULTIPLY			= 0x00000002,
		FLAG_OPERATION_TOGGLE_BOOLEAN	= 0x00000003,

		// Allow up to 256 different operations.
		FLAG_OPERATION_MASK				= 0x000000ff,

		// MGH 25/6/2007: NOTE: currently it isn't possible to have flags that
		// aren't operations, due to the way that the Dialog works in the function
		// Tools_Entity_ConsoleVar::AddMessageOverlayControls_Change.
	};

	int m_iFlags; // from FLAGS

	// Send data as float, even if it is an integer or boolean.
	// (eg Boolean is 0.0f or non-zero value typically 1.0f)
	float m_fData;
};

#endif //ASURA_SUPPORT_COMMAND_CONSOLE

#endif //__ASURA_SERVER_ENTITY_CONSOLE_VAR_H__

