varying vec2 texCoord;
//varying vec4 vColor;
uniform sampler2D colorMap;
uniform sampler2D titleMap;
uniform sampler2D titleMask;
uniform sampler2D displaceMap;

uniform float displacefx;
uniform float displacefx2;
uniform float displacefxrnd;

uniform float boostlow;
uniform float boosthigh;

uniform int abc;

uniform int swapbg;
uniform float factorr;
uniform float factorg;
uniform float factorb;
uniform float mix_;
uniform float titlefade;
uniform float yscroll;
uniform int picindex;

uniform float saturation;
uniform float luminance;

uniform int dosharpen;

uniform int docinemascopeboost;

/*
void main (void)
{
	gl_FragColor = texture2D(colorMap, texCoord);
}
*/
//	rgb<-->hsv functions by Sam Hocevar
//	http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
vec3 rgb2hsv(vec3 c)
{
	vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
	vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
	vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

	float d = q.x - min(q.w, q.y);
	float e = 1.0e-10;
	return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)
{
	vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
	vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
	return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

vec4 sharpen(){

float kernel[9];
float kernelinc[9];
vec2 offset[9];

float step_w = 1.0/1920.0;
float step_h = 1.0/1080.0;


        offset[0] = vec2(-step_w, -step_h);
        offset[1] = vec2(0.0, -step_h);
        offset[2] = vec2(step_w, -step_h);
        offset[3] = vec2(-step_w, 0.0);
        offset[4] = vec2(0.0, 0.0);
        offset[5] = vec2(step_w, 0.0);
        offset[6] = vec2(-step_w, step_h);
        offset[7] = vec2(0.0, step_h);
        offset[8] = vec2(step_w, step_h);


        /* SHARPEN KERNEL
         0 -1  0
        -1  5 -1
         0 -1  0
        */

        kernel[0] = 0.;
        kernel[1] = -1.;
        kernel[2] = 0.;
        kernel[3] = -1.;
        kernel[4] = 4.;
        kernel[5] = -1.;
        kernel[6] = 0.;
        kernel[7] = -1.;
        kernel[8] = 0.;

        kernelinc[0] = 0.;
        kernelinc[1] = 0.;
        kernelinc[2] = 0.;
        kernelinc[3] = 0.;
        kernelinc[4] = 1.;
        kernelinc[5] = 0.;
        kernelinc[6] = 0.;
        kernelinc[7] = 0.;
        kernelinc[8] = 0.;


        vec4 sum = vec4(0.0);
        int i;

        for (i = 0; i < 9; i++) {
                vec4 color = texture2D(colorMap, texCoord + offset[i]);
                sum += color * ((kernel[i] * dosharpen)+kernelinc[i]);
        }

        ///gl_FragColor = sum;
        return sum;

}















/* https://www.shadertoy.com/view/XsX3zB
 *
 * The MIT License
 * Copyright © 2013 Nikita Miropolskiy
 *
 * ( license has been changed from CCA-NC-SA 3.0 to MIT
 *
 *   but thanks for attributing your source code when deriving from this sample
 *   with a following link: https://www.shadertoy.com/view/XsX3zB )
 *
 * ~
 * ~ if you're looking for procedural noise implementation examples you might
 * ~ also want to look at the following shaders:
 * ~
 * ~ Noise Lab shader by candycat: https://www.shadertoy.com/view/4sc3z2
 * ~
 * ~ Noise shaders by iq:
 * ~     Value    Noise 2D, Derivatives: https://www.shadertoy.com/view/4dXBRH
 * ~     Gradient Noise 2D, Derivatives: https://www.shadertoy.com/view/XdXBRH
 * ~     Value    Noise 3D, Derivatives: https://www.shadertoy.com/view/XsXfRH
 * ~     Gradient Noise 3D, Derivatives: https://www.shadertoy.com/view/4dffRH
 * ~     Value    Noise 2D             : https://www.shadertoy.com/view/lsf3WH
 * ~     Value    Noise 3D             : https://www.shadertoy.com/view/4sfGzS
 * ~     Gradient Noise 2D             : https://www.shadertoy.com/view/XdXGW8
 * ~     Gradient Noise 3D             : https://www.shadertoy.com/view/Xsl3Dl
 * ~     Simplex  Noise 2D             : https://www.shadertoy.com/view/Msf3WH
 * ~     Voronoise: https://www.shadertoy.com/view/Xd23Dh
 * ~
 *
 */

/* discontinuous pseudorandom uniformly distributed in [-0.5, +0.5]^3 */
vec3 random3(vec3 c) {
	float j = 4096.0*sin(dot(c,vec3(17.0, 59.4, 15.0)));
	vec3 r;
	r.z = fract(512.0*j);
	j *= .125;
	r.x = fract(512.0*j);
	j *= .125;
	r.y = fract(512.0*j);
	return r-0.5;
}

/* skew constants for 3d simplex functions */
const float F3 =  0.3333333;
const float G3 =  0.1666667;

/* 3d simplex noise */
float simplex3d(vec3 p) {
	 /* 1. find current tetrahedron T and it's four vertices */
	 /* s, s+i1, s+i2, s+1.0 - absolute skewed (integer) coordinates of T vertices */
	 /* x, x1, x2, x3 - unskewed coordinates of p relative to each of T vertices*/

	 /* calculate s and x */
	 vec3 s = floor(p + dot(p, vec3(F3)));
	 vec3 x = p - s + dot(s, vec3(G3));

	 /* calculate i1 and i2 */
	 vec3 e = step(vec3(0.0), x - x.yzx);
	 vec3 i1 = e*(1.0 - e.zxy);
	 vec3 i2 = 1.0 - e.zxy*(1.0 - e);

	 /* x1, x2, x3 */
	 vec3 x1 = x - i1 + G3;
	 vec3 x2 = x - i2 + 2.0*G3;
	 vec3 x3 = x - 1.0 + 3.0*G3;

     //const float scale=0.65; // the lower the bigger
     //x*=scale; x1*=scale; x2*=scale; x3*=scale; // added by dm

	 /* 2. find four surflets and store them in d */
	 vec4 w, d;

	 /* calculate surflet weights */
	 w.x = dot(x, x);
	 w.y = dot(x1, x1);
	 w.z = dot(x2, x2);
	 w.w = dot(x3, x3);

	 /* w fades from 0.6 at the center of the surflet to 0.0 at the margin */
	 w = max(0.6 - w, 0.0);

	 /* calculate surflet components */
	 d.x = dot(random3(s), x);
	 d.y = dot(random3(s + i1), x1);
	 d.z = dot(random3(s + i2), x2);
	 d.w = dot(random3(s + 1.0), x3);

	 /* multiply d by w^4 */
	 w *= w;
	 w *= w;
	 d *= w;

	 /* 3. return the sum of the four surflets */
	 return dot(d, vec4(52.0));
}

/* const matrices for 3d rotation */
const mat3 rot1 = mat3(-0.37, 0.36, 0.85,-0.14,-0.93, 0.34,0.92, 0.01,0.4);
const mat3 rot2 = mat3(-0.55,-0.39, 0.74, 0.33,-0.91,-0.24,0.77, 0.12,0.63);
const mat3 rot3 = mat3(-0.71, 0.52,-0.47,-0.08,-0.72,-0.68,-0.7,-0.45,0.56);

/* directional artifacts can be reduced by rotating each octave */
float simplex3d_fractal(vec3 m) {
    return   0.5333333*simplex3d(m*rot1)
			+0.2666667*simplex3d(2.0*m*rot2)
			+0.1333333*simplex3d(4.0*m*rot3)
			+0.0666667*simplex3d(8.0*m);
}

vec4 mainImageSimplex(in vec2 fragCoord )
{
	vec2 p = fragCoord;///fragCoord.xy/1920.0;
	///vec3 p3 = vec3(p, iTime*0.025);
    vec3 p3 = vec3(p, titlefade*0.025);

	float value;

	if (p.x <= 0.6) {
		value = simplex3d(p3*32.0);
	} else {
		value = simplex3d_fractal(p3*8.0+8.0);
	}

	value = 0.5 + 0.5*value;
	value *= smoothstep(0.0, 0.005, abs(0.6-p.x)); // hello, iq :)

	vec4 fragColor = vec4(
			vec3(value),
			1.0);
	return fragColor;
}



















void main (void)
{
/*
vec4 color2= texture2D(titleMap, texCoord); ///backup fb
bool black=false;
vec4 check=texture2D(colorMap, vec2(0.2,0.2))+texture2D(colorMap, vec2(0.8,0.2))+texture2D(colorMap, vec2(0.2,0.8))+texture2D(colorMap, vec2(0.8,0.8))+texture2D(colorMap, vec2(0.5,0.5));
if (check.rgb==vec3(0,0,0)) black=true;
if (black) 
gl_FragColor=color2;
///gl_FragColor=vec4(1,1,1,0.5);
///discard; 
else
*/
{
//vec2 nutexcoord;
//	nutexcoord=texCoord;
//	nutexcoord.x=1.0-nutexcoord.x;
vec4 currentpixel;

    vec2 texCoord_=texCoord;
    vec4 colornoise=vec4(0.0,0.0,0.0,0.0);
    if (displacefx2>0){
        vec2 scroll=texCoord; scroll.x=displacefx2; scroll.y+=displacefxrnd;
        float yoff=texture2D(displaceMap, scroll).r;

        texCoord_.y+=((0.5-yoff)*displacefx/10.0);
        texCoord_.y=clamp(texCoord_.y,0.0,1.0-1.0/1080.0);

        vec2 noisecoo=vec2(texCoord_.x,scroll.y+yoff);
        float noise_=texture2D(displaceMap, noisecoo).b;
        colornoise=vec4(noise_,noise_,noise_,1.0)*displacefx2/4.0f;
        //texture2D(titleMap, noisecoo)*displacefx2/4.0f;
    }
    if (dosharpen>0) currentpixel=sharpen(); else
    {
        vec2 scrollx=texCoord; scrollx.x+=0.0; scrollx.y/=2.0; scrollx.y+=pow(displacefx2/6.33,1.23)+displacefxrnd;
        float xoff=texture2D(displaceMap, scrollx).g/12.0*displacefx2;
        texCoord_.x+=xoff;texCoord_.x=clamp(texCoord_.x,0.0,1.0f-1.0f/1920.0f);
        currentpixel=texture2D(colorMap, texCoord_)+colornoise;
    }
	vec4 color = currentpixel;///texture2D(colorMap, texCoord);

    float color2_=texture2D(displaceMap, texCoord).b;
	vec4 color2= vec4(color2_,color2_,color2_,1.0);///texture2D(titleMap, texCoord);

    /*
	vec4 colormask=texture2D(titleMask, vec2(titlefade,texCoord.y*10.0f+yscroll));
	float mask=colormask.r;
	color2.a=color2.a*mask;
	color=color*(1.0-color2.a)+color2*(color2.a);
    */


//    vec2 texCoord3=texCoord+vec2(simplex3d(vec3(color2.x,color2.y,color2.z*titlefade)),simplex3d(vec3(color.xyz)))*(1.0-titlefade);
/* 
uncomment the following to have noised fading 
*/

    vec2 texCoord3=texCoord;
    const float granularity=12.0; ///20.0 16.0
    const float intensitydiv=40.0; ///60.0
    ///if (picindex==2&&titlefade<1.0)
        texCoord3=vec2(simplex3d(vec3(texCoord.xy,titlefade/8.0)*granularity),0.25+simplex3d(vec3(texCoord.xy*5.0,1.0-titlefade/8.0)*granularity))/intensitydiv*(1.0-titlefade);
        texCoord3+=vec2(simplex3d(vec3(texCoord.xy,10.0+titlefade/8.0)*granularity*1.05),0.25+simplex3d(vec3(texCoord.xy*5.0,10.0+1.0-titlefade/8.0)*granularity*1.05))/intensitydiv*(1.0-titlefade);
        texCoord3=texCoord+texCoord3/2.0;
	vec4 cc = texture2D(titleMask, texCoord3);

    /*
    when commenting out the above, uncomment the following
    */
	///vec4 cc = texture2D(titleMask, texCoord);

    /*
    if (cc.r+cc.g+cc.b>0.4)
    if (cc.r==cc.g&&cc.r==cc.b)
        color=color*(1.0-cc.r*titlefade)+vec4(1.0,1.0,1.0,1.0)*cc.r*titlefade;
    else
        color=color*(1.0-titlefade)+cc*titlefade;
    */

   if (docinemascopeboost==1){
        // two thirds of the original color and a third of blurred value or even worse
        vec4 col1=color/4.0*3.0;
        vec4 col2=color;
        for (int x=-20;x<=20;x+=4)
            for (int y=-20;y<=20;y+=4){
                vec2 blurcoo=vec2(texCoord + vec2((float(x)/1920.0),(float(y)/1080.0)) );
                blurcoo.x=clamp(blurcoo.x,0.0,1.0-1.0/1920.0);
                blurcoo.y=clamp(blurcoo.y,0.0,1.0-1.0/1080.0);
                col2 += texture2D(colorMap, blurcoo);
            }
        col2/=11*11*4;
        //col2=vec4(1.0,0.0,0.0,1.0);
        color=col1+col2;
   }

	vec4 color_original = color;
	if (swapbg==1) color=color.rbga;
	float r=color.r; r*=factorr; r=clamp(r,0.0,1.0); color.r=r;
	float g=color.g; g*=factorg; g=clamp(g,0.0,1.0); color.g=g;
	float b=color.b; b*=factorb; b=clamp(b,0.0,1.0); color.b=b;
	if (swapbg==2) {
        color=vec4(1.0,1.0,1.0,1.0);
	}


	/// contrast boost:
    ///#define const_1 ( 16.0f / 255.0f)
    ///#define const_2 (255.0f / 219.0f)
    #define const_1 (boostlow / 255.0)
    #define const_2 (255.0 / boosthigh)
    color= ((color - const_1) * const_2);
    color_original= ((color_original - const_1) * const_2);

	///gl_FragColor = color*mix_+color_original*(1.0-mix_);
    color = color*mix_+color_original*(1.0-mix_);
    
    /*
    #define const_1 (boostlow / 255.0f)
    #define const_2 (255.0f / boosthigh)
    color= ((color - const_1) * const_2);
    */

	///vec4 cc = texture2D(titleMask, texCoord);
    float ac=cc.a*titlefade;
    gl_FragColor = color*(1.0f-ac)+vec4(cc.rgb,1.0)*ac;

	if (saturation!=0.0){
        vec3 hsv=rgb2hsv(gl_FragColor.rgb);
        hsv.y+=saturation;hsv.y=clamp(hsv.y,0,1);
        hsv.z+=luminance;hsv.z=clamp(hsv.z,0,1);
        vec3 rgb=hsv2rgb(hsv);
        gl_FragColor=vec4(rgb.x,rgb.y,rgb.z,1.0f);
	}
    if(luminance!=0.0){
        gl_FragColor+=vec4(vec3(luminance),1.0f);
    }
	//gl_FragColor = texture2D(colorMap, texCoord)*vColor;
	//gl_FragColor = texture2D(colorMap, nutexcoord);

 
}
}