
#ifdef FLAG_NORMAL_MAP
varying vec3 lightVec, halfVec;
#endif

#ifdef FLAG_ENV_MAP
varying vec3 envReflect;

uniform mat4 envMatrix;
#endif

#ifdef FLAG_FOG
varying float fogDist;
#endif

uniform int n_lights;

vec4 lAmbient;
vec4 lDiffuse;
vec4 lSpecular;

vec3 eyePos, eyePos_N, Normal;

void add_light(int i)
{
	if(i <= n_lights)
	{
		vec3 lightPos = gl_LightSource[i].position.xyz;
		vec3 halfVec = lightPos - eyePos_N;
		float att = 1.0;
	
		if (gl_LightSource[i].position.w == 1.0) {
			lightPos -= eyePos;
			halfVec = gl_LightSource[i].halfVector.xyz;
	
			float spotEffect = 1.0;
	
			if (gl_LightSource[i].spotCutoff < 91.0) {
				spotEffect = dot(normalize(gl_LightSource[i].spotDirection), normalize(-lightPos));
	
				if (spotEffect < gl_LightSource[i].spotCosCutoff) {
					spotEffect = 0.0;
				}
			}
	
			att = spotEffect / (gl_LightSource[i].constantAttenuation + (gl_LightSource[i].linearAttenuation * length(lightPos)));
		}
	
		lAmbient += (gl_FrontLightProduct[i].ambient * att);
	
		float NdotL = max( dot(Normal, normalize(lightPos)), 0.0 );
		lDiffuse += ((gl_FrontLightProduct[i].diffuse * NdotL) * att);
	
		if (NdotL > 0.0) {
			float dotV = clamp( dot(Normal, normalize(halfVec)), 0.0, 1.0 );
			lSpecular += ((gl_FrontLightProduct[i].specular * pow(dotV, gl_FrontMaterial.shininess)) * att);
		}
	}
}

void main()
{
	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_Position = ftransform();

	// Transform vertex position into view space:
	vec4 viewPos = gl_ModelViewMatrix * gl_Vertex;
	eyePos = viewPos.xyz / viewPos.w;
	eyePos_N = normalize(eyePos);
	Normal = normalize(gl_NormalMatrix * gl_Normal);
	lAmbient = gl_FrontMaterial.emission + (gl_LightModel.ambient * gl_FrontMaterial.ambient);
	lDiffuse = vec4(0.0);
	lSpecular = vec4(0.0);

#ifdef FLAG_LIGHT
 #ifndef FLAG_NORMAL_MAP
	add_light(0);
 #endif
	add_light(1);
	add_light(2);
	add_light(3);
	add_light(4);
	add_light(5);
	add_light(6);
	add_light(7);

	clamp(lDiffuse, 0.0, 1.0);
	clamp(lSpecular, 0.0, 1.0);

	gl_FrontColor = lAmbient + lDiffuse;
	gl_FrontSecondaryColor = lSpecular;

 #ifdef FLAG_NORMAL_MAP
	// setup stuff for normal maps
	vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
	vec3 b = cross(Normal, t) * gl_MultiTexCoord1.w;

	mat3 TBN_matrix = mat3(t, b, Normal);

	vec3 lightPos = gl_LightSource[0].position.xyz;
	vec3 halfV = lightPos - eyePos_N;

	if (gl_LightSource[0].position.w == 1.0) {
		lightPos -= eyePos;
		halfV = gl_LightSource[0].halfVector.xyz;
	}

	lightVec = lightPos * TBN_matrix;
	halfVec = halfV * TBN_matrix;
 #endif

 #ifdef FLAG_ENV_MAP
	// used for env map
	envReflect = reflect(eyePos, Normal);
	envReflect = normalize( vec3(envMatrix * vec4(envReflect, 0.0)));
 #endif

#else
	gl_FrontColor = gl_Color;
#endif

#ifdef FLAG_FOG
	fogDist = clamp( (gl_Position.z - gl_Fog.start) * 0.75 * gl_Fog.scale, 0.0, 1.0 );
#endif

	// * grrrr ... stupid ATI ... *
#ifdef __GLSL_CG_DATA_TYPES
	gl_ClipVertex = viewPos;
#endif
}
