/**
*
* \file Asura_Entity.h
*
* Created by Kevin Lea - 27/11/2001 14:57:06
*
* Copyright (C) 2001 Rebellion, All Rights Reserved.
*
* \brief
*
**/

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_ENTITY_H__
#define __ASURA_ENTITY_H__

// KOR - this macros include is not actually used in this header,
// but is used by a lot of files that include it. It should really
// be removed, but requires changing many Asura and project files.
#include "ChunkSystem/Asura_Chunk_Macros.h"//For the load/save macros that used to be in this file. Include should possibly go in individual files as required. RAR.
#include "Core/Asura_Combined_List.h"
#include "Core/Asura_Hash.h"
#include "Entity/Asura_Entity_System.h"
#include "Network/Asura_Guid.h"
#if defined(ASURA_USE_STREAMING)
#include "Streaming/Asura_Streaming_Zone.h"
#endif


// Forward declarations
class Asura_Blueprint;
class Asura_Chunk_Stream;
class Asura_Entity_PeriodicClientUpdateList;
class Asura_Entity_Server;
struct Asura_EventAndMessage;
template<typename T> class Asura_Hashed_List;
class Asura_Message;
class Asura_Vector_3;

//////////////////////////////////////////////////////////////////////////////
//
// Asura_Entity
//
// Kevin Lea - 27/11/2001 16:01:57 - a basic Asura_Entity: all other entities
// are derived from this. Note that the constructor automatically adds the entity
// to the overall entity list, and the destructor removes it. When deriving further
// entity classes, you can add to other lists too. So, a 'Marine_Entity' might end up
// on a 'Marine' list, a 'Human' list, a 'Renderable' list and so on, depending on 
// its inheritance. This makes scanning through different types of entities very easy.
//
//////////////////////////////////////////////////////////////////////////////
class Asura_ServerEntity_Template;
class Asura_Entity
{
	friend class Asura_Entity_System;
	friend class Tools_BaseEntity_Object;	// for access to SetActive() etc.
	friend class Tools_Entity_Object;		// for access to m_bEntityActive for testing.

protected:
	Asura_Entity();
    virtual ~Asura_Entity();

public:
	// (MH - 11.09.2003) made this virtual so Asura_Entity_Client can add to its recently-destroyed list.
	virtual void SetAsDestroyed(void);

	bool HasBeenShutdown() const { return m_bHasBeenShutdown; }

	// Called immediately before the destructor. Allows any clean-up code to be encapsulated and safely call virtual functions.
	virtual void PreDestructionShutdown();

	bool IsDestroyed() const 
	{
		return (m_bReadyToBeDestroyed!=0) || Asura_Entity_System::IsDestroyingAllEntities();
	}
	Asura_Guid     GetGuid()           const { return Guid; }
	unsigned short GetClassification() const { return Classification; }

	// HandleMessage: returns true if the message was dealt with and no further handling is needed.
	// If the class can't handle the message it will generally offer it to a parent class.
	// (Although multiple inheritance complicates things a bit.)
	// Returns false, if it couldn't handle the message (and nor could any parent
	// that it offered the message to).
	virtual bool HandleMessage(const Asura_Message* pxMessage);

	// Per frame update: generally it will update itself and then call update for its parent class.
	// (Although things are more complex where multiple inheritance is being used).
	// Each part of a class that defines Update() should have it called exactly once per frame.
	virtual void Update();

#ifdef ASURA_TOOLS
	//Calls callback function for each sound used by the entity. Used by tools to build
	//a list of sounds that are needed by existing entities
	virtual void TraverseUsedSounds(void (*pfnCallback)(int iSoundID,void* pUserData),void* pUserData) const {};

	//and similarly for textures
	virtual void TraverseUsedTextures(void (*pfnCallback)(int iTextureID,void* pUserData),void* pUserData) const{};

	//and for shapes
	virtual void TraverseUsedShapes(void (*pfnCallback)(Asura_Hash_ID uShapeHash,void* pUserData),void* pUserData) const {};

	//Used after an entity has been created from the template's chunk buffers to adjust message blocks,
	//and positions as needed. RAR 16/04/2004
	virtual void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance){}

	//Indicates whether it is safe for this entity type to be included in a template file
	//Each class should make sure that their classification is as expected before returning true ,
	//to prevent derived classes from being included in templates by mistake. RAR 23/04/2004
	virtual bool CanBeIncludedInTemplate() const {return false;}

	//Returns true if this entity will be needed in exported levels. This is in addition to other
	//checks about whether an entity should be saved at all
	virtual bool ShouldIncludeInLevelExport() const;

#endif //ASURA_TOOLS

#ifdef ASURA_SUPPORT_ENTITYWATCH
	//Called by entity watch system to get the entities to display appropriate
	//debugging text.
	virtual void DisplayEntityWatchText(){};
#endif

	//Normally the loaders assert and abort if a duplicate of the entity already exists
	//Return true for derived classes if they handle loading over existing entities.
	//RAR 24/04/2006
	virtual bool AllowOverwriteOnLoad() const {return false;}

#if defined(ASURA_USE_STREAMING)
	Asura_Hash_ID GetZoneHashID() const { return m_uZoneHashID; }
	Asura_Hash_ID GetContainingZoneHashID() const { return(m_xZoneCache.GetZoneHash()); }
	const Asura_Streaming_ZoneCache& GetZoneCache(void) const { return(m_xZoneCache); }
	// Update the containing zone hash ID and return the zone if found. Pass in the current position of the entity.
	Asura_Hash_ID UpdateContainingZone(const Asura_Vector_3& xPosition);
	bool GetCanChangeZone() const { return m_bAllowZoneChange; }
	void SetCanChangeZone(bool bCanChange) { m_bAllowZoneChange = bCanChange; }
#endif

    Asura_Hash_ID GetBlueprintHashID()     const { return m_uBlueprintHashID; }
    Asura_Hash_ID GetBlueprintTypeHashID() const { return m_uBlueprintTypeHashID; }
    void SetBlueprintHashID( const Asura_Hash_ID uHashID )     { m_uBlueprintHashID     = uHashID; }
    void SetBlueprintTypeHashID( const Asura_Hash_ID uHashID ) { m_uBlueprintTypeHashID = uHashID; }
    // Initialises this entity with its blueprint data.
    void InitFromBlueprint();
    Asura_Blueprint* GetBlueprint() const;

	// SetEntityActive() - should not be virtual but will call virtual functions. Generally called
	// on receving an activate/deactivate message. If active status is initialised it calls both 
	// OnEntity(De)Activate() and OnEntity(De)ActivateMessage() otherwise it calls just the former.
	void SetEntityActive( bool bActive );
	void SetTemplateInstanceActive( bool bActive );
	// IsEntityActive() - just returns current state (including template instance status)
	bool IsEntityActive() const { return m_bEntityActive && m_bTemplateInstanceActive; }
	// GetEntityActiveIgnoringTemplate() and GetTemplateInstanceActive() are mainly for chunk writing code.
	bool GetEntityActiveIgnoringTemplate() const { return m_bEntityActive; }
	bool GetTemplateInstanceActive() const { return m_bTemplateInstanceActive; }
#ifdef ASURA_TOOLS
	// UpdateTemplateInstanceActive() used when in tools to sort out children when master active status changes.
	void UpdateTemplateInstanceActive( bool bActive ) { m_bTemplateInstanceActive = bActive; }
#endif

protected:		
	void Send( Asura_Message* pxMessage, Asura_Guid uTo = ASURA_GUID_UNREGISTERED ) const;

    virtual void InitialiseFromBlueprint( const Asura_Blueprint& xBlueprint ) {}

	// SetEntityActiveFromLoad() - should not be virtual or call virtual functions. Generally called
	// by chunk loading code (which might include constructors) so the OnActivate() etc are not called
	// until PostLoadInitialise() when SetEntityActive(IsEntityActive()) will do the side-effects. 
	void SetEntityActiveFromLoad( bool bActive ) { m_bEntityActive = bActive; m_bActiveStatusInitialised = false; }
	void SetTemplateInstanceActiveFromLoad( bool bActive ) { m_bTemplateInstanceActive = bActive; }
	// InitialiseClientEntityActivity() - client entities are assumed to be active on creation.
	void InitialiseClientEntityActivity() { m_bEntityActive = true; m_bActiveStatusInitialised = true; }
	// OnEntityActivate()/OnEntityDeactivate() - called when active status changes or is initialised. 
	// Derived classes should always call parent versions if they override them. 
	virtual	void OnEntityActivate(void) {}
	virtual	void OnEntityDeactivate(void) {}
	// OnEntityActivateMessage()/OnEntityDeactivateMessage() - called when active status changes as a result 
	// of a message being received as opposed to on creation/loading. Used for things that have side-effects
	// such as sending messages to other entities. 
	// Derived classes should always call parent versions if they override them. 
	virtual void OnEntityActivateMessage(void) {}
	virtual void OnEntityDeactivateMessage(void) {}

	// Dummy Read/Write functions so Asura_Entity_Client/Server can safely call parent
	virtual	void ReadFromChunkStream(Asura_Chunk_Stream& xStream) {}
	virtual	void WriteToChunkStream(Asura_Chunk_Stream& xStream) const {}
	virtual void PostLoadInitialise() {}
	virtual void PostCreateInitialise() {}
	static void	SkipDataInChunkStream(Asura_Chunk_Stream& xStream) {}

	// Return the relevant periodic client update list.
	Asura_Entity_PeriodicClientUpdateList* GetPeriodicClientUpdateList() const;
	// Return the relevant constant client update list.
	Asura_Hashed_List<Asura_Entity_Server>* GetConstantClientUpdateList() const;

    /// Kevin Lea - 27/11/2001 16:08:30 - Globally unique identifier.
	/// No two entities have the same id number.
	Asura_Guid Guid;

	/// Richard Rice - 30/04/2002 - Classification now used as a way of working out exactly what
	/// class this entity is. Enumeration is in Asura_Entity_Classification.h
	/// Undecided as yet whether server/client versions of the same entity type should get the same value,
	/// but for the moment the classes I need to deal with only have server versions
	unsigned short Classification;

#if defined(ASURA_USE_STREAMING)
	// ART - 18/04/06 - The streaming-zone in which this entity was created.
	// This zone never changes, so the entity should be able to be destroyed
	// when that particular zone is destroyed.
	Asura_Hash_ID	m_uZoneHashID;
	// AJG - 14/09/06 - Exception to the above when this flag is set.
	// An example for the use of this is if the player's entity is created in the zone instead of a mission,
	// we can change its current zone as we move around so it isn't deleted accidentally.
	bool m_bAllowZoneChange;

	// ART 14/06/06 - Replaced containing zone hash-ID with a position cache which
	// keeps better track of exactly where within a zone our entity is...
	Asura_Streaming_ZoneCache	m_xZoneCache;

	// AJG - 14/09/06 - If above flag is true, function to handle the changing.
	virtual Asura_Hash_ID CheckForZoneChange( void );

	// Function to migrate to another zone, including updating all lists
	void MigrateZone(Asura_Hash_ID uNewZoneHash);
private:
	// virtual function called from above to call the migration specific to the entity type.
	virtual void MigrateZone(Asura_Streaming_ZoneEntities* pxOldEntities, Asura_Streaming_ZoneEntities* pxNewEntities) = 0;
#endif

private:
	// private functions
	void ActivityChanged();

	void SetHasBeenShutdown() { m_bHasBeenShutdown = true; }

	// private data

	// (MP - 11.06.2003) Made m_bReadyToBeDestroyed private to force subclasses to go via SetAsDestroyed().
	unsigned int m_bReadyToBeDestroyed : 1;
	unsigned int m_bEntityActive : 1;
	unsigned int m_bTemplateInstanceActive : 1;
	unsigned int m_bActiveStatusInitialised : 1;
	unsigned int m_bHasBeenShutdown : 1;

    Asura_Hash_ID m_uBlueprintHashID;
    Asura_Hash_ID m_uBlueprintTypeHashID;


#ifdef ASURA_TOOLS
public:
	//for storing position/name data for tools editing
	struct Tools_Entity_Data* ToolsData;
#endif
};

//////////////////////////////////////////////////////////////////////////////
//
// Asura_Entity_Server
//
//////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_ENTITY_SERVER_PARENT
// Project needs to supply this header file with definition of parent class included...
#include "Entity/Asura_Project_Entity.h"
// Need to increment the version number to tell it whether to read parent data, but still need to be able to 
// increment base version for Asura_Entity_Server chunk changes, so pick a suitably high bit in the int.
#define SERVER_PARENT_DATA_INCREMENT 0x1000000
#else
#define ASURA_ENTITY_SERVER_PARENT Asura_Entity
#define SERVER_PARENT_DATA_INCREMENT 0x0
#endif

class Asura_Entity_Server : public ASURA_ENTITY_SERVER_PARENT
{
	typedef ASURA_ENTITY_SERVER_PARENT PARENT;

	friend class Asura_Entity_System;
	friend class Asura_Entity_PeriodicClientUpdateList;
	friend class Asura_Streaming_ZoneEntities;
	friend class Tools_BaseEntity_Object;

public:
	virtual ~Asura_Entity_Server();

	// assume that most server entities have corresponding client entities. Those
	// that don't should override HasClientEntities(). Failure to do so should only
	// lead to asserts and possibly network bandwidth wastage.
	virtual bool HasClientEntities() const { return true; }

	// (MH - 31.03.2004) call SetAlwaysUpdateClient(false) when an object decides 
	// it doesn't have to send updates every 0.1 seconds, but will still send 
	// updates occasionally, and will send heartbeats in case an update was 
	// missed. Calling with true gives the default behaviour of updating every 0.1s
	void SetAlwaysUpdateClient(bool bEnable);

	// (MH - 31.03.2004) call SetNeverUpdateClient() if MakeClientUpdateMessage
	// it not overridden, so there's no point calling it. If a base class calls 
	// this and you want to override it call SetAlwaysUpdateClient() with the
	// appropriate parameter.
	void SetNeverUpdateClient();

    // Causes the server entity to send an update message to its client
    // entity every frame. This setting is mutually exclusive with the
    // always/burst/never update stuff. It's used for server-side cutscenes
	// like those used in Gunfighter2 and RogueTrooper and should not be used
	// for games which support networking.
    void SetUpdateClientEveryFrame( bool bEnable );

	bool IsInClientUpdateLists() const;
	int  GetClientUpdateMode() const;
	
	// This is true for entities that were in the client update lists at the moment they were deactivated
	bool GetShouldAddToClientUpdateListWhenActivated() const { return m_bShouldAddToClientUpdateListWhenActivated; }

    // (MH - 30.03.2004) call RequestClientUpdate when something changes that 
	// requires a client update message to be sent when it wouldn't normally
	// (e.g. for a static object, when it changes its shape).
	void RequestClientUpdate();

	// KOR - 23/03/2006 - Adds or removes from the updateable list as appropriate.
	// Call with true if the Update() call would do nothing, for example for
	// static objects, or for NPCs that are not active.
	// Do not call every frame - potentially very slow as it checks through the list.
	// If it turns out to be useful to call every frame (can't think why at the moment),
	// we could add a flag which tells us if it's currently in the list.
	void SetNeverUpdates(bool bNeverUpdates);
	bool IsUpdateable();
	
	void SetThisAndClientsAsDestroyed();

    // (MH - 16.08.2002) added HandleMessage to catch destroy msg
	virtual bool HandleMessage(const Asura_Message* pxMessage);

    virtual void PostLoadInitialise();

	// Functions for saving the entities to chunks.
	// NOTE: The first 4 functions will eventually become redundant, being
	// ~~~~~ replaced by the read/write from/to stream functions.
	virtual	bool IsFilledFromChunkBuffer(void) const { return true; }

	//Indicates whether this entity can be saved to an entity chunk
	virtual bool CanBeSavedToChunk() const { return false; }
												
	virtual	int	 GetChunkBufferSize(void);
	virtual	void FillInChunkBuffer(char*& pcChunkBuffer);
	virtual	void InitialiseFromChunkBuffer(const char*& pcChunkBuffer);

    // Reads this entity from the specified chunk-stream.
	virtual	void ReadFromChunkStream(Asura_Chunk_Stream& xStream);
    // Writes this entity to the specified chunk-stream.
	virtual	void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;

	//allows client entities that use the same chunkbuffer as the server to skip unneeded data
	// NY - to stop the function params snowballing, any data to be returned goes via this class,
	// which SkipDataInChunk(Stream/Buffer) assumes to be uninitiallised.
	class SkippedServerData
	{
	public:

		SkippedServerData()
		{
			m_uBlueprintHashID		= ASURA_HASH_ID_UNSET;
			m_uBlueprintTypeHashID	= ASURA_HASH_ID_UNSET;
			m_bActive				= false;
			m_bTemplateActive		= false;
		}
		Asura_Hash_ID m_uBlueprintHashID;
		Asura_Hash_ID m_uBlueprintTypeHashID;
		bool m_bActive;
		bool m_bTemplateActive;
	};
	// AJG - 09/10/07 - Allow client entities to get the blueprint data if they want it.
	static void	SkipDataInChunkBuffer(const char*& pcChunkBuffer, SkippedServerData* puSkippedServerData = NULL);
	static void	SkipDataInChunkStream(Asura_Chunk_Stream& xStream, SkippedServerData* puSkippedServerData = NULL);

	//Return true to prevent saved chunk buffer from being parsed by client entity loading code.
	//Only really needed for the annoying cases where the server and client have different 
	//chunkbuffer formats. RAR 24/04/2006
	virtual bool IsChunkBufferServerOnly() const {return false;}

	virtual bool GetCanBeQuicksaved() const { return true; }
	// In most cases, the following function probably matches GetCanBeQuicksaved. However, there are cases where an entity creates non-quicksavable entities as
	// part of their chunk, deleting them when they're deleted, and so they cannot be destroyed on checkpoint loading.
	// There's also an argument that nothing should be destroyed on checkpoint load (only destroying some has the potential for fragmenting memory), with the entities that
	// exist parsing their saved chunks. However, that's not traditionally how things have been done, so that can be considered later.
	virtual bool IsDestroyedOnQuickload() const { return true; }

#ifdef ASURA_TOOLS
	virtual void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance);
#endif

    int GetNumEvents( void ) const { return m_iNumberOfEvents; }
    const Asura_EventAndMessage* GetEvents( void ) const { return m_pxEvents; }

	#ifdef ASURA_TOOLS
	virtual bool SupportsCustomEvents() const { return false; }
	virtual int GetNumCustomEvents() const { return 0; }
	virtual unsigned short* GetCustomEvent(int iIndex) { return NULL; }
	virtual void GetCustomEventName(int iEventIndex, Asura_String& xEventName) {}
	virtual int GetCustomEventMessageSet(int iEventIndex) const;//defaults to ASURA_STATICMESSAGE_ENTITYSET which is correct except for some cutscene stuff
	virtual int GetDefaultMessageEvent() { return -1; }
	#endif

	// AJG - 21/01/08 - Functions to send create messages automatically, designed for games like AVP where there's an initialisation phase between loading a level and playing.
	virtual bool GetHasCreateMessage() const { return false; }
	virtual void MakeCreateMessage(Asura_Guid uRequestingClient, bool bSendGuaranteed = false);

    static Asura_Entity_Server* FindEntity(Asura_Guid uGuid)
    {
        return s_xList.FindEntity(uGuid);
    }
    static Asura_Entity_Server* FindObject(Asura_Guid uGuid, bool bIgnoreDestroyedEntities = true)
    {
        return s_xList.FindObject(uGuid, bIgnoreDestroyedEntities);
    }
    static Asura_Classified_List<Asura_Entity_Server>* GetList()
    {
        return s_xList.GetList();
    }
    static void DestroyAllEntities()
    {
        s_xList.DestroyAllObjects();
    }
	static u_int GetNumUpdating(void)
	{
		return(s_xUpdateableList.GetNumEntries());
	}

protected:
	// Protected constructor since we cannot create entities outside of the inheritance hierarchy...
	explicit Asura_Entity_Server(Asura_Guid uGuid);

    virtual void MakeClientUpdateMessage( void );

	//Sends any messages for the event passed (taken from ASURA_ENTITY_EVENT enum)
	void SendMessagesForEvent(int iEventID);
	
	// Assign an existing message block to a given event ID
	bool SetMessageBlockForEvent( int iEventID, u_short usMsgBlockID );

	//For dealing with old physical objets that store this data elsewhere
	void ReadEventsFromChunkBuffer(const char*& pcChunkBuffer);

#ifdef ASURA_TOOLS
	//for converting other means of storing messages to this system
	virtual void AddMessageForEvent(int iEventID,Asura_Guid uGuid,int iMessageID);

	// for checking whether this entity makes use of the event
	virtual bool HasMessageBlockForEvent( int iEventID ) const;

	// for copying a message block from another entity
	virtual void CopyMessagesForEvent( const Asura_Entity_Server* pxEntity, int iEventID );
#endif

	// overrides of OnEntityActivate()/OnEntityDeactivate() - called when active status changes or is initialised. 
	// Derived classes should always call parent versions if they override them. 
	virtual	void OnEntityActivate(void);
	virtual	void OnEntityDeactivate(void);
	// overrides of OnEntityActivateMessage()/OnEntityDeactivateMessage() - called when active status changes as a result 
	// of a message being received as opposed to on creation/loading. Used for things that have side-effects
	// such as sending messages to other entities.
	// Derived classes should always call parent versions if they override them. 
	virtual void OnEntityActivateMessage(void);
	virtual void OnEntityDeactivateMessage(void);

#ifdef ASURA_ASSERT
	// code to help check messages are being sent on activation/deactivation
	bool ExpectingBaseEventMessage(u_short usMsgID);
	bool SentBaseEventMessage() const { return m_bSentBaseEventMessage; }
#endif


private:
#ifdef ASURA_USE_STREAMING
	void MigrateZone(Asura_Streaming_ZoneEntities* pxOldEntities, Asura_Streaming_ZoneEntities* pxNewEntities);
#endif

	int m_iNumberOfEvents;
    // Events that messages should be sent for.
	Asura_EventAndMessage* m_pxEvents;

	unsigned int m_bShouldAddToUpdateListWhenActivated : 1;
	unsigned int m_bShouldAddToClientUpdateListWhenActivated : 1;
	unsigned int m_bAlwaysUpdateClient : 1;
#ifdef ASURA_ASSERT
	unsigned int m_bSentBaseEventMessage : 1;
#endif

	static Asura_Combined_List<Asura_Entity_Server> s_xList;
	// KOR - 23/03/2006 - only entities in this list have Update() called on them.
	// Mostly just iterated through, so use the classified rather than combined list.
	static Asura_Classified_List<Asura_Entity_Server> s_xUpdateableList;

	// ART - 18/04/06 - List manipulation functions are now used to hide the
	// extra work the streaming system does with entities...
	void AddToList(void);
	void RemoveFromList(void);

	void AddToUpdateableList(void);
	void RemoveFromUpdateableList(const bool bShouldAlwaysBePresent);

    // chunk history:
	// version 2: added active
	// version 3: added template instance active
	// version incremented by 1 if server-side project class added to hierarchy
	enum { CURRENT_CHUNK_VERSION = (3+SERVER_PARENT_DATA_INCREMENT) };
};

//////////////////////////////////////////////////////////////////////////////
//
// Asura_Entity_Client
//
//////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_ENTITY_CLIENT_PARENT
// RWM - Included again as above; client or server could be defined independently; project needs to supply this header with definition of client parent class
#include "Entity/Asura_Project_Entity.h"
#else
#define ASURA_ENTITY_CLIENT_PARENT Asura_Entity
#endif
class Asura_Entity_Client : public virtual ASURA_ENTITY_CLIENT_PARENT
{
	typedef ASURA_ENTITY_CLIENT_PARENT PARENT;

	friend class Asura_Entity_System;

public:
	virtual ~Asura_Entity_Client();
    

    // Do the base class version and add this entity to the recently-destroyed list.
	virtual void SetAsDestroyed(void);

	bool IsUpdateable(void) const { return s_xUpdateableList.FindEntity(GetGuid()) != NULL; }

	virtual void PostCreateInitialise() { PARENT::PostCreateInitialise(); }

	// GetPositionForDialogue() - virtual function for where the dialogue system should 
	// play its sounds from. Human classes might want to override this and move the y up.
	virtual bool GetPositionForDialogue(Asura_Vector_3& xPosition) const { return false; }
	// virtual function to dictate whether we're currently able to play dialogue at all.
	virtual bool GetCanPlayDialogue() const { return true; }

public:
	/* static members */

	// Was the entity recently deleted? This is to work around client updates arriving after the destroy message in internet games.
	static bool HasRecentlyBeenDestroyed(Asura_Guid uGuid);

	static Asura_Entity_Client* FindEntity( Asura_Guid uGuid ) { return s_xList.FindEntity(uGuid); }
    static Asura_Entity_Client* FindObject( Asura_Guid uGuid, bool bIgnoreDestroyedEntities = true ) { return s_xList.FindObject( uGuid, bIgnoreDestroyedEntities ); }
	static Asura_Classified_List<Asura_Entity_Client>* GetList() { return s_xList.GetList(); }
	static void DestroyAllEntities() { s_xList.DestroyAllObjects(); }

	// We'll make the updateable list inaccessible to the outside for now, as it should only be needed for iterating 
	// through in the entity system update, except for the adding and removing functions, and the update call itself.
	static void AddToUpdateableClientList(Asura_Entity_Client* pxEntity)
	{
		pxEntity->AddToUpdateableList();
	}
	static void RemoveFromUpdateableClientList(Asura_Entity_Client* pxEntity, bool bShouldAlwaysBePresent = true)
	{
		pxEntity->RemoveFromUpdateableList(bShouldAlwaysBePresent);
	}
	static bool IsInUpdateableClientList( const Asura_Entity_Client* pxEntity )
	{
		return (s_xUpdateableList.FindEntity( pxEntity->GetGuid() ) != NULL);
	}
	static u_int GetNumUpdating(void)
	{
		return(s_xUpdateableList.GetNumEntries());
	}

protected:
	// Protected constructors since we cannot create entities outside of the inheritance hierarchy...
	Asura_Entity_Client();
	explicit Asura_Entity_Client(Asura_Guid uGuid);

	// overrides of OnEntityActivate()/OnEntityDeactivate() - called when active status changes or is initialised. 
	// Derived classes should always call parent versions if they override them. 
	virtual	void OnEntityActivate(void);
	virtual	void OnEntityDeactivate(void);

private:

	union
	{
		struct
		{
			u_int	m_bShouldAddToUpdateListWhenActivated	: 1,
															: 0;
		};
		u_int m_uClientFlags;
	};

#ifdef ASURA_USE_STREAMING
	virtual void MigrateZone(Asura_Streaming_ZoneEntities* pxOldEntities, Asura_Streaming_ZoneEntities* pxNewEntities);
#endif

	/* static data */
	static Asura_Combined_List<Asura_Entity_Client> s_xList;
	// This is likely only to be iterated through, so use the classified.
	static Asura_Classified_List<Asura_Entity_Client> s_xUpdateableList;

	// ART - 18/04/06 - List manipulation functions are now used to hide the
	// extra work the streaming system does with entities...
	void AddToList(void);
	void RemoveFromList(void);

	void AddToUpdateableList(void);
	void RemoveFromUpdateableList(const bool bShouldAlwaysBePresent);
};


// (MH - 04.08.2003) Asura_Entity_Renderable used to be defined here in this header
// so to minimise disruption I'm including the new header here.
#include "Entity/Asura_Entity_Renderable.h"
// KOR - 22/03/2006 - similarly for the entity system.
#include "Entity/Asura_Entity_System.h"
// TODO - at some point someone should run through and sort these two + the chunk macro includes out.
// It would probably have a big effect on dependencies and build times.

#endif//__ASURA_ENTITY_H__
