#ifndef _RUSHADER_D3D_WATER_H_
#define _RUSHADER_D3D_WATER_H_

// Rune system core
#include "../../Direct3D/Shader/RuShader_D3D_Base.h"

#pragma unmanaged

// ************************************************************************************************************************************************************

/*!
	VERTEX SHADER CONSTANTS
	-----------------------
	[ 27 -  30] Projected texture transform
	[ 31 -  31] (base color R, base color G, base color B, alpha factor)

	PIXEL SHADER CONSTANTS
	----------------------
	[  2 -   2] (reflect factor, refract factor, base factor, specular strength)
*/
class CRuShader_Water_PS20_Base : public CRuShader_Base
{
public:
											CRuShader_Water_PS20_Base(CRuEngineD3D *engine);
	virtual									~CRuShader_Water_PS20_Base();

	// Shader capabilities query
	virtual INT32							GetShaderPriority() const;
	virtual DWORD							GetCaps() const;

	// Shader parameter setup
	virtual void							SetParameters(const CRuParameterCache *paramCache);

	// Instancing helper
	virtual void							Instance(INT32 streamIndex, IRuMesh *mesh, UINT32 morphTargetIndex, void *buffer) const;
};

// ************************************************************************************************************************************************************

class CRuShader_Water_PS20_Full : public CRuShader_Water_PS20_Base
{
public:
											CRuShader_Water_PS20_Full(CRuEngineD3D *engine);
	virtual									~CRuShader_Water_PS20_Full();

	// Shader capabilities query
	virtual const char*						GetShaderName() const;

	// Rendering setup
	virtual INT32							GetNumPasses() const;
	virtual void							BeginPass(INT32 passNumber);
	virtual void							EndPass(INT32 passNumber);

	// Shader texture placement query
	virtual INT32							GetNumSamplers(INT32 passNumber) const;
	virtual RuTextureChannel				GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const;
};

// ************************************************************************************************************************************************************

class CRuShader_Water_PS20_Diffuse : public CRuShader_Water_PS20_Base
{
public:
											CRuShader_Water_PS20_Diffuse(CRuEngineD3D *engine);
	virtual									~CRuShader_Water_PS20_Diffuse();

	// Shader capabilities query
	virtual const char*						GetShaderName() const;

	// Rendering setup
	virtual INT32							GetNumPasses() const;
	virtual void							BeginPass(INT32 passNumber);
	virtual void							EndPass(INT32 passNumber);

	// Shader texture placement query
	virtual INT32							GetNumSamplers(INT32 passNumber) const;
	virtual RuTextureChannel				GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const;
};

// ************************************************************************************************************************************************************

inline INT32 CRuShader_Water_PS20_Base::GetShaderPriority() const
{
	return 1100;
}

inline DWORD CRuShader_Water_PS20_Base::GetCaps() const
{
	return 0x00000000;
}

// ************************************************************************************************************************************************************

inline const char *CRuShader_Water_PS20_Full::GetShaderName() const
{
	return "ruSHADER_WATER_PS20_FULL";
}

inline INT32 CRuShader_Water_PS20_Full::GetNumPasses() const
{
	return 1;
}

inline INT32 CRuShader_Water_PS20_Full::GetNumSamplers(INT32 passNumber) const
{
	return 4;
}

inline RuTextureChannel CRuShader_Water_PS20_Full::GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const
{
	switch(samplerNumber)
	{
		case 0:
			return ruTEXCHANNEL_REFLECTIONMAP;
		case 1:
			return ruTEXCHANNEL_REFRACTIONMAP;
		case 2:
			return ruTEXCHANNEL_DIFFUSEMAP;
		case 3:
			return ruTEXCHANNEL_CAUSTICMAP;
	}

	return ruTEXCHANNEL_INVALID;
}

// ************************************************************************************************************************************************************

inline const char *CRuShader_Water_PS20_Diffuse::GetShaderName() const
{
	return "ruSHADER_WATER_PS20_DIFFUSE";
}

inline INT32 CRuShader_Water_PS20_Diffuse::GetNumPasses() const
{
	return 1;
}

inline INT32 CRuShader_Water_PS20_Diffuse::GetNumSamplers(INT32 passNumber) const
{
	return 2;
}

inline RuTextureChannel CRuShader_Water_PS20_Diffuse::GetTextureChannel(INT32 passNumber, INT32 samplerNumber) const
{
	switch(samplerNumber)
	{
		case 0:
			return ruTEXCHANNEL_DIFFUSEMAP;
		case 1:
			return ruTEXCHANNEL_CAUSTICMAP;
	}

	return ruTEXCHANNEL_INVALID;
}

// ************************************************************************************************************************************************************

#pragma managed

#endif
