uniform sampler2D Color0;   // diffuse color
uniform sampler2D Normal;   // eye space normal
uniform sampler2D Position; // eye space position
uniform sampler2D Color1;   // moon environment texture
uniform sampler2D Normal1;  // water bump
uniform float Timer;

varying vec3 eyePos;
varying vec4 projPos;
varying vec3 normal;
varying vec3 tangent;
varying vec3 binormal;
//varying vec3 taneye;
varying vec3 worldPos;
varying vec3 up;

//const vec3 waterColor = vec3( 0.0, 0.2, 0.6 );

//////////////////////////////////////////////////////////////////////////
// method to pack a f32 into an rgba8 from gamedev.net forums
//
// http://www.gamedev.net/community/forums/topic.asp?topic_id=463075
//
//////////////////////////////////////////////////////////////////////////

const vec4 bitSh = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);

// for schlick bias fn.
const float oneOverAMinusTwo = 1.85714;//1.0 / 0.7 - 2.0;

const float offsetX = 2.5 / 1024.0;
const float offsetY = 2.5 / 768.0;

const float scale = 0.0005;
void main()
{
  // compute projected position
  vec2 texCoord = projPos.xy / projPos.w * .5 + .5;
    
  // normalize eye vector
  vec3 e = normalize( eyePos );
  
  // want eye linear depth
  float pos = 1.0 - eyePos.z / 30000.0;
  float depth = ( dot( bitSh, texture2D( Position, texCoord ) ) );
  depth = 1.0 - abs( depth - pos );
  depth *= 10.0;
  // scale
  //depth = min( depth, 0.9 ) * 0.5 + 0.55;
  depth = min( depth, 1.0 );
  //depth = depth / ( oneOverAMinusTwo * ( 1.0 - depth ) + 1 );
  //depth = min( depth, 0.9 );
/**/
  // unpack normals
  vec3 tangentspacenormal = texture2D( Normal1, gl_TexCoord[0].st ).xyz;
  tangentspacenormal = tangentspacenormal * (255.0/128.0) - 1.0;
  //float surfaceBump  = surfaceNormal.z;
  // transform
  vec3 norm;
  vec3 t1 = normalize( tangent );
  vec3 b1 = normalize( binormal );
  vec3 n1 = normalize( normal );
  norm.x = dot( vec3( t1.x, b1.x, n1.x ), tangentspacenormal );
  norm.y = dot( vec3( t1.y, b1.y, n1.y ), tangentspacenormal );
  norm.z = dot( vec3( t1.z, b1.z, n1.z ), tangentspacenormal );

  vec3 n = norm;

  // look ups
  //vec2 wpos = vec2( Timer, Timer * 0.9 );
  vec2 wpos = worldPos.xz;
  wpos *= (1.0 - 0.1 * Timer);
  float wr = texture2D( Normal1, wpos * 0.1 ).r;
  float wg = texture2D( Normal1, wpos * 0.22 ).g;
  float wb = texture2D( Normal1, wpos * 0.047 ).b;

  n.x += wg - wr;
  n.z += wb - wr;
  n.y *= Timer;

  n = normalize( n );

  //texCoord.y -= n.z;
  
  // reflect
  vec3 r = reflect( -e, vec3( n.x*0.2, n.y, n.z*0.2 ) );
  //r.xz /= r.y; // scale
  //r.xz = 0.2;
  r = r * 0.5 + 0.5; // scale into [0,1]
  //r.z += n.z * scale; // offset
  r = clamp( r, 0.0, 1.0 );
  
  vec3 causticColor    = texture2D( Normal1, (gl_TexCoord[0].st + n.xy )* 0.5 ).rgb;
  float greyscale      = dot( causticColor, vec3( 0.3, 0.0, 0.4 ) );
  // colors
  vec3 bottomColor     = texture2D( Color0, texCoord.st ).xyz;
  //float causticApprox  = surfaceNormal.z;
  //bottomColor.rgb += vec3( causticApprox, causticApprox, causticApprox );
  bottomColor += 0.2 * causticColor;
  vec3 refractiveColor = mix( bottomColor, vec3( 0.0, 0.1, 0.2 ), depth );
  vec3 reflectiveColor = refractiveColor;//texture2D( Color1, worldPos.xz / 500.0 ).xyz;//

  float fresApprox = 1.0 - max( dot( -e, n ), 0.0 );//
  fresApprox*=0.2;

  // specular high light
  vec3 l = normalize( up );
  vec3 h = normalize( l + e );
  float ndotl = max( dot( n, l ), 0.0 );
  float ndoth = max( dot( n, h ), 0.0 );

  float spec = pow( ndoth, 64.0 );
  spec *= 0.33 * ndotl;

  vec3 color = mix( refractiveColor, reflectiveColor, fresApprox );//refractiveColor;//
  greyscale -= 0.5;
  greyscale *= 0.05;
  greyscale += spec;
  color += greyscale;
  

  // fake reflection
  /*
  vec4 outColor = vec4( color, depth );
  float luma       = dot( vec3( .299, .587, .114 ), outColor.rgb );
  vec3 reflect = vec3( 0.0, 0.0, 0.0 );
  vec2 ccoord = texCoord.st + ( outColor.rb / outColor.g * luma );
  reflect += texture2D( Color0, ccoord ).rgb;
  vec2 scoord = ccoord + vec2( -offsetX, -offsetY );
  reflect += texture2D( Color0, scoord ).rgb;
  scoord = ccoord + vec2( offsetX, -offsetY );
  reflect += texture2D( Color0, scoord ).rgb;
  scoord = ccoord + vec2( offsetX, offsetY );
  reflect += texture2D( Color0, scoord ).rgb;
  scoord = ccoord + vec2( -offsetX, offsetY );
  reflect += texture2D( Color0, scoord ).rgb;

  outColor.rgb += reflect * 0.2;
  outColor.rgb *= 0.5;
  //outColor.rgb *= texture2D( Color0, texCoord.st + ( outColor.rb / outColor.g * luma ) ).rgb;
  //outColor.rgb *= 0.5;
  
  gl_FragColor.rgb = mix( refractiveColor, outColor.rgb, fresApprox );//  outColor;//vec4( color, depth );
  gl_FragColor.a = depth;
  */

  gl_FragColor = vec4( color, depth );
}
