#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D texUnit0;
uniform sampler2D texUnit1;
uniform sampler2D texUnit2;
uniform mat4 mv_matrix;
uniform mat4 mat4_slot_1;
varying vec3 N;
varying vec3 V; 
varying vec2 v_texcoord;
varying vec3 eye_dir;
varying float eye_length; 


vec2 parallaxMapping(in vec3 V, in vec2 T, out float parallaxHeight)
{
   // determine optimal number of layers
   const float minLayers = 10.0; //10
   const float maxLayers = 45.0; //35
   
	float e_l = (1.0-(eye_length * 1.5));
	e_l = e_l < 0.01 ? 0.01 : e_l; //prevent becomming zero
   float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0.0, 0.0, 1.0), normalize(V)))) * e_l;

   // height of each layer
   float layerHeight = 1.0 / numLayers;
   // current depth of the layer
   float curLayerHeight = 0.0;
   // shift of texture coordinates for each layer
   float parallaxScale = 0.00; //the higher, the more it comes out
   vec2 dtex = parallaxScale * V.xy / V.z / numLayers;

   // current texture coordinates
   vec2 currentTextureCoords = T;

   // depth from heightmap
   float heightFromTexture = texture2D(texUnit2, currentTextureCoords).r;

   // while point is above the surface
   while(heightFromTexture > curLayerHeight) 
   {
      // to the next layer
      curLayerHeight += layerHeight; 
      // shift of texture coordinates
      currentTextureCoords -= dtex;
      // new depth from heightmap
      heightFromTexture = texture2D(texUnit2, currentTextureCoords).r;
   }

   // previous texture coordinates
   float texStep = 0.001; //0.1
   vec2 prevTCoords = currentTextureCoords + texStep;

   // heights for linear interpolation
   float nextH	= heightFromTexture - curLayerHeight;
   float prevH	= texture2D(texUnit2, prevTCoords).r
                           - curLayerHeight + layerHeight;

   // proportions for linear interpolation
   float weight = nextH / (nextH - prevH);

   // interpolation of texture coordinates
   vec2 finalTexCoords = prevTCoords * weight + currentTextureCoords * (1.0-weight);

   // interpolation of depth values
   parallaxHeight = curLayerHeight + prevH * weight + nextH * (1.0 - weight);

   // return result
   return finalTexCoords;
}

void main (void)  
{  
		float disp_bias = -0.02;
		float disp_scale = 0.08;
		//vec2 texCoords = v_texcoord + (eye_dir.xy * (texture2D(texUnit2, v_texcoord.xy).r * disp_scale + disp_bias));
		float parallaxHeight;
	//	vec2 texCoords = parallaxMapping(eye_dir, v_texcoord.xy, parallaxHeight);
		vec2 texCoords = v_texcoord.xy;
		
		if(texture2D(texUnit0, texCoords)[3]<0.5) discard;
		vec3 E = normalize(-V); 
		vec3 L;
		//calculate Ambient Term:  
		vec4 Iamb = vec4(0.2,0.2,0.2,1.0); 
			
		vec4 light0, light1, light2;
		for(int i=0; i<3; i++)
		{	
			if(i==0)
			//	L = normalize((mat4_slot_1[0]).xyz - (V*mat4_slot_1[3].x)); 
				L = normalize(vec3(0.0,40.5,0.0) - (V*mat4_slot_1[3].x)); 			
			else if(i==1)
				L = normalize((mat4_slot_1[1]).xyz - (V*mat4_slot_1[3].x)); 
			else
				L = normalize((mat4_slot_1[2]).xyz - (V*mat4_slot_1[3].x)); 
			
			vec3 R = normalize(-reflect(L,N));  
		
			//calculate Diffuse Term:  
			vec4 Idiff = vec4(0.1,0.1,0.1,1.0) * max(dot(N,L), 0.0) * texture2D(texUnit2, texCoords.xy)* texture2D(texUnit2, texCoords.xy)*5.0;
			Idiff = clamp(Idiff, 0.0, 1.0);     
		   
			// calculate Specular Term:
			vec4 Ispec = vec4(0.03,0.03,0.03,1.0)
						* pow(max(dot(R,E),0.0),20.0); 
			vec4 Ispec_tex = texture2D(texUnit2, texCoords.xy) * texture2D(texUnit2, texCoords.xy)*40.0;
			Ispec = vec4(Ispec.x * Ispec_tex.x, Ispec.y *Ispec_tex.y, Ispec.z *Ispec_tex.z,1.0); 
			Ispec = clamp(Ispec, 0.0, 1.0); 
			// write Total Color: 
			float intensity=clamp(dot(L,N),0.0,1.0);
			
			if(i==0)
				light0 = (vec4(intensity,intensity,intensity,1.0)*0.6)+Ispec + Idiff;
			else if(i==1)
				light1 = (vec4(intensity,intensity,intensity,1.0)*mat4_slot_1[1].w)+Ispec + Idiff;
			else
				light2 = (vec4(intensity,intensity,intensity,1.0)*mat4_slot_1[2].w)+Ispec + Idiff;
		}		
		gl_FragColor = (light0+light1+light2+Iamb)*texture2D(texUnit0, texCoords);
	//	gl_FragColor = texture2D(texUnit0, v_texcoord);
/*	if(eye_length>0.0)
	gl_FragColor = vec4(1,0,0,1);
	if(eye_length>0.3)
	gl_FragColor = vec4(0,1,0,1);
	if(eye_length>0.5)
	gl_FragColor = vec4(0,0,1,1);
	if(eye_length>1.0)
	gl_FragColor = vec4(1,0,1,1);
*/		
}

