//
// Asura_ServerEntity_PFX_Effect.h
//
// Created by KOR - 15/03/2004 10:54:15
//
// Copyright (C) 2004 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif

#ifndef __ASURA_SERVERENTITY_PFX_EFFECT_H__
#define __ASURA_SERVERENTITY_PFX_EFFECT_H__

#include "Entity/Asura_Entity.h"
#include "Entity/Asura_Entity_Classification.h"
#include "Entity/ParticleGenerator/Asura_Entity_PFX_Effect_Data.h"

// Constants
// Version 10 - 25/01/2008 - KOR - Merged common client and server data into Asura_Entity_PFX_Effect_Data
// Version 11 - 14/03/2008 - RAR - Moved to using 'active' flag from Asura_Entity
static const int ASURA_SERVERENTITY_PFX_EFFECT_VERSION = 11;

// Forward defines

class Asura_PFX_Effect_Template;
template <typename T> class Asura_Spline;

struct Asura_Entity_PFX_Effect_ChunkData
{
	Asura_Vector_3		m_xPosition;
	Asura_Comp_Quat_Fast		m_xOrientation;
	Asura_Hash_ID		m_uEffectTemplateHash;
	Asura_Vector_3		m_xCollisionPosition;
	Asura_Vector_3		m_xCollisionDirection;
	float				m_fTimeSinceLastActivateMessage;
	float				m_fMinRetriggerTime;
	float				m_fMaxRetriggerTime;
	union
	{
		u_int			m_uFlags;
		struct
		{
			// NOTE: These bit's are written out, adding any new bits means
			// ~~~~~ that you will need to add those bits to the bitfield
			//       preparation code in "WriteToChunkStream".
			u_int		m_bOldActiveFlag : 1;
			u_int		m_bIgnoreModuleLinking : 1;
			u_int		m_bSkyboxEffect : 1;
			u_int		m_bWaterDistorterEffect : 1;
		};
	};
};

struct Asura_Entity_PFX_Effect_ChunkData_V7
{
	Asura_Vector_3		m_xPosition;
	Asura_Comp_Quat_Fast		m_xOrientation;
	Asura_Hash_ID		m_uEffectTemplateHash;
	Asura_Vector_3		m_xCollisionPosition;
	Asura_Vector_3		m_xCollisionDirection;
	float				m_fTimeSinceLastActivateMessage;
	union
	{
		u_int			m_uFlags;
		struct
		{
			// NOTE: These bit's are written out, adding any new bits means
			// ~~~~~ that you will need to add those bits to the bitfield
			//       preparation code in "WriteToChunkStream".
			u_int		m_bOldActiveFlag : 1;
			u_int		m_bIgnoreModuleLinking : 1;
			u_int		m_bSkyboxEffect : 1;
		};
	};
};

struct Asura_Entity_PFX_Effect_ChunkData_V6
{
	Asura_Vector_3		m_xPosition;
	Asura_Comp_Quat_Fast		m_xOrientation;
	Asura_Hash_ID		m_uEffectTemplateHash;
	Asura_Vector_3		m_xCollisionPosition;
	Asura_Vector_3		m_xCollisionDirection;
	union
	{
		u_int			m_uFlags;
		struct
		{
			// NOTE: These bit's are written out, adding any new bits means
			// ~~~~~ that you will need to add those bits to the bitfield
			//       preparation code in "WriteToChunkStream".
			u_int		m_bOldActiveFlag : 1;
			u_int		m_bIgnoreModuleLinking : 1;
			u_int		m_bSkyboxEffect : 1;
		};
	};
};

struct Asura_Entity_PFX_Effect_ChunkData_V1
{
	Asura_Vector_3		m_xPosition;
	Asura_Matrix_3x3	m_xOrientation;
	Asura_Hash_ID		m_uEffectTemplateHash;
	Asura_Vector_3		m_xCollisionPosition;
	Asura_Vector_3		m_xCollisionDirection;
	union
	{
		u_int			m_uFlags;
		struct
		{
			u_int		m_bOldActiveFlag : 1;
			u_int		m_bIgnoreModuleLinking : 1;
		};
	};
};

struct Asura_Entity_PFX_Effect_ChunkData_V0
{
	Asura_Vector_3		m_xPosition;
	Asura_Matrix_3x3	m_xOrientation;
	Asura_Hash_ID		m_uEffectTemplateHash;
	Asura_Vector_3		m_xCollisionPosition;
	Asura_Vector_3		m_xCollisionDirection;
};

class Asura_ServerEntity_PFX_Effect : public Asura_Entity_Server
{

public:

    static Asura_ServerEntity_PFX_Effect* FindEntity( Asura_Guid uGUID ) { return s_xList.FindEntity( uGUID ); }
	static const Asura_Hashed_List<Asura_ServerEntity_PFX_Effect>* GetList( void ) { return &s_xList; }

	Asura_ServerEntity_PFX_Effect(Asura_Guid uGuid);
	// Need to add template
	Asura_ServerEntity_PFX_Effect( Asura_Guid uGuid, const Asura_Vector_3& xPos, const Asura_Matrix_3x3& xDir);
	~Asura_ServerEntity_PFX_Effect();

	static void CreateFromChunkStream(Asura_Guid uGuid, Asura_Chunk_Stream& xStream);

	// virtual functions
    virtual bool HandleMessage(const Asura_Message* pxMessage);

	Asura_Hash_ID GetTemplateHashID() const { return m_xPFXEffectData.m_uEffectTemplateHash; }

	// Functions for saving the entities to chunks...
	virtual	bool	IsFilledFromChunkBuffer		(void) const	{ return (false); }
	virtual bool	CanBeSavedToChunk() const {return true;}

	virtual	int		GetChunkBufferSize			(void);
	virtual	void	FillInChunkBuffer			(char*& pcChunkBuffer);

	virtual	void	ReadFromChunkStream			(Asura_Chunk_Stream& xStream);
	virtual	void	WriteToChunkStream			(Asura_Chunk_Stream& xStream) const;

#ifdef ASURA_TOOLS
	virtual void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance);
	virtual bool CanBeIncludedInTemplate() const {return Classification == AsuraEntityClass_PFX_Effect;}

#endif

	bool IsActive() const { return IsEntityActive(); }
	const Asura_Vector_3& GetPosition() const { return m_xPosition; }
	float GetStartTime(void) const;

	// Function used to work out how far a point is away from this entity...
	float	CalculateSquaredDistanceTo(const Asura_Vector_3& xPosition) const	{ const Asura_Vector_3 xDistance(m_xPosition - xPosition); return(xDistance.MagnitudeSquared()); }

protected:

    // more virtual functions
	virtual void OnEntityActivateMessage(void);
	virtual void OnEntityDeactivateMessage(void);
		
	Asura_Vector_3				m_xPosition;
	Asura_Matrix_3x3			m_xOrientation;

	Asura_Entity_PFX_Effect_Data m_xPFXEffectData;

private:

	friend class Asura_ClientEntity_PFX_Effect;
#ifdef ASURA_TOOLS
	friend class Tools_Entity_PFX_Effect;
#endif

    static Asura_Hashed_List<Asura_ServerEntity_PFX_Effect> s_xList;

};

#endif//__ASURA_SERVERENTITY_PFX_EFFECT_H__
