//!HLSL



#define PI 3.141592654

void getWaveVariables( out float4 magnitudes, out float4 sins,
					   in float4 scale, in float4 unscaledMagnitudes, in float4 frequencies, float xPoint, float zPoint, float time,
					   float4 waveDirX, float4 waveDirZ, float4 waveSpeed, float4 offsets )
{

///	height(x, z, t) = sum { M sin[ K ( x cos D + z sin D ) + W t + P]
//	M = amplitude
//	K = 2 pi / wavelength
//	D = direction
//	W = 2 pi * frequency = 2 pi * velocity / wavelength
//	P = phase angle
	
	// wave equation stolen from paper
	float4 kxz = frequencies *(((xPoint * waveDirX) + (zPoint * waveDirZ)) + waveSpeed*time + offsets);
	
	magnitudes = unscaledMagnitudes * scale;
	
	float4 clamped = ( (2*PI)*frac((kxz/(2*PI))+.5) ) - PI;
	sins = sin(clamped);

}

struct DecalVOut 
{
	float4 _position : POSITION;
	float4 _color : COLOR;
	float2 _uv : TEXCOORD0;
};


DecalVOut DecalVS(
		float4 position : POSITION,
		uniform float4x4 decalTransforms[MAX_DECALS_PER_CALL],
		uniform float4x4 viewProjection,
		uniform float4 wakeColor[MAX_DECALS_PER_CALL],
		uniform float4 waveDirX,
		uniform float4 waveDirZ,
#ifdef USE_WAVES
		uniform float4  waveFrequency,
		uniform float4  waveMagnitude,
		uniform float4 waveSpeed,
		uniform float4 waveOffset,
#endif
		uniform float3 rampConst,
		uniform float3 eyeWorld,
		uniform float time
		)
		
{

	DecalVOut output;
	
	int index = position.y;
	
	// worldspace
	float4 oceanPoint = position;
	oceanPoint.y = 0;
	
	oceanPoint = mul( decalTransforms[index], oceanPoint );
	
	float3 eyevertdist = oceanPoint.xyz - eyeWorld;

	// distance from eye to vertex in xz plane
	eyevertdist.y = 0;
	// distance gets clamped to between x (1 value) and y (0 value)
	float  distance = clamp(length(eyevertdist), rampConst.x, rampConst.y);

	// we are going to scale y so it damps off with distance.
	// this gives us 1 when distance = rampConst.x, and 0 when it = rampConst.y. 
	float	scale;
	scale = (rampConst.y - distance)/(rampConst.y  - rampConst.x);
	
#ifdef USE_WAVES

	float4 magnitudes;
	float4 sins;
	
	getWaveVariables( magnitudes,  sins,
					   scale, waveMagnitude, waveFrequency, oceanPoint.x, oceanPoint.z, time,
					   waveDirX, waveDirZ, waveSpeed, waveOffset );
					   					   
	
	// sum up to get the height
	// zfighting - hack in an offset
	oceanPoint.y = dot( sins, magnitudes) + .1;
	
#endif

	
	// this is pathetic, but I know its going to be a pain to get alchemy to give up the viewprojection matrix
	oceanPoint = mul(viewProjection, oceanPoint );

	output._position = oceanPoint;
	output._uv = .5 + position.xz;
	output._color.xyzw = wakeColor[index];

	return output;
	
} 

float4 DecalPS(DecalVOut vertex,
			   uniform sampler2D samplerDiffuse0 ) : COLOR0
{
	float4 vFinalColor = tex2D(samplerDiffuse0, vertex._uv);
	vFinalColor *= vertex._color;
	return vFinalColor;
}
