uniform sampler2D ShadowMap;

varying vec4 ShadowCoord;

varying vec4 position;
varying vec3 normals;

varying vec3 lightDir, eyeVec;

uniform bool renderShadow;
uniform bool enableColourVariance;

uniform float lightDecrease;

float maxLightDecrease = 0.75;
float actualLightDecrease = lightDecrease * maxLightDecrease;

float LookupShadow(vec2 offSet)
{
	vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w;

	offSet.x *= 0.0001;
	offSet.y *= 0.0001;

	// Values are multiplied by ShadowCoord.w because shadow2DProj does a W division for us.
	return texture2D(ShadowMap, ShadowCoord.xy + vec2(offSet.x * ShadowCoord.w, offSet.y * ShadowCoord.w) ).z;
}

void main (void)
{
	vec3 packedNormal = (normalize(normals) + 1.0)*0.5; // Compress normal

	if(renderShadow)
	{
		vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w;

 		float shadow = 1.0;
		if (ShadowCoord.w > 0.0)
		{
			//shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.35 : 1.0 ;

			// Simple lookup, no PCF
			//shadow = LookupShadow(vec2(0.0,0.0)) < shadowCoordinateWdivide.z ? 0.35 : 1.0;
		
			/*
			float x,y;
			for (y = -4.5; y <= 4.5; y+=1.0)
				for (x = -4.5; x <= 4.5; x+=1.0)
					shadow += LookupShadow(vec2(x,y)) < shadowCoordinateWdivide.z ? 0.35 : 1.0;
					
			shadow /= 96.0;
			*/

			// 8x8 kernel PCF
			float x,y;
			for (y = -3.5; y <= 3.5; y+=1.0)
				for (x = -3.5; x <= 3.5; x+=1.0)
					shadow += LookupShadow(vec2(x,y)) < shadowCoordinateWdivide.z ? 0.35 : 1.0;
					
			shadow /= 64.0;

			/*
			float x,y;
			for (y = -2.5; y <= 2.5; y+=1.0)
				for (x = -2.5; x <= 2.5; x+=1.0)
					shadow += LookupShadow(vec2(x,y)) < shadowCoordinateWdivide.z ? 0.35 : 1.0;
					
			shadow /= 32.0;
			*/

			// 4x4 kernel PCF
			/*
			float x,y;
			for (y = -1.5 ; y <=1.5 ; y+=1.0)
				for (x = -1.5 ; x <=1.5 ; x+=1.0)
					shadow += LookupShadow(vec2(x,y)) < shadowCoordinateWdivide.z ? 0.35 : 1.0;
		
			shadow /= 16.0;
			*/
		}


		// Normal map
		vec3 N = normalize(normals);
		vec3 L = normalize(lightDir);	
		float lambertTerm = dot(N,L);
	
		if(lambertTerm > 0.0)
		{
			shadow += (1.0 - shadow) * lightDecrease;
		}
		else
		{
			// If we are not facing the light, then we are definitely in shadow
			shadow = 0.35 + (0.65 * lightDecrease);
		}

		if(enableColourVariance)
		{
			vec4 noiseCol;
			if(gl_TexCoord[0].t <= 0.0)
			{
				noiseCol = vec4(gl_TexCoord[0].s, gl_TexCoord[0].s*0.5, 0.0, 1.0);
			}
			else
			{
				noiseCol = vec4(0.725*gl_TexCoord[0].s, 0.47*gl_TexCoord[0].s, 0.34*gl_TexCoord[0].s, 1.0)*0.5;
			}

			gl_FragData[0] = (vec4(gl_Color.x * shadow, gl_Color.y * shadow, gl_Color.z * shadow, gl_Color.w)+noiseCol)-actualLightDecrease;
		}
		else
		{
			gl_FragData[0] = vec4(gl_Color.x * shadow, gl_Color.y * shadow, gl_Color.z * shadow, gl_Color.w)-actualLightDecrease;
		}
	}
	else
	{
		if(enableColourVariance)
		{
			vec4 noiseCol;
			if(gl_TexCoord[0].t <= 0.0)
			{
				noiseCol = vec4(gl_TexCoord[0].s, gl_TexCoord[0].s*0.5, 0.0, 1.0);
			}
			else
			{
				noiseCol = vec4(0.725*gl_TexCoord[0].s, 0.47*gl_TexCoord[0].s, 0.34*gl_TexCoord[0].s, 1.0)*0.5;
			}

			gl_FragData[0] = (gl_Color+noiseCol)-actualLightDecrease;
		}
		else
		{
			gl_FragData[0] = gl_Color-actualLightDecrease;
		}
	}

	gl_FragData[1] = vec4(position.xyz,0);
	gl_FragData[2] = vec4(packedNormal,1.0);
}