#version 330

in vec3 vNormal;
in vec3 vEye;
in vec2 vTexCoord;

out vec4 OutColor;

uniform vec3 uLightPos;
uniform vec4 uDiffuse;

uniform sampler2D uNoiseTexSampler;

uniform samplerCube uSkyboxSampler;

in vec2 vTimeOffset;
in float vHeight;

vec3 CalcNormal( sampler2D inTexSampler, vec2 inCoord, int inComponent )
{
	float texOffset = 1.0 / 2048.0;
	float centerSample = texture( inTexSampler, inCoord ).w;
	float topSample = texture( inTexSampler, inCoord + vec2( 0.0, texOffset ) + vTimeOffset )[inComponent];
	float bottomSample = texture( inTexSampler, inCoord + vec2( 0.0, -texOffset ) + vTimeOffset )[inComponent];
	float leftSample = texture( inTexSampler, inCoord + vec2( -texOffset, 0.0 ) + vTimeOffset )[inComponent];
	float rightSample = texture( inTexSampler, inCoord + vec2( texOffset, 0.0 ) + vTimeOffset )[inComponent];
	
	return vec3( rightSample - leftSample, topSample - bottomSample, centerSample );
}

void main()
{
	vec3 normal1 = CalcNormal( uNoiseTexSampler, vTexCoord, 0 );
	vec3 normal2 = CalcNormal( uNoiseTexSampler, vTexCoord, 1 );
	vec3 normal3 = CalcNormal( uNoiseTexSampler, vTexCoord, 2 );
	vec3 normal4 = CalcNormal( uNoiseTexSampler, vTexCoord, 3 );
	
	vec3 normal = normalize( ( normal1 + normal2 + normal3 + normal4 ) / 4.0 );//normal1 * 0.125 + normal2 * 0.125 + normal3 * 0.25 + normal4 * 0.5;
	
	// All this normalization is extremely wasteful... Fix this.
	vec3 n = normalize( (normal4 + normal3) / 2.0 );
	vec3 v = normalize( -vEye );
	vec3 l = normalize( uLightPos - vEye );
	vec3 h = normalize( v + l );
	
	float specularCoefficient = 120.0;

	vec3 cAmb = vec3( 0.0 );
	vec3 cDiff = uDiffuse.rgb;
	vec3 cSpec = vec3( 1.0, 1.0, 1.0 );
	float diff = max( 0.0, dot( n, l ) );
	float spec = max( pow( ( dot( n, h ) ), specularCoefficient ), 0.0 );
	
	vec3 eyeDir = normalize( vEye );
	vec3 reflDir = normalize( reflect( eyeDir, normal ) );
	
	vec4 reflectionColor = texture( uSkyboxSampler, reflDir ) * 0.75;
	
	float waterRefractionIndex = 1.33;
	float airRefractionIndex = 1.00;
	float parallelReflectionCoeff = pow( ( airRefractionIndex - waterRefractionIndex ) / ( airRefractionIndex + waterRefractionIndex ), 2.0 );
	float reflCoeff = parallelReflectionCoeff + ( 1.0 - parallelReflectionCoeff ) * pow( ( dot( h, v ) ), 5.0 );
	
	vec3 waterColor = vec3( 0.0, 0.15, 0.115 );
	//vec3 waterColor = vec3( 0.00, 0.00, 0.02 );
	vec3 reflColor = ( reflectionColor.xyz * reflCoeff );
	vec3 finalColor = ( reflColor + waterColor * ( 1.0 - reflCoeff ) ) * 0.75;
	vec3 lightColor = cAmb + cDiff*diff + cSpec*spec;
	
	OutColor = vec4( mix( finalColor, lightColor, 0.0 ), 1.0 );
}