#version 400

//texturing
uniform int textureCoordGenMode; // 0 - no generating, 1 - object space, 2 - eye space, 3 - sphere
uniform int textureMode;         // 0 - no texture, 1 - replace, 2 - decal, 3 - blend, 4 - add, 5 - interpolate, 6 - modulate
uniform int alphaTest = 0;		 // alpha testing
uniform bool cubeMap = false;    // environment map enabled
uniform sampler2D texture0;
uniform samplerCube environmentMap;

//material
struct Material
{
	float type; 
	vec4  diffuse;
	vec4  specular;
	float shininess;
};
uniform Material material;

smooth in vec3 VS_Normal;
smooth in vec3 VS_View;
smooth in vec2 VS_TexCoord;

layout(location = 0) out vec4 normalOut;
layout(location = 1) out vec4 materialInfoOut; //ID (0.1 - reflective, 0.2 - phong, 0.3 - shader), shininess, free, free
layout(location = 2) out vec4 diffuseOut;
layout(location = 3) out vec4 specularOut;

vec2 spheremapEnc(vec3 n)
{
  vec2 ret = normalize(n.xy) * sqrt(-n.z * 0.5 + 0.5);
  return ret * 0.5 + 0.5;
}

void main()
{
	vec3 N = normalize(VS_Normal);
	normalOut.xy = spheremapEnc(N);
	materialInfoOut = vec4(material.type, material.shininess*0.003921569, 0.0, 0.0);  // a * 0.003921569 == a / 255

	//diffuse color
	vec4 color;
	if(textureCoordGenMode != 2 && !cubeMap)
		color = texture(texture0, VS_TexCoord);
	else if(cubeMap)
		color = texture(environmentMap, reflect(normalize(VS_View), N));
	else
		color = textureProj(texture0, gl_FragCoord);

	switch(textureMode)
	{
		case 0:
			diffuseOut = material.diffuse;
			break;
		case 1:
			diffuseOut = color;
			break;
		case 2:
		{
			diffuseOut = vec4(color.rgb * color.a, 1.0);
			diffuseOut += material.diffuse * (1 - color.a);
			diffuseOut.a = material.diffuse.a;		
			break;
		}
		case 3:
		{
			diffuseOut = material.diffuse * (1 - color) + color;
			diffuseOut.a = material.diffuse.a * color.a;
			break;
		}
		case 4:
		{
			diffuseOut = clamp(material.diffuse +  color, 0.0, 1.0);
			diffuseOut.a = material.diffuse.a * color.a;
			break;
		}
		case 5:
			diffuseOut = mix(material.diffuse, color, color.a);
			break;
		default:
			diffuseOut = material.diffuse * color;
	}

	if(alphaTest == 1 && diffuseOut.a < 0.5)
		discard;

	specularOut = material.specular;
}
