#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; // vertex color - used on cars to simulate damage
varying vec4 WorldCoords;



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;
	
}

// convert to HSL
vec4 RGB2HSL(float R, float G, float B) {
	
	float H, S, L;
	
	float Cmax, Cmin;
	float D;
	
	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;
	}
	
	return vec4(H, S, L, 0.0);
	
}

vec4 HueShiftColor(vec4 color_input, float ChangeHue, float ChangeSat, float ChangeLit, bool burnt_out, bool shadow_mode, float in_transluscency) {
	
	float ModifyHue = ChangeHue;
	float ModifySat = ChangeSat;
	float ModifyLit = ChangeLit;
	
	if (shadow_mode) // shadow mode
		return vec4(0,0,0, (color_input.a * ShadeMode) );
	
	if ( burnt_out ) { // exploded burnt out rendering mode
		
		ModifyHue = 0;
		ModifySat = -1;
		ModifyLit = -0.2;
		
	}
	
	float H, S, L;
	float R, G, B;
	
	R = color_input.r;
	G = color_input.g;
	B = color_input.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))
		return color_input;
	
	vec4 hsl = RGB2HSL(R, G, B);
	
	H = hsl.x;
	S = hsl.y;
	L = hsl.z;
	
	// 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 ) );
		
	}
	
	return vec4(R, G, B, color_input.a * in_transluscency) * VertexColor;
	
}


void main (void) {
	
	// some other ideas:
	// 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
	
	
	vec4 color = texture2D(Texture1, gl_TexCoord[0].st); // get fragment color
	
	gl_FragColor = HueShiftColor(color, AddHue, AddSat, AddLit, ShadeMode < 0.0, ShadeMode > 0.0, Transluscency);
	
}