
#ifndef NUM_LIGHTS
	#define NUM_LIGHTS 2
#endif

#ifndef ADAPTIVE_STEPS
	#define ADAPTIVE_STEPS
#endif

#define WOBBLE

#define FOG

varying vec3 normal;
varying vec3 lightDir[NUM_LIGHTS];
varying vec3 eye;
varying float dist;
varying float camdot;

uniform sampler2D t_color;
uniform sampler2D t_disp;
uniform sampler2D t_normal;
//uniform sampler2D t_occlusion;
//uniform sampler2D t_specular;
uniform float parallaxHeight;
uniform float adaptiveSteps = 2.0;
uniform float extraLod = 25.0;
uniform float time;

void main(void) {
	vec3 e = normalize(eye);

	vec2 texcoord = (gl_TexCoord[0].xy);

	#ifdef WOBBLEASDF
		const float pi = 3.1415926535;
		float t = time;
		texcoord.x += 0.05*(sin(t*pi+gl_TexCoord[0].x*8.0+sin(t*pi*2.52+gl_TexCoord[0].y*16.0)*cos(t*pi*pi))+cos(gl_TexCoord[0].x*2+t*pi*2.369+sin(gl_TexCoord[0].y*4+t*pi*0.574+cos(t*pi*3.4+gl_TexCoord[0].x*gl_TexCoord[0].y))));
		texcoord.y += 0.05*(sin(t*pi+gl_TexCoord[0].y*16.0+cos(t*pi*2.52+gl_TexCoord[0].x*8.0)*sin(t*pi*pi))+sin(gl_TexCoord[0].x*2+t*pi*2.369+sin(gl_TexCoord[0].y*4+t*pi*0.574+sin(t*pi*3.4+gl_TexCoord[0].x*gl_TexCoord[0].y))));
	#endif

	float height = texture2D(t_disp, texcoord).r;

	// steep
	float lod = 1.0+extraLod*camdot;
	float numSteps = lod;
	numSteps = mix(numSteps*adaptiveSteps, numSteps, e.x);

	float fogEff = dist/gl_Fog.end*2.0;
	fogEff = clamp(pow(fogEff, 2.0), 0.0, 1.0);
	numSteps = mix(numSteps, 1.0, fogEff);

	float step = 1.0/numSteps;
	vec2 delta = vec2(-e.x,e.y)*parallaxHeight/(e.z*numSteps);
	float bheight = 1.0;
	int counter = 0;	// nvidia's vista drivers seem to crash because of too many iterations
	while (height < bheight && counter < 100) {
		bheight -= step;
		texcoord += delta;
		height = texture2D(t_disp, texcoord).r;
		counter++;
	}

	if (texcoord.x < 0 || texcoord.x > 1.0 || texcoord.y < 0 || texcoord.y > 1.0) {
		discard;
	}

	vec3 n = normalize(-1.0+2.0*texture2D(t_normal, texcoord).xyz);

	vec4 col = texture2D(t_color, texcoord);
	vec4 fambient = vec4(0.0);
	vec4 fdiff = vec4(0.0);
	vec4 fspec = vec4(0.0);

	float specmul = min((col.r+col.g+col.b)*4.0, 1.0);

	for (int i = 0; i < NUM_LIGHTS; i++) {
		vec3 l = normalize(lightDir[i]);
		float diff = dot(n, l);

		fambient += gl_LightSource[i].ambient;

		if (diff > 0.0) {
			fdiff += gl_LightSource[i].diffuse*diff;

			vec3 r = normalize(reflect(-l, n));

			fspec += specmul*(vec4(gl_LightSource[i].specular.xyz, 1.0)*pow(max(dot(r, e), 0.0), gl_LightSource[i].specular.w));
		}
	}

	vec4 final = fambient*col + fdiff*col + fspec;

	#ifdef FOG
		float  fogFactor = clamp((gl_Fog.end-gl_FogFragCoord)*gl_Fog.scale, 0.0, 1.0);
		final = mix(gl_Fog.color, final, fogFactor);
	#endif

	final.a = min(specmul, 1.0);

	gl_FragColor = final;
}
