uniform sampler2D depthTex;	// depth texture
uniform sampler2D normalTex; // normal tex
uniform sampler2D BGTex; // relected background

uniform int NUM_SAMPLES;

varying vec2 	texCoord;
varying vec2	VPOS;

uniform vec4	TM0,
				TM1,
				TM2,
				TM3;

vec4 decode(vec4 enc)
{
    vec2 fenc = enc.xy*4.0-2.0;
    float f = dot(fenc,fenc);
    float g = sqrt(1.0-f/4.0);
    vec4 n;
    n.xy = fenc.xy*g;
    n.z = 1.0-f/2.0;
	n.w=enc.w;
    return n;
}

vec4 getSSpos(vec4 pos)
{
	vec4 sspos;
		
	// compute texture space beam pos
	sspos.x = dot(pos,TM0);
	sspos.y = dot(pos,TM1);
	sspos.w = dot(pos,TM3);
	sspos.xy=sspos.xy/sspos.w;
	sspos.xy=vec2(1.0-sspos.x,1.0-sspos.y);
				
	//compare z
	sspos.z=texture2D( depthTex, sspos.xy ).x;
	return sspos;
}

void main(void)
{	
	// compute eye space position
	vec4 pos = texture2D(depthTex,texCoord.st);
	pos.xy=VPOS.xy*-pos.z;
	pos.w=1.0;
	
	float t=0.0;
	vec4 reflColor=vec4(0.0,0.0,0.0,0.0);	
	int found=0;
	
	if(-pos.z<NUM_SAMPLES*20.0)
	{
		// get normal
		vec4 normal = decode(texture2D(normalTex,texCoord.st));
			
		// get eyedir
		vec3 eye=normalize(pos.xyz);
		
		// compute reflected vector
		vec3 reflected=reflect(eye,normal.xyz);

		// compute reflected color
		if(reflected.z<-0.2)
		{
			t=-reflected.z;
			t=(t-0.2)/0.1;
			t=clamp(t,0.0,1.0);
			
			vec4 sspos;
			vec2 expUV;
			
		//	reflected*=20;
			
			vec4 curpos;
			int i=0;
			int j=NUM_SAMPLES*20;
			int m;
		
			do
			{
				m=(i+j)/2;
				curpos.xyz=pos.xyz+(reflected*m);
				sspos=getSSpos(curpos);
				
				if(curpos.z<=sspos.z+5.0 && curpos.z>=sspos.z-5.0)
				{
					expUV=abs((sspos.xy-vec2(0.5))*vec2(2.0));	
					t*= 1.0-clamp((expUV.x-0.8)*5.0,0.0,1.0);
					t*=	1.0-clamp((expUV.y-0.8)*5.0,0.0,1.0);
					
					if(sspos.x>=1.0)
						break;
					if(sspos.x<=0.0)
						break;
					if(sspos.y>=1.0)
						break;
					if(sspos.y<=0.0)
						break;
						
					reflColor=texture2D( BGTex, sspos.xy );
					found=1;
					break;
				}
				else
				{
					if(curpos.z>sspos.z/*+10.0*/)
						i=m+1;
					else
						j=m-1;
				}
			}
			while(i<=j);
			
		/*	if(!found)
			{
				// try linear
				for(int i=0; i < NUM_SAMPLES; i++)
				{
					pos.xyz+=reflected;
				
					// compute texture space beam pos
					sspos.x = dot(pos,TM0);
					sspos.y = dot(pos,TM1);
					sspos.w = dot(pos,TM3);
					sspos.xy=sspos.xy/sspos.w;
					sspos.xy=vec2(1.0-sspos.x,1.0-sspos.y);
					
					//compare z
					sspos.z=texture2D( depthTex, sspos.xy ).x;
					if(pos.z<sspos.z+10.0 && pos.z>sspos.z-10.0)
					{
						expUV=abs((sspos.xy-vec2(0.5))*vec2(2.0));	
						t*= 1.0-clamp((expUV.x-0.8)*5.0,0.0,1.0);
						t*=	1.0-clamp((expUV.y-0.8)*5.0,0.0,1.0);
						
						if(sspos.x>=1.0)
							break;
						if(sspos.x<=0.0)
							break;
						if(sspos.y>=1.0)
							break;
						if(sspos.y<=0.0)
							break;
							
						reflColor=texture2D( BGTex, sspos.xy );
						reflColor.a=1.0;
						break;
					}
				}
			}*/
		}	
	}

	gl_FragColor = reflColor*t;
}