#version 330 core

uniform int			filterNumber;		// Used for selection of filter
uniform sampler2D	filterMap;			// The render to texture map
uniform sampler2D	filterMap2;			// The render to texture map
uniform vec2		filterVec2;			// Used for giving data to shader like how much blur etc.
uniform vec4		colorValue1;		// Send color information to shader. Used in 2 color for sending dark color
uniform vec4		colorValue2;		// Send color information to shader. Used in 2 color for sending light color
uniform float		colorLine;			// Number between 0 and 1 to determine where to cut the line between dark and light color
uniform float		time;				// Get the time
uniform float		alpha;				// Alpha value

float	samples[21];		// Used for blur function

in vec2	texCoord;			// The texture coordinates

out vec4 color;

void main()
{ 
	if(filterNumber == 0)						// Pass through
	{
		color.rgb = texture( filterMap, texCoord ).rgb;
		color.a = alpha;
	}


	else if(filterNumber == 1)						// Blur
	{
		samples[0]  = 0.009167927656011385;
		samples[1]  = 0.014053461291849008;
		samples[2]  = 0.020595286319257878;
		samples[3]  = 0.028855245532226279;
		samples[4]  = 0.038650411513543079;
		samples[5]  = 0.049494378859311142;
		samples[6]  = 0.060594058578763078;
		samples[7]  = 0.070921288047096992;
		samples[8]  = 0.079358891804948081;
		samples[9]  = 0.084895951965930902;
		samples[10] = 0.086826196862124602;
		samples[11] = 0.084895951965930902;
		samples[12] = 0.079358891804948081;
		samples[13] = 0.070921288047096992;
		samples[14] = 0.060594058578763092;
		samples[15] = 0.049494378859311121;
		samples[16] = 0.038650411513543079;
		samples[17] = 0.028855245532226279;
		samples[18] = 0.020595286319257885;
		samples[19] = 0.014053461291849008;
		samples[20] = 0.009167927656011385;

		vec3 sum = vec3( 0.0, 0.0, 0.0 );
		vec2 offset = vec2( 0.0, 0.0 );
		vec2 baseOffset = -10.0 * filterVec2;

		for( int s = 0; s < 21; ++s ) 
		{
			sum += texture( filterMap, texCoord + baseOffset + offset ).rgb * samples[s];
			offset += filterVec2;
		} 

		color.rgb = sum;
		color.a = 1.0;
	}

	else if(filterNumber == 2)					// Negative
	{
		color = 1.0 - texture(filterMap, texCoord);
	}

	else if(filterNumber == 3)					// Grayscale
	{
		float grayscale = dot(texture(filterMap, texCoord).rgb, vec3(0.2126, 0.7152, 0.0722)); // Use the weight model for HDTV developed by the ATSC
		color = vec4(grayscale, grayscale, grayscale, alpha);
	}

	else if(filterNumber == 4)					// TwoColor
	{
		vec4 data = texture( filterMap, texCoord );

		if ( data.r < colorLine && data.g < colorLine && data.b < colorLine)
		{
			color = colorValue1;
		}
		else
		{
			color = colorValue2;
		}
	}

	else if(filterNumber == 5)					// Color tone - May be used for Sepia
	{
		float grayscale = dot(texture(filterMap, texCoord).rgb, vec3(0.2126, 0.7152, 0.0722)); // Use the weight model for HDTV developed by the ATSC
		color = vec4(grayscale * vec3(colorValue1.r, colorValue1.g, colorValue1.b), colorValue1.a);
	}

	else if(filterNumber == 6)					// Radial Blur
	{
		samples[0] = -0.084895951965930902;
		samples[1] = -0.079358891804948081;
		samples[2] = -0.070921288047096992;
		samples[3] = -0.060594058578763078;
		samples[4] = -0.049494378859311142;
		samples[5] = -0.038650411513543079;
		samples[6] = -0.028855245532226279;
		samples[7] = -0.020595286319257878;
		samples[8] = -0.014053461291849008;
		samples[9] = -0.009167927656011385;
		samples[10] = 0.084895951965930902;
		samples[11] = 0.079358891804948081;
		samples[12] = 0.070921288047096992;
		samples[13] = 0.060594058578763078;
		samples[14] = 0.049494378859311142;
		samples[15] = 0.038650411513543079;
		samples[16] = 0.028855245532226279;
		samples[17] = 0.020595286319257878;
		samples[18] = 0.014053461291849008;
		samples[19] = 0.009167927656011385;
		samples[20] = 0.086826196862124602;
 
		// 0.5,0.5 is the center of the screen
		// so substracting uv from it will result in
		// a vector pointing to the middle of the screen
		vec2 dir = 0.5 - texCoord; 
 
		// calculate the distance to the center of the screen
		float dist = sqrt(dir.x*dir.x + dir.y*dir.y); 
 
		// normalize the direction (reuse the distance)
		dir = dir/dist; 
 
		// this is the original colour of this fragment
		// using only this would result in a nonblurred version
		color = texture(filterMap,texCoord); 
 
		vec4 sum = color;
 
		// take 10 additional blur samples in the direction towards
		// the center of the screen
		for (int i = 0; i < 21; i++)
		{
		  sum += texture(filterMap, texCoord + dir * samples[i] * filterVec2.y);
		}
 
		// we have taken eleven samples
		sum *= 1.0/11.0;
 
		// weighten the blur effect with the distance to the
		// center of the screen ( further out is blurred more)
		float t = dist * filterVec2.x;
		t = clamp( t ,0.0,1.0); //0 &lt;= t &lt;= 1
 
		//Blend the original color with the averaged pixels
		color = mix( color, sum, t );
	}
	else if(filterNumber == 7)					// Sine distort
	{ 
		vec2 temp = texCoord;
		//temp.x = temp.x + (sin(temp.y*filterVec2.y+time*1.5)*filterVec2.x);
		//temp.y = sin(temp.y*time);

		temp.y = temp.y + (sin(temp.x*filterVec2.x+time*1.5)*filterVec2.y);

		color = texture(filterMap, temp);
	}
	
	else if(filterNumber == 8)					// Color fade
	{
		vec4 data = texture( filterMap, texCoord );

		color = vec4(data.r*(smoothstep(0.0, data.r, colorLine)), data.g*(smoothstep(0.0, data.g, colorLine)), data.b*(smoothstep(0.0, data.b, colorLine)), data.a*(smoothstep(0.0, data.a, colorLine)));
	}

	else if(filterNumber == 9)						// Sobel - but not quite!
	{
		vec4 s1 = texture(filterMap, texCoord - 1.0 / 300.0 - 1.0 / 200.0);
		vec4 s2 = texture(filterMap, texCoord + 1.0 / 300.0 - 1.0 / 200.0);
		vec4 s3 = texture(filterMap, texCoord - 1.0 / 300.0 + 1.0 / 200.0);
		vec4 s4 = texture(filterMap, texCoord + 1.0 / 300.0 + 1.0 / 200.0);
		vec4 sx = 4.0 * ((s4 + s3) - (s2 + s1));
		vec4 sy = 4.0 * ((s2 + s4) - (s1 + s3));
		s1 = sqrt(sx * sx + sy * sy);
		float grayscale = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); // Use the weight model for HDTV developed by the ATSC
		color.rgba = sqrt((s1 + s2) - (s3*s4));
	}
	
	else if(filterNumber == 10)					// NegativeLine
	{
		// 0.5 for colorLine is real negative. Gives a nice coloring to animate this variable
		color = colorLine - texture(filterMap, texCoord);
	}			 
}