//
// Asura_EffectVolume_EntityParameters.h
//
// Created by Emil Popovic - 15/12/2008
// 
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif



#ifndef __ASURA_EFFECTVOLUME_ENTITYPARAMETERS_H__
#define __ASURA_EFFECTVOLUME_ENTITYPARAMETERS_H__

#include "Volume/Asura_VolumeGroup.h"
#include "Entity/Triggers/EffectVolume/Asura_EffectVolume_Effect.h"

// Data object for Asura_ClientEntity_EffectVolume and Asura_ServerEntity_EffectVolume. 
// Main thing it contains is list of all Effects that are inside. It might be Fog, SFSX, Skybox, etc... 

// Also it contain 2 types of volume.
// -1 Transition Volume. These volumes are Box, Sphere, Cylinder. So, depending on camera position inside the volume.
//                       the Strength of the effect will be calculated. So, strength of effect is changing, depending
//                       on where exactly camera is.
// -2 (Time) Volumes.    These volumes are based on time. It doesn't matter where exactly camera is inside the volume,
//                       as long as it is in the volume. Strength is determined on fact, how long we are in the volume.
//                       For doing that, two extra values are taken into account. FadeInDuration and FadeOutDuration.
// Please note that Transition Volumes have higher priority that (Time) Volumes. So if they overlap and camera is inside
// both of them, Transition Volume will take a lead.

class Asura_EffectVolume_EntityParameters
{
#ifdef ASURA_TOOLS
	friend class Tools_Entity_EffectVolume;
#endif

public:
	// Accessor functions
	void	SetFadeInDuration( float fFadeInDuration )		{	m_fFadeInDuration = fFadeInDuration; }
	void	SetFadeOutDuration( float fFadeOutDuration )	{	m_fFadeOutDuration= fFadeOutDuration;}

	float	GetFadeInDuration() const						{return m_fFadeInDuration; }
	float	GetFadeOutDuration() const						{return m_fFadeOutDuration;}

	u_int	GetPriority() const								{return m_uPriority;}
	void	SetPriority( u_int uPriority )					{m_uPriority = uPriority;}

	u_int	GetNumOfEffects() const							{return m_uNumEffects;}

	bool	IsPositionWithinVolume( const Asura_Vector_3& xPosition ) const				{ return m_pxVolumeGroup->Contains(xPosition ); }	
	bool	IsPositionWithinTransitionVolume( const Asura_Vector_3& xPosition ) const	{ return m_pxTransitionVolumeGroup->Contains(xPosition); }	
	float	CalculateStrengthFromTransitionVolume( const Asura_Vector_3& xPosition  ) const;

	void	AddNewEffect( Asura_EffectVolume_Effect* pxNewEffect );
	void	RemoveEffect( u_int uNumOfEffectToRemove );
	Asura_EffectVolume_Effect* GetEffect( u_int uNumOfEffectToGet );
	void	RemoveAllEffects();


	Asura_VolumeGroup* GetVolume()				{	return m_pxVolumeGroup;	};				// Accessor to VolumeGroup
	Asura_VolumeGroup* GetTransitionVolume()	{	return m_pxTransitionVolumeGroup;	};	// Accessor to VolumeGroup


	void	Clear();

	Asura_EffectVolume_EntityParameters();
	~Asura_EffectVolume_EntityParameters();

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

#ifdef ASURA_TOOLS
	// This will copy the values from one object to another. However, function is slower, because instead of directly copying all values, 
	// it will WriteToChunk the xFrom value and ReadFromChunk it from that stream in xTo. This approach is little bit slower, but it's 
	// benefit is that we don't need to duplicate the code twice. Once for Reading and once for Copy. So the source code will be safer. 
	// This function will be available only in tools, (therefore 0.0005 seconds slower copy won't bother anyone. :-) But each time, anyone will copy this, it will also check for you if Read/Write code works too. :-)
	static void Tools_Copy( Asura_EffectVolume_EntityParameters& xTo, const Asura_EffectVolume_EntityParameters& xFrom );

	void ApplyChangesForTemplateInstance(class Tools_EntityTemplateInstance* pxInstance);
#endif

private:
	static const u_int			s_uChunkVersion;	// The version used when reading/writing.

	float						m_fFadeInDuration;		// Once we enter the volume: How much time in seconds is needed to set the effect to full strength.
	float						m_fFadeOutDuration;		// Once we leave the volume: How much time in seconds is needed to set the effect to zero strength.
	u_int						m_uPriority;			// For the moment priority is between 1 and 10 (including)

	u_int						m_uNumEffects;
	Asura_EffectVolume_Effect** m_pxEffects;

	Asura_VolumeGroup*			m_pxVolumeGroup;			// Container class for Asura_Volumes. This one is time based Volume
	Asura_VolumeGroup*			m_pxTransitionVolumeGroup;	// Container class for Asura_Volumes. This one is position based Volume.
};

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

#endif //__ASURA_EFFECTVOLUME_ENTITYPARAMETERS_H__