varying vec3 position;
varying vec3 normal;
varying vec3 tangent;
varying vec3 binormal;
varying vec3 eye;
varying vec3 eyeTan;

uniform sampler2D reflectionMap;
uniform vec2 viewSize;
uniform float scrollTime;

uniform sampler2D normalMap1;
uniform sampler2D normalMap2;

const vec3 waterColor = vec3(0.1, 0.08, 0.0);

const float flowSpeed = 0.1;
const float textureScale = 0.25;
const float waveAmplitude = 0.7;
const float uvDistortion = 0.05;

const float fresnelPower = 2.0;
const float f0 = 0.1;

mat3 cotangentFrame(in vec3 N, in vec3 p, in vec2 uv)
{
    vec3 dp1 = dFdx(p);
    vec3 dp2 = dFdy(p);
    vec2 duv1 = dFdx(uv);
    vec2 duv2 = dFdy(uv);
    vec3 dp2perp = cross(dp2, N);
    vec3 dp1perp = cross(N, dp1);
    vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
    vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
    float invmax = inversesqrt(max(dot(T, T), dot(B, B)));
    return mat3(T * invmax, B * invmax, N);
}

void main(void)
{
    vec2 screenCoord = gl_FragCoord.xy / viewSize;
    
    vec3 dirToLight = normalize(gl_LightSource[0].position.xyz);
    vec3 eyeN = normalize(normal);
    vec3 eyeT = normalize(tangent);
    vec3 eyeB = normalize(binormal);
    vec3 L = vec3(dot(dirToLight, eyeT),
                  dot(dirToLight, eyeB),
                  dot(dirToLight, eyeN));
    
    vec3 N = eyeN;
    mat3 tangentToEye = cotangentFrame(N, position, gl_TexCoord[0].st);
    
    vec3 E = normalize(-position);
    
    vec2 uv = gl_TexCoord[0].st * textureScale;
    vec2 scrolluv1 = vec2(uv.s, uv.t + scrollTime * flowSpeed);
    vec2 scrolluv2 = vec2(uv.s + scrollTime * flowSpeed, uv.t);
    
    vec3 wave1N = normalize(texture2D(normalMap1, scrolluv1).rgb * 2.0 - 1.0);
    vec3 wave2N = normalize(texture2D(normalMap2, scrolluv2).rgb * 2.0 - 1.0);
    float fade = min(30.0, length(position)) / 30.0;
    N = mix(vec3(0.0, 0.0, 1.0), (wave1N + wave2N) * 0.5, waveAmplitude);
    N = mix(N, vec3(0.0, 0.0, 1.0), fade);
    vec2 noise = N.xy * uvDistortion;
    N = normalize(tangentToEye * N);
    
    vec2 projCoord = screenCoord + noise;
    projCoord = clamp(projCoord, 0.0, 1.0);
    
    vec3 reflectionColor = texture2D(reflectionMap, vec2(projCoord.x, 1.0 - projCoord.y)).rgb;
    
    float fresnel = f0 + pow(1.0 - dot(N, E), fresnelPower);
    
    vec3 color = mix(waterColor, reflectionColor, fresnel);
    float alpha = mix(0.8, 1.0, fresnel);
    
    gl_FragColor = vec4(color, alpha);
}
