varying vec3 frontLighting;
varying vec3 backLighting;
varying vec3 frontSpecular;
varying vec3 backSpecular;
varying vec3 eyePos;
varying vec2 texCoord;

uniform vec3 ambientColor;
uniform float emission;
uniform sampler2D diffuse1;
uniform vec2 scale1;

uniform float mistEnable;
uniform float mistStart;
uniform float mistDistance;
uniform float mistIntensity;
uniform float mistType;
uniform vec3 mistColor;

// ########################################Functions########################################

float linearrgb_to_srgb(float c)
{
    if(c < 0.0031308)
        return (c < 0.0) ? 0.0: c * 12.92;
    else
        return 1.055 * pow(c, 1.0/2.4) - 0.055;
}

float srgb_to_linearrgb(float c)
{
	if(c < 0.04045)
		return (c < 0.0) ? 0.0: c * (1.0 / 12.92);
	else
		return pow((c + 0.055)*(1.0/1.055), 2.4);
}

vec3 linearrgb_to_srgb(vec3 col_from)
{
    vec3 col_to;
    col_to.r = linearrgb_to_srgb(col_from.r);
    col_to.g = linearrgb_to_srgb(col_from.g);
    col_to.b = linearrgb_to_srgb(col_from.b);

    return col_to;
}

vec3 srgb_to_linearrgb(vec3 col_from)
{
    vec3 col_to;
	col_to.r = srgb_to_linearrgb(col_from.r);
	col_to.g = srgb_to_linearrgb(col_from.g);
	col_to.b = srgb_to_linearrgb(col_from.b);
    
    return col_to;
}

vec3 shade_mist_blend(vec3 co, float enable, float miststa, float mistdist, float misttype, float intensity, vec3 col1, vec3 col2)
{
	float mist = 0.0;
	if(enable == 1.0) 
	{
		float fac, zcor;

		zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
		
		fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
		if(misttype == 0.0) fac *= fac;
		else if(misttype == 1.0);
		else fac = sqrt(fac);

		mist = 1.0 - (1.0 - fac) * (1.0 - intensity);
	}
		
	float mixFac = clamp(mist, 0.0, 1.0);
	vec3 result = mix(col1, col2, mixFac);
	
	return result;
}

// ########################################Main-Function########################################

void main()
{	 
    vec2 ofs = (1.0 - scale1) / 2.0;
    vec4 dif1 = texture2D(diffuse1, texCoord*scale1+ofs);
    dif1.rgb = srgb_to_linearrgb(dif1.rgb);
    vec4 color = dif1;
	
	if (gl_FrontFacing)
    {
        color.rgb = (emission * dif1.rgb) + ambientColor + (frontLighting * dif1.rgb) + frontSpecular; 
    }
    else
    {
        color.rgb = (emission * dif1.rgb) + ambientColor + (backLighting * dif1.rgb) + backSpecular; 
    } 	
	color.rgb = shade_mist_blend(eyePos, mistEnable, mistStart, mistDistance, mistType, mistIntensity, color.rgb, mistColor);
    
    color.rgb = linearrgb_to_srgb(color.rgb);
	gl_FragColor = color;
}