
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_SurfaceEffects.h
// Author : Chris Wallace
// Date   : 2-Aug-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __AVP_SURFACEEFFECTS_H__
#define __AVP_SURFACEEFFECTS_H__

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Blueprint/Asura_Blueprint_System.h"
#include "Core/Asura_HashTree.h"
#include "Core/Asura_Maths.h"
#include "Network/Asura_Guid.h"

#define AVP_MAX_SURFACE_EFFECT_PFX 10 

class Asura_Blueprint;
class AVP_EntityDamage_ApplyToEntity;
/////////////////////////////////////////////////////////
// Simply contains a hash for a AVP_SurfaceEffect
/////////////////////////////////////////////////////////

class AVP_SurfaceEffect_Map
{
public:
	Asura_Hash_ID	GetHash(void)					{ return(m_uEffectHash); }
	void			SetHash(Asura_Hash_ID uHash)	{ m_uEffectHash = uHash; }
private:
	Asura_Hash_ID m_uEffectHash;
};

/////////////////////////////////////////////////////////
// Class containing a list of AVP_SurfaceEffect_Map
// for the damage table
/////////////////////////////////////////////////////////

class AVP_SurfaceEffect_DamageMap
{
public:
	Asura_TemplateHashTree<AVP_SurfaceEffect_Map>* GetList(void) { return(&m_xList); }
private:
	Asura_TemplateHashTree<AVP_SurfaceEffect_Map> m_xList;
};

/////////////////////////////////////////////////////////
// Class containing a list of AVP_SurfaceEffect_Map
// for the collision table
/////////////////////////////////////////////////////////

class AVP_SurfaceEffect_CollisionMap
{
public:
	Asura_TemplateHashTree<AVP_SurfaceEffect_Map>* GetList(void) { return(&m_xList); }
private:
	Asura_TemplateHashTree<AVP_SurfaceEffect_Map> m_xList;
};

/////////////////////////////////////////////////////////
// Class containing a list of AVP_SurfaceEffect_EffectTypeMap
// for the collision table
/////////////////////////////////////////////////////////

class AVP_SurfaceEffect_EffectTypeMap
{
public:
	Asura_TemplateHashTree<AVP_SurfaceEffect_Map>* GetList(void) { return(&m_xList); }
private:
	Asura_TemplateHashTree<AVP_SurfaceEffect_Map> m_xList;
};

/////////////////////////////////////////////////////////
// Class containing AVP_SurfaceEffect_Data
// All data for creating one surface effect in one handy struct. If the number of PFX in an effect becomes enumerated, instead of fixed at primary and secondary, we'll have to change this a bit.
/////////////////////////////////////////////////////////

struct AVP_SurfaceEffect_Data
{
	AVP_SurfaceEffect_Data() : m_uDecalHash( ASURA_HASH_ID_UNSET ), m_uNumPFX(0), m_uSoundHash( ASURA_HASH_ID_UNSET ), m_uVibration( ASURA_HASH_ID_UNSET), 
							  m_uDamageType( ASURA_HASH_ID_UNSET ), m_fDamageDelay(0.f), m_fDamageInterval(0.f), m_fLifetime(0.f), m_fDamage(0.f), m_fPFXBBScaling(0.f) {}

	Asura_Hash_ID m_uDecalHash;
	u_int m_uNumPFX;
	Asura_Hash_ID m_auPFXHash[ AVP_MAX_SURFACE_EFFECT_PFX ];
	Asura_Hash_ID m_uSoundHash;
	Asura_Hash_ID m_uVibration;

	// Surface effect damage - played on first pfx only!
	Asura_Hash_ID m_uDamageType;
	float m_fDamageDelay;
	float m_fDamageInterval;
	float m_fLifetime; 
	float m_fDamage;
	float m_fPFXBBScaling;

};

/////////////////////////////////////////////////////////
// Class to handle AVP_SurfaceEffect and the damage table
/////////////////////////////////////////////////////////

class AVP_SurfaceEffect_System
{

public:

	static void PlayDamageSurfaceEffect( Asura_Hash_ID uSurfaceHash,const AVP_EntityDamage_ApplyToEntity& xDamage, Asura_Guid uTargetGuid);
	static void PlayDamageSurfaceEffect( Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uDamageTypeHash, const Asura_Vector_3& xPosition, const Asura_Vector_3& xNormal, const float fVolumeScale = 1.0f, Asura_Guid uTargetGuid = ASURA_GUID_UNREGISTERED );
	static void PlayCollisionSurfaceEffect( Asura_Hash_ID uCollider, Asura_Hash_ID uCollidee, const Asura_Vector_3& xPosition, const Asura_Vector_3& xNormal, const float fVolumeScale = 1.0f, Asura_Guid uTargetGuid = ASURA_GUID_UNREGISTERED );
	static void PlayEffectTypeSurfaceEffect( Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uEffectTypeHash, const Asura_Vector_3& xPosition, const Asura_Vector_3& xNormal, const float fVolumeScale = 1.0f, Asura_Guid uTargetGuid = ASURA_GUID_UNREGISTERED );

private:

	static bool GetDamageEffectData(Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uDamageTypeHash, AVP_SurfaceEffect_Data& xData);
	static bool GetCollisionEffectData(Asura_Hash_ID uCollider, Asura_Hash_ID uCollidee, AVP_SurfaceEffect_Data& xData);
	static bool GetEffectTypeEffectData(Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uEffectTypehash, AVP_SurfaceEffect_Data& xData);

	static u_int CreateDamageEntityPFXEffect( const Asura_Vector_3& xPosition, const Asura_Vector_3& xNormal, Asura_Hash_ID uPFXHash, Asura_Guid uTarget, int iBoneID);
	static void PlayEffect( const AVP_SurfaceEffect_Data& xData, const Asura_Vector_3& xPosition, const Asura_Vector_3& xNormal, const float fVolumeScale = 1.0f , Asura_Guid uTargetGuid = ASURA_GUID_UNREGISTERED, int iBoneID = 0 );
	
	static void GetEffectData(const Asura_Blueprint& xBlueprint, AVP_SurfaceEffect_Data& xData);

	static Asura_Hash_ID GetDamageSurfaceEffect( Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uDamageTypeHash );
	static Asura_Hash_ID GetCollisionSurfaceEffect( Asura_Hash_ID uCollider, Asura_Hash_ID uCollidee );
	static Asura_Hash_ID GetEffectTypeSurfaceEffect( Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uEffectTypeHash );

	static AVP_SurfaceEffect_Map* GetDamageMap( Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uDamageHash, bool bAddOnFail = false );
	static AVP_SurfaceEffect_Map* GetCollisionMap( Asura_Hash_ID uCollider, Asura_Hash_ID uCollidee, bool bAddOnFail = false );
	static AVP_SurfaceEffect_Map* GetEffectTypeMap( Asura_Hash_ID uSurfaceHash, Asura_Hash_ID uEffectTypeHash, bool bAddOnFail = false );

	static Asura_TemplateHashTree<AVP_SurfaceEffect_DamageMap>		s_xDamageTableList;
	static Asura_TemplateHashTree<AVP_SurfaceEffect_CollisionMap>	s_xCollisionTableList;
	static Asura_TemplateHashTree<AVP_SurfaceEffect_EffectTypeMap>	s_xEffectTypeTableList;
	

	friend class AVP_Chunk_SurfaceOverlay;
#ifdef ASURA_TOOLS
	friend class ToolsAVP_DamageCell_Dialog;
	friend class ToolsAVP_CollisionCell_Dialog;
	friend class ToolsAVP_EffectTypeCell_Dialog;
#endif
};

class AVP_SurfaceEffect_PFXEnumerator : public Asura_Blueprint_ParameterEnumerator
{
public:
	AVP_SurfaceEffect_PFXEnumerator( Asura_Hash_ID* puHash ) : m_puHash( puHash ) {}
	virtual ~AVP_SurfaceEffect_PFXEnumerator() {}

	virtual void BeginEnumeration() {}
	virtual bool Enumerate( const u_int uIndex, char const* const szName, const Asura_Value& xValue);
	virtual void EndEnumeration( const bool bSuccess ) {}

private:
	typedef Asura_Blueprint_ParameterEnumerator PARENT;

	Asura_Hash_ID* m_puHash;
};

#endif   // ifndef __AVP_SURFACEEFFECTS_H__

/// End of file. ///
