//////////////////////////////////////////////////////////////////////////////
//
// Asura_ClientEntity_ServerCutsceneActor.h
//
// Created by Mike Healey.
//
// Copyright (c) 2002 Rebellion. All rights reserved.
//
// Entities to receive updates from ServerCutscene and render the actor 
// accordingly. 
//
//////////////////////////////////////////////////////////////////////////////

// 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_CLIENTENTITY_SERVERCUTSCENEACTOR_H___
#define ___ASURA_CLIENTENTITY_SERVERCUTSCENEACTOR_H___ 1

#ifdef ASURA_SUPPORT_SERVERCUTSCENES	// the Gunfighter-style cutscenes with entities

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

// Engine independent.
#include "Core/Asura_Hash.h"
#include "Entity/Asura_Entity.h"
#include "Shapes/Asura_Shapes.h"

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

class  Asura_Cutscene;
struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment;
struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentActor;
struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentEntity;
struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentHierarchy;
struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentShape;
class  Asura_ServerCutscene_ClientAttachment;

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

class Asura_ClientEntity_ServerCutsceneActor : public Asura_Entity_Renderable
{

public:
	Asura_ClientEntity_ServerCutsceneActor();
    ~Asura_ClientEntity_ServerCutsceneActor() {}
	
    
    virtual bool HandleMessage(const Asura_Message* pxMessage);

protected :
	bool m_bAttached;
	virtual void Render(void){};
	virtual void Render(const Asura_Vector_3& xPos,const Asura_Matrix_3x3& xMat){};

	friend class Asura_ServerCutscene_ClientAttachment_Actor;
};

class Asura_ClientEntity_ServerCutsceneActorHierarchy : public Asura_ClientEntity_ServerCutsceneActor
{

public:

	Asura_ClientEntity_ServerCutsceneActorHierarchy(Asura_Hash_ID uCutsceneHash, short _SkinID, short _InitialAnimationID, int iAnimationFlags, float fAnimationDelay, u_int _uFlags, u_int uTextureHash,bool bCreatePosableAnim = false);
	
	virtual ~Asura_ClientEntity_ServerCutsceneActorHierarchy();

    virtual const Asura_Vector_3& GetCurrentPosition( void ) const;
	virtual bool HandleMessage(const Asura_Message* pxMessage);
    bool GetMarkerPosAndOri( Asura_Hash_ID uMarkerHashID, Asura_Vector_3* pxPos, Asura_Matrix_3x3* pxOri ) const;

	const Asura_Animation* GetAnimation( void ) const { return m_pxAnimation; }
	Asura_Animation* GetAnimation( void ) { return m_pxAnimation; }

protected:

	virtual void Render(void);
	virtual void Render(const Asura_Vector_3& xPos,const Asura_Matrix_3x3& xMat);
    

	void InsertAttachment(Asura_ServerCutscene_ClientAttachment* pxAttachment);
	void RemoveAttachment(u_int uID);

    class Asura_Cutscene* m_pxCutscene;
    class Asura_Animation* m_pxAnimation;
    float m_fCutsceneTimeAfterLastRender;
    float m_fCutsceneTimeAtLastUpdate;
    u_int m_uFlags;
	
	Asura_ServerCutscene_ClientAttachment* m_pxFirstAttachment;
    
private:
    
    typedef Asura_ClientEntity_ServerCutsceneActor PARENT;

};

class Asura_ClientEntity_ServerCutsceneActorCamera : public Asura_ClientEntity_ServerCutsceneActor
{
public:

	Asura_ClientEntity_ServerCutsceneActorCamera()
	{
		m_fFOV = 0.0f;
		m_bWidescreen = false;
	}
//	virtual ~Asura_ClientEntity_ServerCutsceneActorCamera();

	   virtual bool HandleMessage(const Asura_Message* pxMessage);

protected:

	virtual void Render(void);    
	virtual void Render(const Asura_Vector_3& xPos,const Asura_Matrix_3x3& xMat){}

	Asura_Angle m_fFOV;
	bool m_bWidescreen;

};

class Asura_ClientEntity_ServerCutsceneActorShape : public Asura_ClientEntity_ServerCutsceneActor
{

public:

	Asura_ClientEntity_ServerCutsceneActorShape(Asura_Hash_ID uCutsceneHash, Asura_Hash_ID uShapeID);

	virtual bool HandleMessage(const Asura_Message* pxMessage);

protected:

	virtual void Render(void);
	virtual void Render(const Asura_Vector_3& xPos,const Asura_Matrix_3x3& xMat);

    Asura_Cutscene* m_pxCutscene;
	Asura_Shape_Instance m_xShapeInstance;
    float m_fCutsceneTimeAfterLastRender;
    float m_fCutsceneTimeAtLastUpdate;

};


/////////////////////////////////////////////////////////////////////////////////////////////////////
class Asura_ServerCutscene_ClientAttachment
{
public :
	Asura_ServerCutscene_ClientAttachment( const Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment* pxMessage );
	virtual ~Asura_ServerCutscene_ClientAttachment(){}

	virtual void Render(){}
	void UpdatePosition(const Asura_Animation* pxParentAnimation, const Asura_Vector_3 &xParentPosition, const Asura_Matrix_3x3 &xParentMatrix);
	u_int GetID() const {return m_uID;}

protected :
	u_int m_uID;
	int m_uMarkerHash;
	bool m_bPositionValid;

	Asura_Vector_3 m_xPos;
	Asura_Matrix_3x3 m_xMat;

public :
	Asura_ServerCutscene_ClientAttachment* m_pxNextAttachment;

};

class Asura_ServerCutscene_ClientAttachment_Shape : public Asura_ServerCutscene_ClientAttachment
{

public:

	Asura_ServerCutscene_ClientAttachment_Shape( const Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentShape* pxMessage,
                                                 Asura_Cutscene* pxParentCutscene );

	virtual void Render();
 
protected:

	Asura_Shape_Instance m_xShapeInstance;

private:

    typedef Asura_ServerCutscene_ClientAttachment PARENT;

};

class Asura_ServerCutscene_ClientAttachment_Hierarchy : public Asura_ServerCutscene_ClientAttachment
{

public:

	Asura_ServerCutscene_ClientAttachment_Hierarchy( const Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentHierarchy* pxMessage,
                                                     Asura_Cutscene* pxParentCutscene,
                                                     Asura_Animation* pxParentAnimation );
	virtual ~Asura_ServerCutscene_ClientAttachment_Hierarchy( void );


protected:

	Asura_Animation* m_pxAnimation;
	Asura_Animation* m_pxParentAnimation;
	

private:

    typedef Asura_ServerCutscene_ClientAttachment PARENT;

};

class Asura_ServerCutscene_ClientAttachment_Actor : public Asura_ServerCutscene_ClientAttachment
{

public:

	Asura_ServerCutscene_ClientAttachment_Actor( const Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentActor* pxMessage );
	virtual ~Asura_ServerCutscene_ClientAttachment_Actor( void );

	virtual void Render();
	Asura_ClientEntity_ServerCutsceneActor* GetAttachedActor( void ) const;
 
protected:

	Asura_Guid m_uActorID;

private:

    typedef Asura_ServerCutscene_ClientAttachment PARENT;

};

class Asura_ServerCutscene_ClientAttachment_Entity : public Asura_ServerCutscene_ClientAttachment
{

public:
    
	Asura_ServerCutscene_ClientAttachment_Entity( const Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentEntity* pxMessage,
                                                  Asura_Cutscene* pxParentCutscene );
	virtual ~Asura_ServerCutscene_ClientAttachment_Entity( void );

	virtual void Render();

protected:

	Asura_Guid m_uEntityGUID;
    u_short    m_usEntityClassification;
	bool	m_bHasBeenUpdated;

private:

    typedef Asura_ServerCutscene_ClientAttachment PARENT;

};



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

class Asura_Message_ServerCutsceneActor_ClientUpdateStandard
{
public:
    Asura_Hash_ID	uCutsceneHash;
    short           sSkinID;
    short           sAnimationID;
	int				iAnimationFlags;
	float			fAnimationDelay;
    u_int           uFlags;
    Asura_Vector_3  xPosition;
    Asura_Quat      xOrientation;
    float           fSpeed;
    float           fCutsceneTime;
	Asura_Hash_ID   uTextureHash;
};

struct Asura_Message_ServerCutsceneActorShape_ClientUpdateStandard
{
    Asura_Hash_ID	m_uCutsceneHash;
	Asura_Hash_ID	m_uShapeID;
    Asura_Vector_3  m_xPosition;
    Asura_Quat      m_xOrientation;
    float           m_fCutsceneTime;
};


struct Asura_Message_ServerCutsceneActor_ClientUpdateChangePrimaryAnim
{
    Asura_Hash_ID   m_uAnimHashID;
	int             m_iAnimationFlags;
	float           m_fTweenDuration;
    float           m_fCutsceneTime;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateSecondaryAnim
{
    Asura_Hash_ID m_uAnimHashID;
	int			  m_iAnimationFlags;
    float		  m_fWeight;
	float		  m_fTweenDuration;
};


struct Asura_Message_ServerCutsceneActor_ClientUpdatePrimaryAnim_ToPos
{
    short AnimationID;
	int AnimationFlags;
	float TweenDuration;

	float m_fStartTimer;
	float m_fEndTimer;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateSecondaryAnim_ToPos
{
    short AnimationID;
	int AnimationFlags;
    float Weight;
	float TweenDuration;

	float m_fStartTimer;
	float m_fEndTimer;

};


struct Asura_Message_ServerCutsceneActor_ClientUpdateBasic
{
    Asura_Vector_3  xPosition;
    Asura_Quat      xOrientation;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment
{
	u_int m_uID;
	Asura_Hash_ID m_uMarkerHash;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentShape : Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment
{
	Asura_Hash_ID m_uShapeHash;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentHierarchy : Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment
{
	int m_iSkinID;
	int m_iAnimID;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentActor : Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment
{
	Asura_Guid m_uActorID;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachmentEntity : Asura_Message_ServerCutsceneActor_ClientUpdateAddAttachment
{
	Asura_Guid m_uEntityGUID;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateRemoveAttachment
{
	u_int m_uID;
};

struct Asura_Message_ServerCutsceneActor_ClientUpdateCamera : Asura_Message_ServerCutsceneActor_ClientUpdateBasic
{
	Asura_Angle m_fFOV;
	unsigned char m_ucWidescreen;
};


#endif // #ifdef ASURA_SUPPORT_SERVERCUTSCENES	// the Gunfighter-style cutscenes with entities

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

#endif // #ifndef ___ASURA_CLIENTENTITY_SERVERCUTSCENEACTOR_H___
