#version 120

uniform sampler2D tex0;
uniform sampler2D tex1;

uniform sampler2D texFractal0;
varying vec2 texFractal0Coords;

const int GL_LINEAR = 9729;
const int GL_EXP = 2048;

const int GL_ONE = 1;
const int GL_ONE_MINUS_SRC_ALPHA = 771;

uniform float ticks;
uniform int worldTime;

uniform int fogMode;
uniform int lightmapEnabled;
uniform int texture2DEnabled;
uniform int blendFunc;
uniform vec4 overrideColor;
uniform int renderMode; //0 = default, 1 = item effect, 2 = item effect backwards

uniform int fractal0TexIndex;

uniform float alcohol;
uniform float weed;
uniform float redshrooms;
uniform float brownshrooms;
uniform float tobacco;
uniform float cocaine;

uniform vec3 playerPos;

varying vec3 normalVector;

uniform int glLightEnabled;
uniform float glLightAmbient;
uniform vec3 glLightPos0;
uniform vec2 glLightStrength0;
uniform vec3 glLightPos1;
uniform vec2 glLightStrength1;

vec3 getRotatedColor(vec3 color, float rot)
{
	vec3 returnColor = vec3(0);
	
	for(int i = 0; i < 3; i++)
	{
        float colorAffected = mod(float(i) + rot * 3.0, 3.0);
        
        int col1 = int(floor(colorAffected));
        
        returnColor[col1] += color[i] * (1.0 - (colorAffected - float(col1)));
        returnColor[int(mod(float(col1 + 1), 3.0))] += color[i] * (colorAffected - float(col1));
	}
    
	return returnColor;
}

vec3 getIntensifiedColor(vec3 color)
{
    float s = 2.0;
    float cR = 0.3086;
    float cG = 0.6084;
    float cB = 0.0820;
    
    float rr = (1.0 - s) * cR + s;
    float rg = (1.0 - s) * cG;
    float rb = (1.0 - s) * cB;
    float gr = (1.0 - s) * cR;
    float gg = (1.0 - s) * cG + s;
    float gb = (1.0 - s) * cB;
    float br = (1.0 - s) * cR;
    float bg = (1.0 - s) * cG;
    float bb = (1.0 - s) * cB + s;
    
    vec3 rVec = vec3(color.r * rr + color.g * rg + color.b * rb, color.r * gr + color.g * gg + color.b * gb, color.r * br + color.g * bg + color.b * bb);
    
    return clamp(rVec * rVec * 10.0, 0.0, 1.0);
}

vec3 getDesaturatedColor(vec3 color)
{
    float brightness = (color.r + color.g + color.b) / 3.0;
    
    return vec3(brightness);
}

void main()
{
    if(texture2DEnabled == 1)
    {
        gl_FragColor = texture2D(tex0, gl_TexCoord[0].st);
    }
    else
    {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
    
    gl_FragColor *= gl_Color;
    
    
    if(brownshrooms > 0.0)
    {
        vec4 fractalColor = texture2D(texFractal0, texFractal0Coords);
        float avg = (fractalColor.r + fractalColor.g + fractalColor.b) / 3.0;
        gl_FragColor.rgb *= mix(1.0, avg * 1.5, brownshrooms);
    }
    if(redshrooms > 0.0)
    {
        float r = (sin((gl_FogFragCoord - ticks) / 5.0) - 0.4) * redshrooms;
        
        if(r > 0.0) gl_FragColor.r += r;
    }
    
    if(weed > 0.0)
    {        
        gl_FragColor.rgb = mix(gl_FragColor.rgb, getIntensifiedColor(gl_FragColor.rgb), weed);
    }
    if(redshrooms > 0.0)
    {        
        gl_FragColor.rgb = mix(gl_FragColor.rgb, getRotatedColor(gl_FragColor.rgb, mod(ticks + gl_FogFragCoord, 50.0) / 50.0), clamp(redshrooms * 1.5, 0.0, 1.0));
    }
    if(brownshrooms > 0.0)
    {
        gl_FragColor.rgb = mix(gl_FragColor.rgb, getIntensifiedColor(gl_FragColor.rgb), brownshrooms);
        
        gl_FragColor.rgb = mix(gl_FragColor.rgb, getRotatedColor(gl_FragColor.rgb, mod(ticks, 300.0) / 300.0), brownshrooms / 2.0);
    }
    if(tobacco > 0.0)
    {
        gl_FragColor.rgb = mix(gl_FragColor.rgb, getDesaturatedColor(gl_FragColor.rgb), tobacco * 0.75);
    }
    if(cocaine > 0.0)
    {
        gl_FragColor.rgb = mix(gl_FragColor.rgb, getDesaturatedColor(gl_FragColor.rgb), cocaine * 0.75);
    }
    
    
    if(overrideColor.a >= 0.0) gl_FragColor *= overrideColor;
    
    
    if (texture2DEnabled == 1)
    {
        if (lightmapEnabled == 1)
        {
            vec2 lMCoords = gl_TexCoord[1].st;
            lMCoords += 8.0;
            lMCoords /= 256.0;
            
            lMCoords = clamp(lMCoords, 0.0, 1.0);

            vec4 lighting = texture2D(tex1, lMCoords);
            gl_FragColor.rgb *= (1.0 * (1.0 - lighting.a)) + lighting.rgb * lighting.a;
        }
    }
    
    if (glLightEnabled == 1)
    {
        float glLightColor = glLightAmbient;
        
        float angle0 = acos((normalVector.x * glLightPos0.x + normalVector.y * glLightPos0.y + normalVector.z * glLightPos0.z) / (length(normalVector) * length(glLightPos0)));
        if (angle0 < 0.0) angle0 = -angle0;
        if (angle0 > 3.1415926) angle0 = 3.1415926;
        glLightColor = glLightColor + (3.1415926 - angle0) * glLightStrength1[0];

        float angle1 = acos((normalVector.x * glLightPos1.x + normalVector.y * glLightPos1.y + normalVector.z * glLightPos1.z) / (length(normalVector) * length(glLightPos1)));
        if (angle1 < 0.0) angle1 = -angle1;
        if (angle1 > 3.1415926) angle1 = 3.1415926;
        glLightColor = glLightColor + (3.1415926 - angle1) * glLightStrength1[1];
        
        gl_FragColor.rgb = gl_FragColor.rgb * clamp(glLightColor, glLightAmbient, 1.0);
    }
    
    gl_FragColor = clamp(gl_FragColor, 0.0, 1.0);
    
	if (blendFunc == GL_ONE_MINUS_SRC_ALPHA && fogMode == GL_EXP)
    {
		gl_FragColor.rgb = mix(gl_FragColor.rgb, gl_Fog.color.rgb, 1.0 - clamp(exp(-gl_Fog.density * gl_FogFragCoord), 0.0, 1.0));
	}
    else if (blendFunc == GL_ONE_MINUS_SRC_ALPHA && fogMode == GL_LINEAR)
    {
		gl_FragColor.rgb = mix(gl_FragColor.rgb, gl_Fog.color.rgb, clamp((gl_FogFragCoord - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0));
	}    
}
