
#ifndef NUM_LIGHTS
	#define NUM_LIGHTS 1
#endif

#define ADAPTIVE_STEPS

#define FOG

#define REFLECTION

varying vec3 normal;
varying vec3 lightDir[NUM_LIGHTS];
varying vec3 eye;
varying float camdot;
varying vec3 pos;
varying vec3 tn, tt, tb;

uniform sampler2D t_height;
uniform float texscale;
uniform float parallaxHeight;
uniform float texSize;// = 1024.0;
uniform sampler2D seedTex;
//uniform samplerCube cubemap;
uniform float seedtime;
uniform float znear;
uniform float zfar;

float getHeight(vec2 texcoord) {
	vec4 col = texture2D(seedTex, texcoord);
	float h = (col.r-0.5)*sin(seedtime) + (col.g-0.5)*cos(seedtime);
	h += 0.25*((col.b-0.5)*sin(seedtime*3.0) + (col.a-0.5)*cos(seedtime*3.0));

	return 0.5+0.35*h;
}

vec3 getBumpNormal(sampler2D height, vec2 xy) {
	float o = texture2D(height, xy).r;

/*	float h = texture2D(height, xy+vec2(1.0/texSize, 0.0)).r;
	float v = texture2D(height, xy+vec2(0.0, 1.0/texSize)).r;
	float dh = o-h;
	float dv = o-v;*/

	float x0 = texture2D(height, xy+vec2(-1.0/texSize, 0.0)).r;
	float x2 = texture2D(height, xy+vec2( 1.0/texSize, 0.0)).r;
	float y0 = texture2D(height, xy+vec2(0.0, -1.0/texSize)).r;
	float y2 = texture2D(height, xy+vec2(0.0,  1.0/texSize)).r;
/*	float texmul = 4.0;
	float x0 = getHeight(xy+vec2(-1.0/texSize*texmul, 0.0)).r;
	float x2 = getHeight(xy+vec2( 1.0/texSize*texmul, 0.0)).r;
	float y0 = getHeight(xy+vec2(0.0, -1.0/texSize*texmul)).r;
	float y2 = getHeight(xy+vec2(0.0,  1.0/texSize*texmul)).r;*/
	float dh = x0-x2;
	float dv = y0-y2;

	return normalize(vec3(dh, parallaxHeight*4.0, dv));
//	return normalize(vec3(0.0, 0.0, 0.0));
//	return vec4(n, o);
}

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

	#ifdef ADAPTIVE_STEPS
		float lod = 2.0+30.0*camdot;
	#else
		float lod = 5.0;
	#endif

//	const float texscale = 1.0;
	vec2 texcoord = gl_TexCoord[0].xy*texscale;
	// get normal and initial height
/*	vec4 nh = getBumpNormal(t_height, texcoord);
	float height = nh.w;*/
	float height = texture2D(t_height, texcoord).r;
//	float height = getHeight(texcoord).r;

	// steep
	//float numSteps = 5.0;
	float numSteps = lod;
	numSteps = mix(numSteps*2.0, numSteps, e.x);
	float step = 1.0/numSteps;
	vec2 delta = vec2(-e.x,e.z)*parallaxHeight/(e.y*numSteps)*texscale;
	float bheight = 1.0;
	int counter = 0;
	while (height < bheight && counter < 100) {
		bheight -= step;
		texcoord += delta;
		height = texture2D(t_height, texcoord).r;
		counter++;
//		height = getHeight(texcoord).r;
	}


//	vec3 n = normalize(-1.0+2.0*texture2D(t_normal, texcoord).xyz);
	vec3 n = getBumpNormal(t_height, texcoord);
//	n = normalize(gl_NormalMatrix*n);
//	n = gl_TextureMatrix[0]*n;
//	vec3 n = normalize(normal);
//	n = normalize(gl_NormalMatrix*n);

//	vec4 col = texture2D(t_height, texcoord);
//	vec4 col = vec4(0.1, 0.15, 0.75, 1.0)*0.5+texture2D(t_height, texcoord)*0.5;
	#ifdef REFLECTION
/*		vec3 r = normalize(reflect(-e, n));
		r = vec3(dot(r, vec3(tt.x, tn.x, tb.x)), dot(r, vec3(tt.y, tn.y, tb.y)), dot(r, vec3(tt.z, tn.z, tb.z)));
		r.z = -r.z;
		vec4 col = textureCube(cubemap, r);*/
	#else
		vec4 col = vec4(0.75, 0.55, 0.95, 1.0);
	#endif
	vec4 final = vec4(0.0);
	vec4 fambient = vec4(0.0);
	vec4 fdiff = vec4(0.0);
	vec4 fspec = vec4(0.0);

	for (int i = 0; i < NUM_LIGHTS; i++) {
		vec3 l = normalize(lightDir[i]);

		vec3 puoli = normalize(e+l);

		float diff = dot(n, l);

		fambient += gl_LightSource[i].ambient;

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

			vec3 r = reflect(-l, n);
//			fspec += vec4(gl_LightSource[i].specular.xyz, 1.0)*pow(max(dot(r, e), 0.0), gl_LightSource[i].specular.w);*/
			fspec += vec4((gl_LightSource[i].specular.xyz, 1.0)*pow(max(dot(puoli, n), 0.0), gl_LightSource[i].specular.w),
			              (gl_LightSource[i].specular.xyz, 1.0)*pow(max(dot(puoli, n), 0.0), gl_LightSource[i].specular.w),
			              (gl_LightSource[i].specular.xyz, 1.0)*pow(max(dot(puoli, n), 0.0), gl_LightSource[i].specular.w),
			              1.0);
		}

		float ev = dot(e, n);
/*		fspec = vec4(fspec.r*cos(ev*160.438945),
		             fspec.g*cos(ev*200.458933),
		             fspec.b*cos(ev*360.859439), 1.0);*/
	}


/*	vec3 p = pos;
	p.z -= normalize(p).z*(1.0-bheight)/-e.y*200.0;	// hattuvakio
	vec2 planes = vec2(-zfar/(zfar-znear), -zfar*znear/(zfar-znear));
	gl_FragDepth = ((planes.x*p.z+planes.y)/-p.z);*/

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


	gl_FragColor = /*fambient*col*/ /*+ fdiff*col */+ /*col**/fspec;
//	gl_FragColor = fdiff*col;
//	gl_FragColor = dot(normalize(lightDir[0]), n);
//	gl_FragColor.xyz = lightDir[0];
//	gl_FragColor = dot(normalize(lightDir[0]), normalize(normal));
//	gl_FragColor = vec4(0.5+0.5*n, 1.0)*vec4(1.0, -1.0, 1.0, 1.0);
//	gl_FragColor.xyz = 0.5+0.5*n.xyz;
//	gl_FragColor = col;
}
