#version 330

in vec3 vPos;
in vec3 vNormal;
in vec3 vEye;
in vec3 vSunPosition;
out vec4 OutColor;

uniform vec4 uDiffuse;
uniform vec3 uCameraPosition;
uniform vec3 uSunPosition;

uniform samplerCube uSkyboxSampler;
uniform sampler2D uNoiseSampler;

float CalcFresnel( vec3 inHalfway, vec3 inViewer, float inNormalReflectance )
{
	float base = 1.0 - max( 0.0, dot( inHalfway, inViewer ) );
	float exponential = pow( base, 5.0 );
	return inNormalReflectance + ( 1.0 - inNormalReflectance ) * exponential;
}

float CalcAltFresnel( float inNdotL, float inFresnelBias, float inFresnelPower )
{
	float facing = ( 1.0 - inNdotL );
	return max( inFresnelBias + ( 1.0 - inFresnelBias ) * pow( facing, inFresnelPower ), 0.0 );
}

void main()
{
	vec3 noiseOffset = vec3(0.0);
	noiseOffset += texture( uNoiseSampler, vPos.xy * 256.0 ).xyz * 0.5;
	noiseOffset += texture( uNoiseSampler, vPos.xy * 128.0 ).xyz * 0.25;
	noiseOffset += texture( uNoiseSampler, vPos.xy * 64.0 ).xyz * 0.125;
	noiseOffset += texture( uNoiseSampler, vPos.xy * 32.0 ).xyz * 0.0625;
	
	vec3 n = normalize( vNormal + (noiseOffset * 0.15) );
	vec3 v = normalize( -vEye );
	//vec3 v = normalize( uCameraPosition - vPos );
	vec3 l = normalize( vSunPosition - vEye );
	vec3 h = normalize( v + l );
	vec3 r = normalize( reflect( l, n ) );
	
	float specularCoefficient = 120.0;

	float dist = length( vPos - uCameraPosition );
	
	vec3 cAmb = vec3( 0.00 );
	vec3 cDiff = vec3( 0.0, 0.07, 0.13 ) * 0.5;//uDiffuse.rgb;
	vec3 cSpec = vec3( 1.0, 1.0, 1.0 );
	float diff = max( 0.0, pow( dot( n, l ) * 0.5 + 0.5, 2.0 ) );
	float spec = max( pow( max( 0.0, dot( n, h ) ), specularCoefficient ), 0.0 );
	
	float indexOfRefraction = 1.33;
	
	vec3 reflectDir = reflect(v, n);
	vec3 refractDir = refract(v, n, indexOfRefraction);
	
	float fresnelR0 = pow((1.0 - indexOfRefraction) / (1.0 + indexOfRefraction), 2.0);
	float reflectionCoefficient = fresnelR0 + ((1.0 - fresnelR0) * pow((1.0 - dot(h, v)), 5.0));
	float refractionCoefficient = 1.0 - reflectionCoefficient;
	
	vec3 waterColor = vec3( 0.52, 0.80, 0.98 ) * 0.5;//vec4( 0.00, 0.04, 0.08, 1.0 );
	vec4 reflectionColor = texture( uSkyboxSampler, reflectDir );
	//vec4 refractionColor = texture( uSkyboxSampler, refractDir ) * refractionCoefficient;
	vec4 refractionColor = mix(vec4(waterColor, 1.0), reflectionColor, 1.0 - refractionCoefficient);
	
	//vec3 waterColor = vec3( 0.0, 0.15, 0.115 );
	//vec3 waterColor2 = vec3( 0.03, 0.20, 0.43 ) * 1.0;
	
	OutColor = vec4( refractionColor.rgb * diff + reflectionColor.rgb * spec, 1.0 );
}