#version 150 compatibility

// This is a simple hue shift fragment shader with alpha color component control.
// 
// This source code contains modified/translated code 
// from Jedi Component Library, which is used under terms of MPL - Mozilla Public License.
// Portions of this source code are based on online mathematical formulas from easyrgb website:
// http://www.easyrgb.com/math.php?MATH=M19#text19
// I've backported also some fixes from https://www.gamedev.net/forums/topic/465948-hsl-shader-glsl-code/

uniform sampler2D Texture1;
uniform float AddHue, AddSat, AddLit;
uniform float ShadeMode;
uniform float Transluscency;
uniform vec4 MyPoint;
// Passed in from the vertex shader.
varying vec2 v_texcoord;
varying vec4 VertexColor;
varying vec4 WorldCoords;

//gl_Position = gl_ProjectionMatrix * view_matrix * model_matrix * gl_Vertex;

float Hue_2_RGB(float v1, float v2, float vH ) {
	
	float result;
	
	if ( vH < 0.0 )
		vH += 1.0;
	
	if ( vH > 1.0 )
		vH -= 1.0;
	
	if ( ( 6.0 * vH ) < 1.0 ) {
		result = ( v1 + ( v2 - v1 ) * 6.0 * vH ); 
	} else if ( ( 2.0 * vH ) < 1.0 ) {
		result = ( v2 );
	} else if ( ( 3.0 * vH ) < 2.0 ) {
		result = ( v1 + ( v2 - v1 ) * ( ( 2.0 / 3.0 ) - vH ) * 6.0 );
	} else {
		result = v1;
	}
	
	return result;
	
}

void main (void) {

	vec4  color;

	float Cmax, Cmin;

	float D;

	float H, S, L;
	float R, G, B;
	
	float ModifyHue, ModifySat, ModifyLit;
	
	ModifyHue = AddHue;
	ModifySat = AddSat;
	ModifyLit = AddLit;

	// get world coords, so it could be compared to roof cutout zones.
	// vec3 vert = gl_ModelViewMatrix * gl_Vertex;
	//vert = ViewMatrixInverse * vert;

	// Get fragment color
	color = texture2D(Texture1, gl_TexCoord[0].st);
	
	// https://stackoverflow.com/questions/15242507/perspective-correct-texturing-of-trapezoid-in-opengl-es-2-0
	// https://gamedev.stackexchange.com/questions/68021/how-can-i-draw-a-perspective-correct-quad
	//todo.. test it.
	
	float dist = distance(MyPoint, WorldCoords);
	
	// if (dist > 0) .. 
	
	if ( ShadeMode > 0.0 ) {
		
		gl_FragColor = vec4(0,0,0, (color.a * ShadeMode) );
		
	} else {
		
		if ( ShadeMode < 0.0 ) { // exploded burnt out rendering mode
			
			ModifyHue = 0;
			ModifySat = -1;
			ModifyLit = -0.2;
			
		}
		
		R = color.r;
		G = color.g;
		B = color.b;
		
		// properly process white color which cannot be properly converted to hsl and back (ends up black)
		if ((R == 1.0) && (G == 1.0) && (B == 1.0)) {
			
			gl_FragColor = vec4(color.r, color.g, color.b, color.a);
			
		} else {

			// convert to HSL

			Cmax = max (R, max (G, B));
			Cmin = min (R, min (G, B));

			// calculate lightness
			L = (Cmax + Cmin) / 2.0;

			if (Cmax == Cmin) { // it's grey
				H = 0.0; // it's actually undefined
				S = 0.0;
			} else {
				D = Cmax - Cmin; // we know D != 0 so we cas safely divide by it
			}

			// calculate Saturation
			if (L < 0.5) {
				S = D / (Cmax + Cmin);
			} else {
				S = D / (2.0 - (Cmax + Cmin));
			}

			// calculate Hue
			if (R == Cmax) {
				
				H = (G - B) / D;
				
			} else {
				
				if (G == Cmax) {
					H = 2.0 + (B - R) /D;
				} else {
					H = 4.0 + (R - G) / D;
				}
			}

			H = H / 6.0;

			if (H < 0.0) {
				H = H + 1.0;
			}

			// modify H/S/L values
			H += ModifyHue;
			S += ModifySat;
			L += ModifyLit;
			
			/*if (VertexColor.r < 1.0)
				L -= (1 - VertexColor.r);
			*/
			
			if (H < 0.0) {
				H = H + 1.0;
			}
			
			// clamp H,S and L to [0..1]
			
			if ( ShadeMode < 0.0 ) { // exploded burnt out rendering mode
				
				L = L * 0.5; // clamp lightness so it removes highlights, TODO: maybe just multiply everything by 0.5 ?
				
			}
			
			H = clamp(H, 0.0, 1.0);
			S = clamp(S, 0.0, 1.0);
			L = clamp(L, 0.0, 1.0);
			
			// convert back to RGB
			
			float var_2, var_1;

			if (S == 0.0) {
				
				R = L;
				G = L;
				B = L;
				
			} else {
				
				if ( L < 0.5 ) { 
					var_2 = L * ( 1.0 + S );
				} else {
					var_2 = ( L + S ) - ( S * L );
				}

				var_1 = 2.0 * L - var_2;

				R = Hue_2_RGB( var_1, var_2, H + ( 1.0 / 3.0 ) );
				G = Hue_2_RGB( var_1, var_2, H );
				B = Hue_2_RGB( var_1, var_2, H - ( 1.0 / 3.0 ) );
				
			}
			
			gl_FragColor = vec4(R, G, B, color.a * Transluscency) * VertexColor;
			
		} // white color check

	} // not shadow mode
	
}