varying vec3 v_position;
varying vec3 v_normal;

uniform int num_lights = 2;
uniform bool enable_texture = false;
uniform bool enable_doubleside = false;
uniform bool enable_lighting = true;

uniform sampler2D tex_color;

uniform bool enable_envmap = false;
uniform sampler2D tex_envmap;

varying vec3 v_ref_view;
varying vec3 v_ref_normal;

uniform float env_reflection = 0.2;
uniform float tonemap_ratio = 1.0;


float PI = 3.14159265358979323846264;



vec4 GetPhongReflection(vec3 N, vec3 L, vec3 V, int light_idx)
{
	if(enable_doubleside)
	{
		if(!gl_FrontFacing)
			N = -N;
	}

	float LN = dot(L, N);
	if(LN <= 0.0)
		return vec4(0.0, 0.0, 0.0, 0.0);

	vec4 ref_diffuse = gl_FrontLightProduct[light_idx].diffuse * LN;

	vec4 br = ref_diffuse;

	vec3 H = normalize(L + V);
	float NH = dot(N, H);
	if(NH > 0.0)
	{
		float NHP = pow(NH, gl_FrontMaterial.shininess);

		vec4 ref_spec = gl_FrontLightProduct[light_idx].specular * NHP;
		br += ref_spec;
	}

	return br;
}

vec4 GetPhongReflectionSum(void)
{
	vec4 ret = vec4(0.0, 0.0, 0.0, 0.0);

	vec3 N = normalize(v_normal);

	for(int i = 0; i < num_lights; ++i)
	{
		vec3  light_xyz = gl_LightSource[i].position.xyz;
		float light_w   = gl_LightSource[i].position.w;
		vec3 L = normalize( light_xyz - v_position * light_w );
		vec3 V = normalize( -v_position );

		vec4 br = GetPhongReflection(N, L, V, i);

		ret += br;
	}

	vec4 ref_amb = gl_FrontMaterial.ambient * gl_LightModel.ambient;
	for(int i = 0; i < num_lights; ++i)
	{
		ref_amb += gl_FrontLightProduct[i].ambient;
	}

	ret += ref_amb;

	ret += gl_FrontMaterial.emission;

	ret.x = min(ret.x, 1.0);
	ret.y = min(ret.y, 1.0);
	ret.z = min(ret.z, 1.0);

	ret.w = gl_FrontMaterial.diffuse.w;

	if(enable_texture)
	{
		vec4 t_color = texture2DProj( tex_color , gl_TexCoord[0] );

		ret *= t_color;
	}

	return ret;
}


vec4 GetEnvironmentReflection()
{
	vec3 R = normalize(v_ref_normal * 2.0 - v_ref_view);
	//vec3 R = normalize(v_ref_normal);

	float ty = acos(R.y) / PI;

	float tx = atan(R.x, R.z) / (2.0 * PI) + 0.75;

	vec4 env_texcoord = vec4(tx, ty, 0.0, 1.0);
	vec4 ret = texture2DProj(tex_envmap, env_texcoord);
	ret *= tonemap_ratio;
	ret *= env_reflection;

	ret.w = 0.0;
	return ret;
}

vec4 GetConstantColor(void)
{
	if(enable_texture)
	{
		return gl_Color * texture2DProj(tex_color, gl_TexCoord[0]);
	}
	else
	{
		return gl_Color;
	}
}



void main (void)
{
	gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);

	if(enable_lighting)
		gl_FragColor += GetPhongReflectionSum();
	else
		gl_FragColor += GetConstantColor();

	if(enable_envmap)
		gl_FragColor += GetEnvironmentReflection();
}
