#ifndef __PPEFFECTSCOMMON__
#define __PPEFFECTSCOMMON__

// Forward declarations
class TargetableTexture;
class EffectParam;

#define MAX_NUM_PARAM 2	// We'll have at maximum 2 parameters for this demo


/////////////////////////////////////////////////////////////////////////////
// PPEffectCommon is the common parameters to all post process effects
/////////////////////////////////////////////////////////////////////////////
class PPEffectsCommon
{
	protected:

		LPD3DXEFFECT m_pEffect;						// The effect interface

		D3DXHANDLE * m_hRTTextures;					// Handles to the render target textures
		D3DXHANDLE * m_hSceneTextures;				// Handles to the scene target textures

		D3DXHANDLE m_hTime;							// Handle on the time

		D3DXHANDLE m_hTechnique;					// Handle on the post process technique

		bool * m_bWriteToRT;						// An array of 4 (our max number of RTs) boolean to know where the effect writes to

		EffectParam * m_pParam[MAX_NUM_PARAM];		// The effect user-modifiable parameters
		int m_nNbAvailableParams;					// the number of param actually instanciated


	public:

		// Construction / destruction
		PPEffectsCommon(LPCWSTR filePath, const UINT nNbAvailableRTs);
		~PPEffectsCommon();

		// Effect Setup
		HRESULT CompileEffect(LPCWSTR filePath);				// Compile an effect file
		void SetupCommonHandles(const int nNbAvailableRTs);		// Prepare the common handles
		void SetupParamHandles();								// Prepare the handles on tthe parameters
		void GetWrittenRTSlots(const UINT nRTCount);			// Find the RTs numbers that will be written
		
		HRESULT BindEffectRTTextures(LPDIRECT3DTEXTURE9 * pSrcTexturesSets, const int nCount) const;	// Bind nCount textures to the effect
		HRESULT BindEffectSceneTextures(TargetableTexture * pSceneTexturesSets, const int nCount) const;// Bind the scene texture to the effect
		HRESULT BindTime(const float fTime) const;														// Bind time value to the effect
		HRESULT SetEffectTechnique() const;																// Huuu-duuuuuuuuh!

		// Getters
		LPD3DXEFFECT getEffect(){ return m_pEffect; }
		const bool * getRTWriteList(){ return (const bool*)m_bWriteToRT; }
		EffectParam * getParameter(const int nIndex){ return (nIndex<0 || nIndex>MAX_NUM_PARAM-1 || !m_pParam)?NULL:m_pParam[nIndex]; }
		int GetNbAvailableParams(){ return m_nNbAvailableParams; }

		// DirectX device handling
		HRESULT OnResetDevice(const int nWidth, const int nHeight);
		HRESULT OnLostDevice();
};


#endif