//#extension GL_ARB_texture_rectangle : enable

//
uniform sampler2D cMap;
//uniform sampler2DRect cMap;

uniform sampler2D noiseMap;

///
uniform sampler2DShadow shadowMap;
///uniform sampler2D shadowMap; //DEBUG for light-dist plot

varying vec4 shadow_tex_coord;

//uniform sampler2D wMap; //waterheight
uniform sampler3D wave3D;

uniform samplerCube cubeMap;
varying vec4 eyedir;

uniform vec4 camPos;

uniform float texW;
uniform float texH;

uniform float ctexW;
uniform float ctexH;

uniform float slice_nr;

uniform vec2 texLookupScale;

uniform vec4 trans;
uniform vec4 scale;


uniform float waveScale;
uniform float waveOff;

//uniform vec4 cc;
uniform vec4 cc_below;

//
varying vec2 tc;

//varying float vertex_height;

varying vec3 worldpos_vert;

float water_height(vec2 pos2D)
{
  vec2 texCoords = texLookupScale.st*pos2D.xy;
  
  //float z = (texture3D(wave3D, vec3(texCoords.xy, 12.0*(slice_nr/16.0))).r * waveScale + waveOff);

  float z = (texture3D(wave3D, vec3(texCoords.xy, 12.0*(slice_nr/16.0)), -0.9).r * waveScale + waveOff);

    return z;
  
}

void main() 
{
  vec4 color;

  float eps = (waveScale+abs(waveOff));

  //    float water_h_highfrequ = (texture3D(wave3D, vec3(worldpos_vert.xz*4.25*texLookupScale.st, 18.0*(slice_nr/16.0))).r * waveScale + waveOff);
  //  float water_h_highfrequ = (texture3D(wave3D, vec3(worldpos_vert.xz*4.25*texLookupScale.st, 18.0*(slice_nr/16.0)), -1.25).r * waveScale + waveOff);
  //!  float water_h_highfrequ = (texture3D(wave3D, vec3(worldpos_vert.xz*3.0*texLookupScale.st, 18.0*(slice_nr/16.0)), -1.25).r * waveScale + waveOff);
  ///  float water_h_highfrequ = (texture3D(wave3D, vec3(worldpos_vert.xz*2.5*texLookupScale.st, 18.0*(slice_nr/16.0)), -1.25).r * waveScale + waveOff);
  float water_h_highfrequ = (texture3D(wave3D, vec3(worldpos_vert.xz*2.5*texLookupScale.st, 13.0*(slice_nr/16.0)), -1.25).r * waveScale + waveOff);


  ///NO EXTRA LOOKUP NEEDED  
float water_h = water_height(worldpos_vert.xz);


  if(worldpos_vert.y > water_h+eps) //part below the watersurface (refraction)
    {
      discard;
    }
  
  else
    {
      //approx
      //
  color = texture2D(cMap, tc*vec2(4.0/ctexW, 4.0/ctexH));
    color += ((texture2D(noiseMap, tc.xy*vec2(256.0/ctexW, 256.0/ctexH)).rrra-vec4(0.5,0.5,0.5,0.0))*vec4(.35, .35, .35, 1.0));

  float depth = max(0.0, water_h-worldpos_vert.y);

  float h_scale = .5;

  vec4 wat_col;

  wat_col.r = 0.3;
  wat_col.g = 0.53;
  wat_col.b = 0.56;


  wat_col.a = 1.0;
  //  wat_col.a = 0.75;

  //
  vec3 ivec = normalize(worldpos_vert - camPos.xyz);
  float dist = depth / ivec.y;

  
  float t = (water_h - worldpos_vert.y)/(-ivec.y);
  vec3 pos_cam_water_land;
  pos_cam_water_land.y = water_h;
  pos_cam_water_land.xz = worldpos_vert.xz - t*(ivec.xz);

  float dist_cam_in_water = distance(pos_cam_water_land, worldpos_vert.xyz);

  float dist_cam_in_water_mixfactor = clamp(pow(dist_cam_in_water*0.001125, 1.15), 0.0, 0.35);

  color = mix(color, wat_col, dist_cam_in_water_mixfactor);


  //  float caustic_factor = clamp(0.42*pow((water_h_highfrequ-waveOff)/waveScale, 3.0), 0.0, 1.0);
  float caustic_factor = clamp(0.42*pow((water_h_highfrequ-waveOff)/waveScale, 2.135), 0.0, 1.0);

    float mix_factor = 1.0-clamp(exp(-depth*0.004), 0.0, 1.0);

    vec3 mixcolor = mix(vec3(1.0, 1.0, 1.0), wat_col.rgb, mix_factor);


      color.xyz = mix(color.xyz, mixcolor, caustic_factor);


    //make deep water homogeneous

    float border = -20.0; //ORIG
    float val = (worldpos_vert.y/scale.y)-trans.y - border;
    //FIX WATER COLOR
    //// 
   color.xyz = mix( color.xyz, cc_below.xyz, mix_factor );

    //ALSO CHANGE THIS IN EZG.cpp
    //CUBEMAP BELOW
    //// color.xyz = mix( color.xyz, textureCube(cubeMap, eyedir.xyz), mix_factor );

    //GUESS BRIGHT AREAS IN CUBEMAP BELOW HORIZON
    /*
    vec4 usual_refr_color = mix( color.rgba, textureCube(cubeMap, eyedir.xyz), mix_factor );

    color.xyz = mix( usual_refr_color, textureCube(cubeMap, eyedir.xyz), length(textureCube(cubeMap, eyedir.xyz).rgb)*.5 );
    */

    //    color.xyz = mix( color.xyz, cc_below.xyz, 1.0 );

    //    color.xyz = mix(cc_below.xyz, color.xyz, min(max(10.1*val*(float(val<0.0)), 0.0), 1.0) );

    //    color = mix(color, wat_col, max(exp( (dist+depth) * 0.025), 0.001) );

    //  color = mix(color, wat_col, 1.0-dist * 0.01);
    //  color = mix(wat_col, color, exp(-dist * 0.001));
    //  color = mix(wat_col, color, exp(dist * 0.001));

    //  color = mix(wat_col, color, dist);

  //  color = mix(wat_col, color, exp(-dist * 0.001));
  //  color = mix(color, wat_col, exp(-dist * 0.00001));

    
    /*
    //this is what the shadowmap "covers" from the terrain
    in_shadow = float(
		      (shadow_tex_coord.x>=0.0)&&(shadow_tex_coord.x<1.0)&&
		      (shadow_tex_coord.y>=0.0)&&(shadow_tex_coord.y<1.0)&&
		      (shadow_tex_coord.z>0.0));
    */


   // SM stable!!!
   // 0 ... if the object is in shadow 
   // 1 ... if it is not in shadow
   //
   if(shadow_tex_coord.q > 0.0)
   //   if((shadow_tex_coord.q > 0.0) && (shadow_tex_coord.q < 1.0))
     {
   float in_shadow = shadow2DProj(shadowMap, shadow_tex_coord).x;
   //   color.rgb *= max(in_shadow, 0.8); //will still be 80% of original color, if in shadow!!!

   color.rgb *= max(in_shadow, 0.4);
     }

   //DEBUG - dist to cam
   //    color = texture2DProj(shadowMap, shadow_tex_coord).xxxx;

      ///SM+projTex      color = mix(color, texture2DProj(cMap, shadow_tex_coord)*max(1.0-((1.0-in_shadow)*(in_sm_frustum)), .5), in_sm_frustum);

     //     color.a=0.1;
     //
   gl_FragColor = color;


	//	gl_FragColor = cc_below;

     //    gl_FragColor = textureCube(cubeMap, eyedir.xyz);

    }
}
