//
// Asura_FSFX_Component.h
//
// Created by JGP 02/02/06
// 
// Copyright (C) 2006 Rebellion (Derby), All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifdef ASURA_USE_FSFX

#ifndef __ASURA_FSFX_COMPONENT_H__
#define __ASURA_FSFX_COMPONENT_H__

#include "Core/Asura_Maths.h"
#include "Core/Asura_String.h"

class Asura_Chunk_Stream;

/*
	Base component class
*/
class Asura_FSFX_Component
{

public:

	// DON'T RE-ORDER THIS LIST!
	enum Type
	{
		FSFX_TEST = 0,
		FSFX_BRIGHTNESS_AND_CONTRAST = 1,
		FSFX_NOISE = 2,
		FSFX_GAUSSIAN_BLUR = 3,
		FSFX_RADIAL_BLUR = 4,
		FSFX_DEPTH_OF_FIELD = 5,
		FSFX_BLOOM = 6,
		FSFX_GAMMA = 7,
		FSFX_RGB_GAMMA = 8,
		FSFX_DESATURATE_AND_TINT = 9,
		FSFX_SM30_BLOOM	= 10,
		FSFX_COLOUR_MAP = 11,
		FSFX_SM30_DEPTH_OF_FIELD = 12,
		FSFX_SM30_FISHEYE = 13,
		FSFX_SM30_DOUBLEVISION = 14,
		FSFX_SM30_MOTION_BLUR = 15,
		FSFX_FIRST_PROJECT_SPECIFIC = 1000,
	};

	enum Platform
	{
		FSFX_PLATFORM_PC = 0,
		FSFX_PLATFORM_PS2 = 1,
		FSFX_PLATFORM_XB = 2,
		FSFX_PLATFORM_PSP = 3,
		FSFX_PLATFORM_PS3 = 4,
		FSFX_PLATFORM_XB360 = 5,
		FSFX_PLATFORM_WII = 6,
		NUM_PLATFORMS
	};

	// construct

	static Asura_FSFX_Component* CreateOfType( const Type eType );

	Asura_FSFX_Component();
	virtual ~Asura_FSFX_Component() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy() = 0;

	// render
	// (may not exist on all platforms/build configs)
	virtual void Platform_Render( const float fIntensity ) = 0;

	// type

	virtual Type GetType() = 0;

	// get / set

	bool IsPlatformEnabled( const Platform m_ePlatform );

	// tools only

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	virtual const char* GetTypeDesc() const = 0;
	virtual int GetPlatformsSupported() const = 0;	
	static const char* GetPlatformName( const int iIndex )
	{
		static const char* const pszPlatforms[] = { "PC", "PS2", "XB", "PSP", "PS3", "XB360", "Wii" };
		return pszPlatforms[ iIndex ];
	};
#endif // ASURA_TOOLS

	// save / load

	virtual void Deserialize( Asura_Chunk_Stream& xStream ) = 0;
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const = 0;
#endif // ASURA_TOOl

	// DLH - 05 April 2006 12:55:55 - Textures
	virtual u_int GetTextureCount( void) const;
	virtual int GetTextureIndex( const u_int uTemplateTextureIndex ) const;
	virtual const char* GetTextureName( const u_int uTemplateTextureIndex ) const;

protected:

	// helper read write functions		

	void ReadStandardHeader( Asura_Chunk_Stream& xStream, int& iVersion, int& iSize );
#ifdef ASURA_TOOLS
	void WriteStandardHeader( Asura_Chunk_Stream& xStream, const int iSize ) const;
#endif // ASURA_TOOLS

	virtual int GetVersion() const = 0;

	static Asura_FSFX_Component* Project_CreateOfType( const Type eType );

	// vars

	int m_iPlatformsActive;

	// tools only

#ifdef ASURA_TOOLS
	bool m_bExpanded;
#endif // ASURA_TOOLS

};


/*
	Test effect class
*/
class Asura_FSFX_Component_Test : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_Test();
	virtual ~Asura_FSFX_Component_Test() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_TEST; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Test Effect"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

	// private vars

	bool m_bSubtractive;
	float m_fRed, m_fGreen, m_fBlue;

};


/*
	Brightness and contrast adjustment
*/
class Asura_FSFX_Component_BrightnessAndContrast : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_BrightnessAndContrast();
	virtual ~Asura_FSFX_Component_BrightnessAndContrast() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_BRIGHTNESS_AND_CONTRAST; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Brightness And Contrast"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

	// private vars

	float m_fBrightness;
	float m_fContrast;

};

/*
	Desaturate and Tint
*/
class Asura_FSFX_Component_DesaturateAndTint : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_DesaturateAndTint();
	virtual ~Asura_FSFX_Component_DesaturateAndTint() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_DESATURATE_AND_TINT; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Desaturate And Tint"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

	// private vars

	float m_fStrength;
	float m_fIntensityR;
	float m_fIntensityG;
	float m_fIntensityB;

};


/*
	Add Noise
*/
class Asura_FSFX_Component_Noise : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_Noise();
	virtual ~Asura_FSFX_Component_Noise() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_NOISE; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Noise"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

	// texture handling
	void SetTexture();
	u_int GetTextureCount( void) const;
	int GetTextureIndex( const u_int uTemplateTextureIndex) const;
	const char* GetTextureName( const u_int uTemplateTextureIndex) const;
	
private:

	virtual int GetVersion() const { return 3; }

	// private vars

	float m_fAmount;
	Asura_String m_xTextureFilename;
	int32 m_iTextureID;
	uint32 m_uTextureTileX;
	uint32 m_uTextureTileY;
	uint32 m_uTextureHash;

};


/*
	Gaussian Blur
*/
class Asura_FSFX_Component_GaussianBlur : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_GaussianBlur();
	virtual ~Asura_FSFX_Component_GaussianBlur() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_GAUSSIAN_BLUR; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Gaussian Blur"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

// private vars

	float m_fSize;
	float m_fStrength;

};


/*
	Radial Blur
*/
class Asura_FSFX_Component_RadialBlur : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_RadialBlur();
	virtual ~Asura_FSFX_Component_RadialBlur() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_RADIAL_BLUR; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Radial Blur"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

	// private vars

	float m_fSize;
	float m_fStrength;
	Asura_Angle m_fAngle;
	float m_fCentreX;
	float m_fCentreY;

};


/*
	Depth of Field
*/
class Asura_FSFX_Component_DepthOfField : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_DepthOfField();
	virtual ~Asura_FSFX_Component_DepthOfField() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_DEPTH_OF_FIELD; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Depth Of Field"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 )  | ( 1 << FSFX_PLATFORM_WII ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 2; }

	// private vars

	float m_fSize;
	float m_fStrength;
	float m_fNearBlurZ;
	float m_fFarBlurZ;

};


/*
	Bloom
*/
class Asura_FSFX_Component_Bloom : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_Bloom();
	virtual ~Asura_FSFX_Component_Bloom() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_BLOOM; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Bloom"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) | ( 1 << FSFX_PLATFORM_WII ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 2; }

	// private vars

	float m_fThreshold;
	float m_fIntensityR;
	float m_fIntensityG;
	float m_fIntensityB;
};


/*
	Gamma
*/
class Asura_FSFX_Component_Gamma : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_Gamma();
	virtual ~Asura_FSFX_Component_Gamma() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_GAMMA; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Gamma Adjust"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

	// private vars

	float m_fAmount;

};


/*
	RGB Gamma
*/
class Asura_FSFX_Component_RGBGamma : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_RGBGamma();
	virtual ~Asura_FSFX_Component_RGBGamma() {}

	// copy...

	virtual Asura_FSFX_Component* CreateCopy(); 

	// render

	virtual void Platform_Render( const float fIntensity );

	// type

	static Type GetTypeID() { return FSFX_RGB_GAMMA; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Gamma Adjust (RGB)"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_PS2 ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	
#endif // ASURA_TOOLS

	// save and load

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS

private:

	virtual int GetVersion() const { return 1; }

	// private vars

	float m_fAmountR;
	float m_fAmountG;
	float m_fAmountB;

};




/*
SM3.0 Bloom (more controllable than the old bloom)
*/

class Asura_FSFX_Component_SM30_Bloom : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_SM30_Bloom();
	virtual ~Asura_FSFX_Component_SM30_Bloom() {}

	// copy...
	virtual Asura_FSFX_Component* CreateCopy(); 

	// render
	virtual void Platform_Render( const float fIntensity );

	// Need an init/shutdown for this effect, to handle the persistant-between-frames render target,
	// and to init/release shaders
	static void Platform_Initialise();
	static void Platform_Reset();
	static void Platform_Shutdown();

	// type
	static  Type GetTypeID() { return FSFX_SM30_BLOOM; }
	virtual Type GetType()   { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend  class Tools_Mode_FSFX_Template;
	static  const char* GetTypeDescID() { return "Advanced Bloom (SM3.0)"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static  int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	


	// save and load
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS
	virtual void Deserialize( Asura_Chunk_Stream& xStream );

private:
	virtual int GetVersion() const { return 1; }

	// private vars	
	float m_fRBloomThreshold;
	float m_fGBloomThreshold;
	float m_fBBloomThreshold;

	float m_fROutputCol;
	float m_fGOutputCol;
	float m_fBOutputCol;

	float m_fBlurRadius;
	int   m_iBlurPasses;

	float m_fSaturation;

	bool  m_bAccumulate;
	float m_fAccumFade;

	bool  m_bShowBlurBuffer;
	float m_fInputScale;
};


/*
	Colour Map
*/
class Asura_FSFX_Component_ColourMap : public Asura_FSFX_Component
{

public:

	Asura_FSFX_Component_ColourMap();
	virtual ~Asura_FSFX_Component_ColourMap() {}

	virtual Asura_FSFX_Component* CreateCopy();

	virtual void Platform_Render( const float fIntensity );

	static Type GetTypeID() { return FSFX_COLOUR_MAP; }
	virtual Type GetType() { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Colour Map"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | (1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }
#endif

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#ifdef ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif

	virtual u_int GetTextureCount() const { return 1; }
	virtual int GetTextureIndex( const u_int uTemplateTextureIndex ) const { return m_iColourMapIndex; }
	virtual const char* GetTextureName( const u_int uTemplateTextureIndex ) const { return m_xColourMapName.GetString(); }

private:

	virtual int GetVersion() const { return 0; }

	Asura_String m_xColourMapName;
	int m_iColourMapIndex;

};



/*
SM3.0 Depth of Field
*/

class Asura_FSFX_Component_SM30_DepthOfField : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_SM30_DepthOfField();
	virtual ~Asura_FSFX_Component_SM30_DepthOfField() {}

	// copy...
	virtual Asura_FSFX_Component* CreateCopy(); 

	// render
	virtual void Platform_Render( const float fIntensity );

	// Need an init/shutdown for this effect, to handle the persistant-between-frames render target,
	// and to init/release shaders
	static void Platform_Initialise();
	static void Platform_Reset();
	static void Platform_Shutdown();

	// type
	static  Type GetTypeID() { return FSFX_SM30_DEPTH_OF_FIELD; }
	virtual Type GetType()   { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend  class Tools_Mode_FSFX_Template;
	static  const char* GetTypeDescID() { return "Depth of Field (SM3.0)"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static  int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 1 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	


	// save and load
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS
	virtual void Deserialize( Asura_Chunk_Stream& xStream );

private:
	virtual int GetVersion() const { return 1; }

	// private vars	
	float m_afDistances[4];		// near outoffocus - near infocus - far outoffocus - far infocus

	float m_fBlurRadius;
	int   m_iBlurPasses;
	float m_fBlurDesaturate;
	float m_fBleedScale;

	bool  m_bShowBlurBuffer;
	float m_fInputScale;
};

class Asura_FSFX_Component_SM30_DoubleVision : public Asura_FSFX_Component
{
public:

	Asura_FSFX_Component_SM30_DoubleVision();

	virtual Asura_FSFX_Component* CreateCopy();

	virtual void Platform_Render( const float fIntensity );

	static Type GetTypeID() { return static_cast< Type >( FSFX_SM30_DOUBLEVISION ); }
	virtual Type GetType() { return GetTypeID(); }

	// Need an init/shutdown for this effect, to handle the persistant-between-frames render target,
	// and to init/release shaders
	static void Platform_Initialise();
	static void Platform_Reset();
	static void Platform_Shutdown();


#if defined ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "Double Vision"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	// Eventually other platforms will be supported
	static int GetPlatformsSupportedID() { return (1 << FSFX_PLATFORM_PC) | (1 << FSFX_PLATFORM_XB360) | ( 1 << FSFX_PLATFORM_PS3 ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }
#endif // defined ASURA_TOOLS

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#if defined ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif

private:
	virtual int GetVersion() const { return 1; }

	float	m_fSpeed1;
	float	m_fPhase1;
	float	m_fSpeed2;
	float	m_fPhase2;

	float	m_fOrigXOffset1;
	float	m_fOrigYOffset1;
	float	m_fOrigXScale1;
	float	m_fOrigYScale1;
	float	m_fOrigXOffset2;
	float	m_fOrigYOffset2;
	float	m_fOrigXScale2;
	float	m_fOrigYScale2;
};

class Asura_FSFX_Component_SM30_FishEye : public Asura_FSFX_Component
{
public:

	Asura_FSFX_Component_SM30_FishEye();

	virtual Asura_FSFX_Component* CreateCopy();

	virtual void Platform_Render( const float fIntensity );

	static Type GetTypeID() { return static_cast< Type >( FSFX_SM30_FISHEYE ); }
	virtual Type GetType() { return GetTypeID(); }

	// Need an init/shutdown for this effect, to handle the persistant-between-frames render target,
	// and to init/release shaders
	static void Platform_Initialise();
	static void Platform_Reset();
	static void Platform_Shutdown();


#if defined ASURA_TOOLS
	friend class Tools_Mode_FSFX_Template;
	static const char* GetTypeDescID() { return "FishEye"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static int GetPlatformsSupportedID() { return (1 << FSFX_PLATFORM_PC) | (1 << FSFX_PLATFORM_XB360) | ( 1 << FSFX_PLATFORM_PS3 ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }
#endif // defined ASURA_TOOLS

	virtual void Deserialize( Asura_Chunk_Stream& xStream );
#if defined ASURA_TOOLS
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif

private:
	// Len = sqrt(x*x*m_fXScale + y*y+m_fYscale);
	// tan(Theta) = Len . tan(m_fFov)


	virtual int GetVersion() const { return 3; }

	enum FishEye_Type {
		Gnomonical		= 0, // perspective correct, r = tan(Theta) / tan(m_fFov)
		Linear			= 1, // r = Theta / tan(m_fFov)
		EqualArea		= 2, // r = 2 . sin(Theta / 2) / tan(m_fFov)
		Stereographic	= 3, // r = 2 . tan(Theta / 2) / tan(m_fFov)
	};

	enum FishEye_Flags {
		DynamicSine = 1,		// Multiplier scale is modulated over time (sine wave)
	};

	// Version 1

	// tan(Theta2) = x/y;
	// x' = r . m_fMultiplier . sin(Theta2)
	// y' = r . m_fMultiplier . cos(Theta2)

	float m_fXScale; 
	float m_fYScale; 
	float m_fFov;
	float m_fMultiplier;
	int m_eType;

	// Version 2 - 'dynamic'
	u_int m_uFlags;
	float m_fMinMultiplier;
	float m_fMaxMultiplier;
	float m_fSpeed;

	// Version 3 - adds clipping to the sine wave
	float m_fSineClip;

};

class Asura_FSFX_Component_SM30_MotionBlur : public Asura_FSFX_Component
{

public:

	// construct

	Asura_FSFX_Component_SM30_MotionBlur();
	virtual ~Asura_FSFX_Component_SM30_MotionBlur() {}

	// copy...
	virtual Asura_FSFX_Component* CreateCopy(); 

	// render
	virtual void Platform_Render( const float fIntensity );

	// Need an init/shutdown for this effect, to handle the persistant-between-frames render target,
	// and to init/release shaders
	static void Platform_Initialise();
	static void Platform_Reset();
	static void Platform_Shutdown();

	// type
	static  Type GetTypeID() { return FSFX_SM30_MOTION_BLUR; }
	virtual Type GetType()   { return GetTypeID(); }

#ifdef ASURA_TOOLS
	friend  class Tools_Mode_FSFX_Template;
	static  const char* GetTypeDescID() { return "Motion Blur (SM3.0)"; }
	virtual const char* GetTypeDesc() const { return GetTypeDescID(); }
	static  int GetPlatformsSupportedID() { return ( ( 1 << FSFX_PLATFORM_PC ) | ( 1 << FSFX_PLATFORM_XB360 ) | ( 0 << FSFX_PLATFORM_PS3 ) ); }
	virtual int GetPlatformsSupported() const { return GetPlatformsSupportedID(); }	


	// save and load
	virtual void Serialize( Asura_Chunk_Stream& xStream ) const;
#endif // ASURA_TOOLS
	virtual void Deserialize( Asura_Chunk_Stream& xStream );

private:
	virtual int GetVersion() const { return 2; }

	float	m_fBlurAmount;
	float	m_fIgnoreMovementBlur;
};

#endif // __ASURA_FSFX_COMPONENT_H__

#endif // ASURA_USE_FSFX
