//!HLSL

#include "fogHelper.hlsl"

// -----------------------------------------------------------------------------
// Vertex shader
// -----------------------------------------------------------------------------

struct VSOutput
{
	float4 _position : POSITION;

#ifdef LIGHTING
	float4 _light : COLOR0;
#endif
	float4 _fogValue : COLOR1;

	float2 _uv0 : TEXCOORD0;
	float2 _uv1 : TEXCOORD1;
	float2 _uv2 : TEXCOORD2;
	float2 _lightMapUV : TEXCOORD3;
#ifdef FOURTEX
	float2 _uv3 : TEXCOORD4;
#endif

};

VSOutput VSMain(float4 vPosition : POSITION,
		        float2 vUV : TEXCOORD0,
#ifdef LIGHTING 
	            float3 vNormal : NORMAL,
#endif
		        uniform float fTex1Scale,
		        uniform float fTex2Scale,
		        uniform float fTex3Scale,
#ifdef FOURTEX
				uniform float fTex4Scale,
#endif
		        uniform float fUVAspect,
				uniform float4x4 modelViewProjection,  
	            uniform float4 fogColor,
				uniform float2 fogParams,
		        uniform float4x4 modelWorld
#ifdef LIGHTING
				,
				uniform float3 sunDirectionObject,
		        uniform float4 sunColor,
	            uniform float4 sunAmbient
#endif
#ifdef OCEANDEPTH
				,
				uniform float3 oceanDepthRange,
				uniform float4 oceanDepthColor
#endif

				)
{
	VSOutput ret; 

	// convert to screen space
	//
	ret._position = mul( modelViewProjection, vPosition );
	
	// this uv gets passed through
	ret._lightMapUV = vUV;
	
	// What is our base UV set for the tiling textures
#ifdef WORLDTILEUV
	float3 worldPos = mul( (float4x3)modelWorld, vPosition );
	float2 vBaseUV = worldPos.xz;
#else
	float2 vBaseUV = vUV;
#endif

	// scale the other uvs
	//
	ret._uv0 = vBaseUV * fTex1Scale;
	ret._uv0.x *= fUVAspect;

	ret._uv1 = vBaseUV * fTex2Scale;
	ret._uv1.x *= fUVAspect;

	ret._uv2 = vBaseUV * fTex3Scale;
	ret._uv2 *= fUVAspect;

#ifdef FOURTEX
	ret._uv3 = vBaseUV * fTex4Scale;
	ret._uv3 *= fUVAspect;
#endif

	// fog
	//
							
#ifdef OCEANDEPTH
#ifndef WORLDTILEUV
	float3 worldPos = mul( (float4x3)modelWorld, vPosition );
#endif

	ret._fogValue = getFogValueWorldSpace(fogColor, fogParams,
								ret._position, worldPos, oceanDepthRange, oceanDepthColor);
#else
	ret._fogValue = getFogValue(fogColor, fogParams,
								ret._position);
#endif 

	
	// lighting
	//
#ifdef LIGHTING
	ret._light = saturate(dot(vNormal, sunDirectionObject)) * sunColor + sunAmbient;
#endif

	return ret;
}

// -----------------------------------------------------------------------------
// Pixel shader
// -----------------------------------------------------------------------------
float4 PSMain(VSOutput vertex,
			  uniform sampler2D samplerDiffuse0,
			  uniform sampler2D samplerDiffuse1,
			  uniform sampler2D samplerDiffuse2, 
			  uniform sampler2D maskLightMap,
#ifdef FOURTEX  
			  uniform sampler2D samplerDiffuse3,   
#endif
			  uniform float4 vShadowColor,
			  uniform float fLightScale) : COLOR0
{ 

	// lookup the three base texture
	//
	float4 vColor0 = tex2D(samplerDiffuse0, vertex._uv0);
	float4 vColor1 = tex2D(samplerDiffuse1, vertex._uv1);
	float4 vColor2 = tex2D(samplerDiffuse2, vertex._uv2);
	// get the blend factors
	//
	float4 vMask = tex2D(maskLightMap, vertex._lightMapUV);

#ifdef FOURTEX
	float4 vColor3 = tex2D(samplerDiffuse3, vertex._uv3);
#endif

	// and blend b/t them
	float4 vFinalColor;
	vFinalColor = lerp(vColor0, vColor1, vMask.x);
	vFinalColor = lerp(vFinalColor, vColor2, vMask.y);
#ifdef FOURTEX
	vFinalColor = lerp(vFinalColor, vColor3, vMask.z);
#endif

	// calculate shadow color from constants color and light map
	float fShadow = fLightScale;
#ifndef FOURTEX
	fShadow *= vMask.z;
#endif

	float4 vFinalShadowColor = fShadow + vShadowColor;

	vFinalColor *= vFinalShadowColor;

#ifdef LIGHTING

	vFinalColor *= vertex._light;

#endif

	vFinalColor = getFogColor(vFinalColor, vertex._fogValue);

	return vFinalColor;
}
