#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef _ASURA_CUTSCENE_ACTOR_H_
#define _ASURA_CUTSCENE_ACTOR_H_

#include "Animation/Asura_Animation.h"
#include "Core/Asura_Handle.h"
#include "Core/Asura_Hash.h"
#include "Core/Asura_Maths.h"
#include "Core/Asura_NameTree.h"
#include "Core/Asura_String.h"
#include "Cutscene/Asura_Cutscene_Camera_Shake.h"
#include "Network/Asura_Guid.h"
#include "Shapes/Asura_Shapes.h"

#ifdef ASURA_TOOLS
#include "Misc/list_tem.hpp"
#endif

class Asura_Animation;
class Asura_Chunk_Stream;
class Asura_Cutscene;
class Asura_Cutscene_Track;
class Asura_Cutscene_Attachment;
class Asura_Physics_Object;
class Asura_Animation_IK_Solver;
class Asura_FacialAnimation_AnimationHandler_Cutscene;

/////////////////////////////////////////////////////////////////////////////////////////////////

enum Asura_Cutscene_Actor_Type
{
	ACAT_Camera,
	ACAT_CameraTarget,
	ACAT_Hierarchy,
	ACAT_Shape,

	ACAT_FirstProjectSpecific = 1000,//project specific actor types start from here
	ACAT_FORCE_INT = 0xffffffff,
};

#define ASURA_ACTORFLAG_EXTERNALTRACKCONTROL	0x00000001 //This actor's timer is set by external means ,and so shouldn't be changed by Update()
#define ASURA_ACTORFLAG_COLLISIONS				0x00000002 //This actor should drive a physics block

class Asura_Cutscene_Actor
{
public :
	Asura_Cutscene_Actor(Asura_Cutscene* _Cutscene, int iType);
	virtual ~Asura_Cutscene_Actor();

	#ifdef ASURA_TOOLS
	//Used as part of the cutscene copying code , should only copy to a newly allocated actor
	virtual void Copy(Asura_Cutscene_Actor* pxActor);
	virtual void CopyTracks(Asura_Cutscene_Actor* pxActor);
	virtual void ListShapesUsed(List<Asura_Hash_ID>& xShapeList){};
	virtual void BuildUsedTextureTree(Asura_NameTree* pxNameTree){}
	//called during level export to add extra asura files to export list
	virtual void AddExtraFilesToList( List<Asura_String>& xNameList ) const {}

	//These two are for moving the members of a cutscene as the cutscene object is moved
	virtual void CalculateRelativePosition(const Asura_Matrix_3x3& xCutsceneOrientInverse,const Asura_Vector_3 xCutscenePosition);
	virtual void UpdateRelativeToPosition(const Asura_Matrix_3x3& xCutsceneOrient,const Asura_Vector_3 xCutscenePosition);
	#endif

	static Asura_Cutscene_Actor* AllocateActor(int iActorType,bool bServer,Asura_Cutscene* pxCutscene);
	static Asura_Cutscene_Actor* Project_AllocateActor(int iActorType,bool bServer,Asura_Cutscene* pxCutscene);

	//Tools use.. remove any links this actor may have elsewhere before it gets killed
	virtual void PreDestructionCleanup(){};

	//If set then the track timer won't be updated automatically
	void SetExternalTrackControl(bool bSet);
	bool IsExternalTrackControl() const {return m_uActorFlags & ASURA_ACTORFLAG_EXTERNALTRACKCONTROL;}


	//If set then the actor will have a dynamics object created/updated
	void SetCollisions(bool bSet);
	bool IsCollisionsEnabled() const { return (m_uActorFlags & ASURA_ACTORFLAG_COLLISIONS) != 0; }
	virtual bool IsCollisionsSupported() const { return (Type == ACAT_Hierarchy); }


	//Set/get the time along the track
	void SetTrackTime(float fTime);
	float GetTrackTime() const {return m_fTrackTimer;}

	//virtual alpha accessors for setting alpha of hierarchies, shapes, etc.
	virtual void SetAlpha(float fAlpha) {};
	virtual float GetAlpha() const { return 1.0f; }

	virtual void Initialise();
	virtual void InitialiseAttachments(){};
	virtual void Finish();
	virtual void Update(float frameTime);
	virtual void Render(){}
	virtual void RenderShadow(){}
	virtual void LoadFiles(){}
	virtual bool IsHierarchyActor() const { return false; }
    virtual bool IsCamera() const { return (Type == ACAT_Camera); }
    virtual bool IsCameraTarget() const { return (Type == ACAT_CameraTarget); }
	virtual unsigned GetDefaultTrackFlags() const {return 0;} //get default flags for new tracks , and for upgrading old tracks
	virtual int GetAnimationFlagsForLastFrame() const {return 0;}

	float GetLastPointTime() const;

	//get the position from which sounds should be played (probably just needed for tools)
	virtual void GetSoundPosition(Asura_Vector_3& xPosition) const { xPosition = Position; }

	//Updates the orientation for hierarchy/shape actors
	virtual void UpdateOrientation();

    virtual bool LoadAnimFile(const Asura_String& animName,Asura_String& animFileName);

	//Load/save functions , defined in Asura_Chunk_Cutscene.cpp
	virtual int GetChunkSize();
	virtual void SaveToChunk(char*& chunkBuffer);
	virtual void LoadFromChunk(class Asura_Chunk_Actor* chunk,Asura_Handle fileHandle);
//	virtual void ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	virtual void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;


#ifdef ASURA_TOOLS
    // (MH - 01.11.2002) code to track down unused skins and animations
    virtual bool UsesSkin(int iSkinIndex) {return false;}// note this is an index into the NameList NOT a hashID
    virtual bool UsesAnim(int iAnimIndex) {return false;}// note this is an index into the NameList NOT a hashID

	virtual void ResetGuidsAndMessages();

    virtual bool HandlesThisMessage( int iMsgID ) const;

	//Should return true if the passed actor is directly dependent on this one
	//(for sorting out ordering of actor array)
	virtual bool NeedsUpdateBefore(const Asura_Cutscene_Actor* pxActor) const {return false;}
#endif
    
    // (MH - 02.01.2003) base classes may need to know when entities associated with actors are destroyed.
    virtual void NotifyDestruction(const class Asura_Entity_Server* pxEntity) {}


	//Hide/Unhides the entity associated with this actor
	virtual void HideEntityToReplace(bool bHide);

	Asura_Cutscene* GetCutscene() {return Cutscene;}

	//common actor data
	int Type;//takes values from enum Asura_Cutscene_Actor_Type
	Asura_String ActorName;
	u_int m_uActorFlags;//from actor flag defines above
	
	//For the moment at least , only hierarchy actors will get 'non-null' guid. But i'll stick it here
	//anyway , in case other actors need it. RAR 16/08/02
	Asura_Guid m_uGuid;

	//Guid of the entity that this actor replaces (if any).
	//Used for hiding entities that correspond to actors in cutscenes
	Asura_Guid m_uGuidToReplace;

	#ifdef ASURA_TOOLS
	u_int m_uToolsSortOrder;//Determines order of actors within timeline in cutscene mode
	#endif
	
	int NumberOfTracks;
	Asura_Cutscene_Track** Tracks;

	Asura_Cutscene* Cutscene;

	//cutscene playback data
	int CurrentTrack;
	float m_fTrackTimer;//Timer for determining track position. In most cases this will be the same as Cutscene->Timer

	bool m_bTryToHideEntityAgain;//flag used when client entity being hidden doesn't exist yet , so another attempt needs to be made

	Asura_Vector_3 Position;
	Asura_Matrix_3x3 Orientation;
	bool m_bAttached;//indicated whether this actor is currently attached to another


	Asura_Physics_Object* m_pxDynamicObject;		// collisions causer for appropriately flagged actors
	virtual bool SetCollisionObject() { Asura_Assert(false, "Not overridden for this class!"); return false; }

};

/////////////////////////////////////////////////////////////////////////////////////////////////

#define ASURA_HIERARCHYACTORFLAG_NOSHADOW 0x00000001
#define ASURA_HIERARCHYACTORFLAG_INITIALLY_HIDDEN 0x00000002 //actor is only used for attachments ,and is not rendered itself
#define ASURA_HIERARCHYACTORFLAG_AMBIENTONLY 0x00000004
#define ASURA_HIERARCHYACTORFLAG_CURRENTLY_HIDDEN 0x00000008 
#define ASURA_HIERARCHYACTORFLAG_DONT_EXPORT_RESOURCES 0x000000010

class Asura_Cutscene_Actor_Hierarchy : public Asura_Cutscene_Actor
{
public :
	Asura_Cutscene_Actor_Hierarchy(Asura_Cutscene* _Cutscene, Asura_Cutscene_Actor_Type eActorType=ACAT_Hierarchy);
	~Asura_Cutscene_Actor_Hierarchy();

	#ifdef ASURA_TOOLS
	//Used as part of the cutscene copying code , should only copy to a newly allocated actor
	virtual void Copy(Asura_Cutscene_Actor* pxActor);
	virtual void ListShapesUsed(List<Asura_Hash_ID>& xShapeList);
	virtual void BuildUsedTextureTree(Asura_NameTree* pxNameTree);
	virtual void AddExtraFilesToList( List<Asura_String>& xNameList ) const;
	#endif

	void PreDestructionCleanup();


	virtual void Initialise();
	virtual void Finish();
	virtual void Update(float frameTime);
	// (MH - 18.07.2002) void Render();
	virtual void LoadFiles();
    virtual bool LoadAnimFile(const Asura_String& animName,Asura_String& animFileName);

	virtual bool IsHierarchyActor() const { return true; }

    virtual Asura_Animation* GetAnimation( void ) { return NULL; }
    virtual const Asura_Animation* GetAnimation( void ) const { return NULL; }
    const char* GetSkinName( void ) const;
	virtual void UpdateAnimTimers(){}

	//virtual void ChangeAnimation(Asura_String& animationName,float time,int flags,float tweenDuration);
    virtual void ChangeAnimation(int animationID,float time,int flags,float tweenDuration, float fAnimDelay) = 0;
	virtual void ChangeAnimation(Asura_Hash_ID xAnimHashID, float fTime, int iFlags, float fTweenDuration) = 0;
	virtual void PlayAnimationToPos(int iAnimationID,float fTime,float fStartTimer,float fEndTimer,int iFlags,float fTweenDurationm, float fAnimDelay) = 0;
	//virtual Asura_Handle PlaySecondaryAnimation(Asura_String& animationName,float time,int flags,float weight,float duration);
    virtual Asura_Handle PlaySecondaryAnimation(int animationID,float time,int flags,float weight,float fTweenDuration,bool bAutoRemove, float fAnimDelay) = 0;
	virtual Asura_Handle PlaySecondaryAnimationToPos(int iAnimationID,float fTime,float fStartTimer,float fEndTimer,int iFlags,float fWeight,float fTweenDuration,bool bAutoRemove, float fAnimDelay) = 0;
	virtual void RemoveSecondaryAnimation(Asura_Handle handle) = 0;

	virtual void ChangeTextureAnimation(int iSequence,float fSpeed,u_int uFlags) = 0;

	#if defined(ASURA_USE_FACIAL_ANIMATION_SYSTEM)
	virtual void PlayFacialAnimation(Asura_Hash_ID uAnimID, float fStartTime, bool bLooped){};
	#endif


	void ActivateAttachment(u_int uID,bool bActivate);
	Asura_Cutscene_Attachment* GetAttachmentByID(u_int uID);
	Asura_Cutscene_Attachment* GetAttachmentByIndex(int iIndex);
	int GetNumAttachments() const { return m_iNumberOfAttachments; }

	void SetIgnoreAnimMovement(bool bSet){m_bIgnoreAnimMovement = bSet;}
	bool GetIgnoreAnimMovement() const {return m_bIgnoreAnimMovement;}

	Asura_Collision_Object* m_pxCollisionObject;
	virtual bool SetCollisionObject();

	//Load/save functions , defined in Asura_Chunk_Cutscene.cpp
	int GetChunkSize();
	void SaveToChunk(char*& chunkBuffer);
	void LoadFromChunk(class Asura_Chunk_Actor* chunk,Asura_Handle fileHandle);
//	void ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;


#ifdef ASURA_TOOLS
    // (MH - 01.11.2002) code to track down unused skins and animations
    virtual bool UsesSkin(int iSkinIndex);// note this is an index into the NameList NOT a hashID
    virtual bool UsesAnim(int iAnimIndex);// note this is an index into the NameList NOT a hashID

	virtual void ResetGuidsAndMessages();

	virtual bool NeedsUpdateBefore(const Asura_Cutscene_Actor* pxActor) const;
#endif

	void SetHidden(bool bHidden);

    int	m_aiSkinID[ASURA_ANIMATION_SKIN_COUNT];

    int AnimID;
	int m_iAnimationFlags;
	float m_fAnimationDelay;//Time to hold first frame of first animation
	u_int m_uHierarchyFlags;
	Asura_Hash_ID m_uTextureHash;//hash id of replacement texture to use.

	int m_iNumberOfAttachments;
	Asura_Cutscene_Attachment** m_ppxAttachments;

	Asura_Hash_ID m_uIKTemplateID;//Option IK template if supported by the project

	#ifdef ASURA_USE_FACIAL_ANIMATION_SYSTEM
	Asura_Hash_ID m_uFaceID; //ID of face to use
	#endif

	bool m_bIgnoreAnimMovement;

};


class Asura_ClientCutscene_Actor_Hierarchy : public Asura_Cutscene_Actor_Hierarchy
{
public:

    Asura_ClientCutscene_Actor_Hierarchy(Asura_Cutscene* _Cutscene, Asura_Cutscene_Actor_Type eActorType=ACAT_Hierarchy);

	virtual void Initialise();
	virtual void InitialiseAttachments();
	virtual void Finish();
	virtual void Render();
	virtual void RenderShadow();

	virtual void  SetAlpha( float fAlpha );
	virtual float GetAlpha() const;

    virtual Asura_Animation* GetAnimation( void ) { return Animation; }
    virtual const Asura_Animation* GetAnimation( void ) const { return Animation; }
	virtual void UpdateAnimTimers();

	//virtual void ChangeAnimation(Asura_String& animationName,float time,int flags,float tweenDuration);
    virtual void ChangeAnimation(int animationID,float time,int flags,float tweenDuration, float fAnimDelay);
	virtual void ChangeAnimation(Asura_Hash_ID xAnimHashID, float fTime, int iFlags, float fTweenDuration);
	virtual void PlayAnimationToPos(int iAnimationID,float fTime,float fStartTimer,float fEndTimer,int iFlags,float fTweenDuration, float fAnimDelay);
	virtual int GetAnimationFlagsForLastFrame() const;
	//virtual Asura_Handle PlaySecondaryAnimation(Asura_String& animationName,float time,int flags,float weight,float duration);
    virtual Asura_Handle PlaySecondaryAnimation(int animationID,float time,int flags,float weight,float duration,bool bAutoRemove, float fAnimDelay);
	virtual Asura_Handle PlaySecondaryAnimationToPos(int iAnimationID,float fTime,float fStartTimer,float fEndTimer,int iFlags,float fWeight,float fDuration,bool bAutoRemove, float fAnimDelay);
	virtual void RemoveSecondaryAnimation(Asura_Handle handle);

	virtual void ChangeTextureAnimation(int iSequence,float fSpeed,u_int uFlags);

	#if defined(ASURA_USE_FACIAL_ANIMATION_SYSTEM)
	virtual void PlayFacialAnimation(Asura_Hash_ID uAnimHash, float fStartTime, bool bLooped);
	#endif

	virtual void GetSoundPosition(Asura_Vector_3& xPosition) const;


    static bool DontRender;//for editing purposes , if set the hierarchical characters aren't drawn

protected :
	//cutscene playback data
	class Asura_Animation* Animation;
	float LastAnimTimer;

	#ifdef ASURA_USE_ANIMATION_IK_SOLVER
	Asura_Animation_IK_Solver* m_pxIKSolver;
	#endif
	#ifdef ASURA_USE_FACIAL_ANIMATION_SYSTEM
	Asura_FacialAnimation_AnimationHandler_Cutscene* m_pxFaceAnimHandler;
	#endif


};


class Asura_ServerCutscene_Actor_Hierarchy : public Asura_Cutscene_Actor_Hierarchy
{
public:
    
    Asura_ServerCutscene_Actor_Hierarchy(Asura_Cutscene* _Cutscene);

	virtual void Initialise();
	virtual void InitialiseAttachments();
	virtual void Finish();
#ifdef ASURA_TOOLS
    virtual void Render();
#endif

	//virtual void ChangeAnimation(Asura_String& animationName,float time,int flags,float tweenDuration);
    virtual void ChangeAnimation(int animationID,float time,int flags,float tweenDuration, float fAnimDelay);
	virtual void ChangeAnimation(Asura_Hash_ID xAnimHashID, float fTime, int iFlags, float fTweenDuration);
	virtual void PlayAnimationToPos(int iAnimationID,float fTime,float fStartTimer,float fEndTimer,int iFlags,float fTweenDuration, float fAnimDelay);
	//virtual Asura_Handle PlaySecondaryAnimation(Asura_String& animationName,float time,int flags,float weight,float duration);
    virtual Asura_Handle PlaySecondaryAnimation(int animationID,float time,int flags,float weight,float duration,bool bAutoRemove, float fAnimDelay);
	virtual Asura_Handle PlaySecondaryAnimationToPos(int iAnimationID,float fTime,float fStartTimer,float fEndTimer,int iFlags,float fWeight,float fDuration,bool bAutoRemove, float fAnimDelay);
	virtual void RemoveSecondaryAnimation(Asura_Handle handle);
#ifdef ASURA_TOOLS
    virtual Asura_Animation* GetAnimation( void ) { return( ToolsCutsceneActor ? ToolsCutsceneActor->GetAnimation() : NULL ); }
    virtual const Asura_Animation* GetAnimation( void ) const { return( ToolsCutsceneActor ? ToolsCutsceneActor->GetAnimation() : NULL ); }
#endif

	virtual void ChangeTextureAnimation(int iSequence,float fSpeed,u_int uFlags) ;


	virtual void GetSoundPosition(Asura_Vector_3& xPosition) const;

	void AddAttachment_Shape(u_int uID,Asura_Hash_ID uMarkerHash,Asura_Hash_ID uShapeHash);
	void AddAttachment_Hierarchy(u_int uID,Asura_Hash_ID uMarkerHash,int iSkinID,int iAnimID);
	void AddAttachment_Actor(u_int uID,Asura_Hash_ID uMarkerHash,Asura_Guid uActorID);
	void AddAttachment_Entity(u_int uID,Asura_Hash_ID uMarkerHash,Asura_Guid uEntityID);
	void RemoveAttachment(u_int uID);

    void NotifyDestruction(const class Asura_Entity_Server* pxEntity);

protected:

    class Asura_ServerEntity_ServerCutsceneActorHierarchy* Entity;
#ifdef ASURA_TOOLS
    Asura_ClientCutscene_Actor_Hierarchy * ToolsCutsceneActor;
#endif
};

/////////////////////////////////////////////////////////////////////////////////////////////////

#define ASURA_CAMERAACTORFLAG_ALLOWPLAYERCONTROL	0x00000001
#define ASURA_CAMERAACTORFLAG_USENEARCLIP			0x00000002
#define ASURA_CAMERAACTORFLAG_USEFARCLIP			0x00000004

class Asura_Cutscene_Actor_Camera : public Asura_Cutscene_Actor
{
public :
	Asura_Cutscene_Actor_Camera(Asura_Cutscene* pxCutscene, int iType = ACAT_Camera);

	#ifdef ASURA_TOOLS
	//Used as part of the cutscene copying code , should only copy to a newly allocated actor
	virtual void Copy(Asura_Cutscene_Actor* pxActor);
	#endif

	virtual void Initialise();
	virtual void Update(float frameTime);

	virtual unsigned GetDefaultTrackFlags() const ; //get default flags for new tracks , and for upgrading old tracks

    const Asura_Vector_3& GetStartPosition( void ) const;
	//get the current camera target..only valid while cutscene is playing
    const Asura_Cutscene_Actor* GetTarget( void ) const { return Target; }
    Asura_Cutscene_Actor* GetTarget( void )  { return Target; }

	virtual void ChangeAnimation(int iIndex,float fStartTime,int iAnimationFlags);

	//get/set name of initial camera target object
	const char* GetInitialTargetName() const {return m_xTargetName.GetString();}
	#ifdef ASURA_TOOLS
	void SetInitialTargetName(const char* pszName){m_xTargetName = pszName;}
	#endif


	//change the target while playing cutscene
	void SetCameraTarget(const char* pszName);

	//get/set the current FOV (only valid during cutscene)
	Asura_Angle GetFOV() const {return m_fCurrentFOV;}
	void SetFOV(Asura_Angle fFOV){m_fCurrentFOV = fFOV;}

	Asura_Angle GetInitialFOV() const {return m_fInitialFOV;}
	void SetInitialFOV(Asura_Angle fFOV){m_fInitialFOV = fFOV;}

	float GetInitialNearClip() const {return m_fNearClip;}
	void SetInitialNearClip(float fNearClip) {m_fNearClip = fNearClip;}
	float GetInitialFarClip() const {return m_fFarClip;}
	void SetInitialFarClip(float fFarClip) {m_fFarClip = fFarClip;}

	u_int GetCameraFlags() const {return m_uCameraFlags;}
	void SetCameraFlags(u_int uFlags) {m_uCameraFlags = uFlags;}
	

	//Load/save functions , defined in Asura_Chunk_Cutscene.cpp
	virtual int GetChunkSize();
	virtual void SaveToChunk(char*& chunkBuffer);
	virtual void LoadFromChunk(class Asura_Chunk_Actor* chunk,Asura_Handle fileHandle);
//	virtual void ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	virtual void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;

	const Asura_Cutscene_Camera_Shake& GetInitialShake() const { return m_xInitialShake; }
	Asura_Cutscene_Camera_Shake& GetInitialShake() { return m_xInitialShake; }
	void SetInitialShake(Asura_Cutscene_Camera_Shake& xShake) { m_xInitialShake = xShake; }

	void ChangeShake(const Asura_Cutscene_Camera_Shake& xShake, float fChangeDuration);

	static void SetPlayerControlEuler(const Asura_Euler_3& xEuler) { s_xPlayerControlEuler = xEuler; }
	static void RotatePlayerControlEuler(const Asura_Euler_3& xRotationEuler) { s_xPlayerControlEuler += xRotationEuler; }

	float GetPlayerControlYawLimit() const { return m_fPlayerControlYawLimit; }
	float GetPlayerControlPitchLimit() const { return m_fPlayerControlPitchLimit; }
	void SetPlayerControlYawLimit(float fLimit) { m_fPlayerControlYawLimit = fLimit; }
	void SetPlayerControlPitchLimit(float fLimit) { m_fPlayerControlPitchLimit = fLimit; }
protected :
	void UpdateAsuraCamera() const;

	//saved data
	Asura_String m_xTargetName;//name of initial target
	Asura_Angle m_fInitialFOV;
	float m_fNearClip; //near clip plane if being set by this camera
	float m_fFarClip;//same for far clip

	//playback data
	Asura_Cutscene_Actor* Target;
	class Asura_Hierarchy_Anim* m_pxAnim;
	float m_fAnimTimer;
	float m_fLastAnimUpdateTime;
	int m_iAnimationFlags;
	Asura_Angle m_fCurrentFOV;
	Asura_Cutscene_Camera_Shake m_xInitialShake;
	Asura_Cutscene_Camera_Shake m_xChangedShake;
	Asura_Cutscene_Camera_Shake m_xLastShake;
	float m_fShakeChangeStartTime;
	float m_fShakeChangeEndTime;
	u_int m_uCameraFlags;
	float m_fPlayerControlYawLimit;
	float m_fPlayerControlPitchLimit;
	float m_fInitialPlayerControlYawLimit;
	float m_fInitialPlayerControlPitchLimit;
	

	static Asura_Euler_3 s_xPlayerControlEuler;

	friend class Asura_ServerCutscene_Actor_Camera;
	friend class Tools_CutsceneActor_Object;

};

class Asura_ClientCutscene_Actor_Camera : public Asura_Cutscene_Actor_Camera
{
public:
    
    Asura_ClientCutscene_Actor_Camera(Asura_Cutscene* _Cutscene) 
        : Asura_Cutscene_Actor_Camera(_Cutscene)
    {}

	virtual void Update(float frameTime);

    void SetTarget(Asura_Cutscene_Actor* pTarget) { Target = pTarget; }
    
    static bool Disable;//for editing purposes , if set the camera isn't moved by the cutscene.
	// (AW - 28.04.2004) - Not just for editing anymore, I'm using it in the HH prototype
};

class Asura_ServerCutscene_Actor_Camera : public Asura_Cutscene_Actor_Camera
{
public:

    Asura_ServerCutscene_Actor_Camera(Asura_Cutscene* pxCutscene);
	virtual void Initialise();
	virtual void Finish();
#ifdef ASURA_TOOLS
    virtual void Update(float frameTime);
	virtual void ChangeAnimation(int iIndex,float fStartTime,int iAnimationFlags);
#endif
    
	void NotifyDestruction(const class Asura_Entity_Server* pxEntity);

protected:
    
    class Asura_ServerEntity_ServerCutsceneActorCamera* m_pxEntity;
#ifdef ASURA_TOOLS
    Asura_ClientCutscene_Actor_Camera* m_pxToolsCutsceneActor;
#endif

};

/////////////////////////////////////////////////////////////////////////////////////////////////

class Asura_Cutscene_Actor_CameraTarget : public Asura_Cutscene_Actor
{
public :
	Asura_Cutscene_Actor_CameraTarget(Asura_Cutscene* _Cutscene, int iType = ACAT_CameraTarget)
	:Asura_Cutscene_Actor(_Cutscene, iType)
	{}
    
#ifdef ASURA_TOOLS
	virtual bool NeedsUpdateBefore(const Asura_Cutscene_Actor* pxActor) const;
#endif
};

/////////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------**
** Asura_Cutscene_Actor_Shape  **
**-----------------------------*/

#define ASURA_SHAPEACTORFLAG_NOSHADOW 0x00000001

class Asura_Cutscene_Actor_Shape : public Asura_Cutscene_Actor
{
public :
	Asura_Cutscene_Actor_Shape(Asura_Cutscene* pxCutscene);

	#ifdef ASURA_TOOLS
	//Used as part of the cutscene copying code , should only copy to a newly allocated actor
	virtual void Copy(Asura_Cutscene_Actor* pxActor);
	virtual void ListShapesUsed(List<Asura_Hash_ID>& xShapeList);
	#endif


//	virtual void Initialise();
//	virtual void Finish();
	virtual void Update(float fFrameTime);

	//Load/save functions , defined in Asura_Chunk_Cutscene.cpp
	int GetChunkSize();
	void SaveToChunk(char*& chunkBuffer);
	void LoadFromChunk(class Asura_Chunk_Actor* chunk,Asura_Handle fileHandle);
//	void ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;

	Asura_Hash_ID m_uShapeID;
	u_int m_uShapeFlags;
};
/////////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Asura_ClientCutscene_Actor_Shape **
**----------------------------------*/

class Asura_ClientCutscene_Actor_Shape : public Asura_Cutscene_Actor_Shape
{
public:
	Asura_ClientCutscene_Actor_Shape(Asura_Cutscene* pxCutscene);

	virtual void Initialise();
	virtual void Render();
	virtual void RenderShadow();

	virtual void  SetAlpha( float fAlpha )	{ m_xShapeInstance.SetAlpha(fAlpha); }
	virtual float GetAlpha() const			{ return m_xShapeInstance.GetAlpha(); }


protected :
	//cutscene playback data
	Asura_Shape_Instance m_xShapeInstance;

};

/////////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Asura_ServerCutscene_Actor_Shape **
**----------------------------------*/
class Asura_ServerCutscene_Actor_Shape : public Asura_Cutscene_Actor_Shape
{
public:
	Asura_ServerCutscene_Actor_Shape(Asura_Cutscene* pxCutscene);

	virtual void Initialise();
	virtual void Finish();
#ifdef ASURA_TOOLS
    virtual void Render();
#endif

    void NotifyDestruction(const class Asura_Entity_Server* pxEntity);

protected:

    class Asura_ServerEntity_ServerCutsceneActorShape* m_pxEntity;
#ifdef ASURA_TOOLS
    Asura_ClientCutscene_Actor_Shape * m_pxToolsCutsceneActor;
#endif

};





#endif //_ASURA_CUTSCENE_ACTOR_H_
