varying vec2 TexCoord0;
varying vec4 ViewCoords;
varying vec3 LightDir, HalfVec;

uniform vec2 Eng_ObjID;
uniform sampler2D DiffuseMap;
uniform sampler2D NormalsAndSpecularMap;
uniform sampler2D Eng_EnvScreenShadows;
uniform float Shine;
uniform float SpecularLevel; 

#ifdef _EngDef_ShadowsEnabled
const float sd = 1.0 / _EngDef_ShadowsScreenTextureSize;

bool compareID(in vec2 I1, in vec2 I2)
{
	return (abs((I1.x*255.0) - I2.x) < 0.5) && (abs((I1.y*255.0) - I2.y) < 0.5);
}

vec4 getShadow(in vec2 C)
{
	float ret = 0.0;
	vec4 shadow = texture2D(Eng_EnvScreenShadows, C + vec2(-sd, -sd));
	ret = compareID(shadow.gb, Eng_ObjID) ? shadow.r: 1.0;

	shadow = texture2D(Eng_EnvScreenShadows, C + vec2(sd, -sd));
	ret = min(ret, compareID(shadow.gb, Eng_ObjID) ? shadow.r: 1.0);

	shadow = texture2D(Eng_EnvScreenShadows, C + vec2(sd, sd));
 	ret = min(ret, compareID(shadow.gb, Eng_ObjID) ? shadow.r: 1.0);

	shadow = texture2D(Eng_EnvScreenShadows, C + vec2(-sd, sd));
	ret = min(ret, compareID(shadow.gb, Eng_ObjID) ? shadow.r: 1.0);

	return vec4(ret);
}
#endif

void main()
{
#ifdef _EngDef_ShadowsEnabled
    vec2 ShadowCoords = ((ViewCoords.xy / ViewCoords.w) + 1.0) * 0.5;
	vec4 shadow = getShadow(ShadowCoords);
#else
	vec4 shadow = vec4(1.0);
#endif
	    
	vec4 NormalAndSpecular = texture2D(NormalsAndSpecularMap, TexCoord0);
	vec3 Normal = normalize((NormalAndSpecular.xyz - 0.5) * 2.0);

	float NdotHV = max(0.0, dot(Normal, normalize(HalfVec)));
    
	vec4 Diffuse = max(0.0, dot(normalize(LightDir), Normal)) * gl_LightSource[0].diffuse * shadow.r;
	vec4 Ambient = gl_LightSource[0].ambient;
	vec4 Specular = pow(NdotHV, Shine) * gl_LightSource[0].specular * shadow.r;

	gl_FragColor = texture2D(DiffuseMap, TexCoord0) * (Diffuse + Ambient) + Specular * NormalAndSpecular.a * SpecularLevel;
}
