precision highp float;

uniform sampler2D SHADOW_MAP_SUN;
uniform mediump float SHADOW_MAP_SUN_VALUE;

varying vec4 lit_vertex_colour;

uniform highp float SHAD_BIAS;

varying vec4 sun_shadow_coord;
varying float cosTheta;

varying vec2 v_texture_coord;
uniform sampler2D texture;

float unpackValue(sampler2D map, vec4 coord)
{
  const vec4 unshift = vec4(1.0 / (256.0 * 256.0), 1.0 / (256.0), 1.0, 0.0);

  vec4 packed_value = texture2DProj(map, coord);
  float value = dot(packed_value, unshift);

  return value;
}

float normaliseShadowValue(sampler2D shadow_map, vec4 shadow_coord)
{
    float depth_value = unpackValue(shadow_map, shadow_coord);
    depth_value *= 2.0;
    depth_value -= 1.0;
    depth_value += SHAD_BIAS;
    return depth_value;
}

float unpackShadow(float value, sampler2D shadow_map, vec4 shadow_map_coord)
{
  float shadow_lightness = 1.0;
  if(value > 0.0)
  {
    float depth_value = normaliseShadowValue(shadow_map, shadow_map_coord);

    // Unpack distance value.
    if(depth_value < shadow_map_coord.z)
    {
      shadow_lightness = 1.0 - value;
    }

    // Depth texture
//    highp float depth = shadow_map_coord.z / shadow_map_coord.w;
//    highp float depth_light = texture2DProj(SHADOW_MAP_SUN, shadow_map_coord).r;
//
//    highp float bias = 0.005 * tan(acos(cosTheta));
//    bias = clamp(bias, 0.00001, 0.0175);
//    if(depth > depth_light + bias)
//        shadow_lightness = 1.0 - value;
  }

  return shadow_lightness;
}

void main()
{
  /* Draw main scene - read and compare shadow map. */
  float shadow_lightness = 1.0;
  shadow_lightness *= unpackShadow(SHADOW_MAP_SUN_VALUE, SHADOW_MAP_SUN, sun_shadow_coord);

  vec4 shadowed_colour = vec4(lit_vertex_colour.rgb * shadow_lightness, lit_vertex_colour.a);

  vec4 base_colour = texture2D(texture, v_texture_coord);
  gl_FragColor = base_colour * shadowed_colour;
}
