#include "/lib/all_the_libs.glsl"

varying vec2 texcoord;

#include "/global/post/taa.glsl"
#include "/global/post/cas.glsl"
#include "/global/post/chromatic_aberration.glsl"
#include "/global/post/apply_warm_tint.glsl"

vec3 film_grain(vec3 Color, vec2 Pos) {
    Pos.x += fract(float(frameCounter) / 4.14159) * 234;
    Pos.y -= fract(float(frameCounter) / 5.49382) * 567;
    Color += (texture2D(noisetex, Pos.xy / 255).rgb - 0.5) * clamp((FILM_GRAIN_STRENGTH/rainStrength),0.0025,FILM_GRAIN_STRENGTH);
    #ifdef FILM_GRAIN_PULSE
    float grainPulse = 0.85 + 0.15 * sin(frameTimeCounter * 0.6);
    return Color * grainPulse;
    #else
    return Color;
    #endif
}

vec3 apply_vignette(vec3 Color, vec2 Pos) {
    Pos = Pos - 0.5;
    Pos *= VIGNETTE_OPACITY;
    float Strength = len2(Pos);
    Strength = pow(Strength, 2 - VIGNETTE_FALLOFF);
    Color *= 1 - min(Strength, 1);
    return Color;
}

float randLine(float y, float t) {
    return fract(sin(dot(vec2(y, t), vec2(12.9898,78.233))) * 43758.5453);
}

float dropout(vec2 uv) {
    float t = frameTimeCounter * 0.5;
    return step(0.995, fract(sin(dot(vec2(floor(uv.y * 240.0), t), vec2(12.9898,78.233))) * 43758.5453));
}

float luma(vec3 c) {
    return dot(c, vec3(0.299, 0.587, 0.114));
}

vec3 colorBleed(vec2 uv) {
    vec3 c0 = texture2D(colortex0, uv).rgb;
    vec3 c1 = texture2D(colortex0, uv + vec2( 1.5 / viewWidth, 0)).rgb;
    vec3 c2 = texture2D(colortex0, uv + vec2(-1.5 / viewWidth, 0)).rgb;

    float y0 = luma(c0);
    vec3 chroma0 = c0 - y0;

    vec3 chroma = (c1 + c2) * 0.5 - y0;
    return vec3(y0) + chroma;
}

// CAS

void main() {
    vec2 uv=texcoord;

    
    #ifdef LOW_RES
        uv = floor(uv * resolution * RES) / (resolution * RES);
    #endif

    #ifdef IMAGE_SHARPENING
    vec4 Color = vec4(CAS(colortex0), 1);
    #else
        #ifdef VHS_JITTER
        vec2 jitter = vec2(0.0);
        float j = sin(frameTimeCounter * 12.0) * 0.0001;
        jitter.x = j;
        uv += jitter;
        uv.x += sin(uv.y * 120.0 + frameTimeCounter * 6.0) * 0.0015;
        float tracking = smoothstep(0.9, 1.0, uv.y);
        uv.x += sin(uv.y * 80.0 + frameTimeCounter * 10.0) * 0.004 * tracking;
        #endif
    vec4 Color = texture2D(colortex0, uv);
    #endif

    Color.rgb = clamp(apply_vibrance(Color.rgb, VIBRANCE-(rainStrength*2)),0.4,2.6);
    Color.rgb = clamp(apply_saturation(Color.rgb, SATURATION-(rainStrength*2)),0.4,2.6);
    Color.rgb = clamp(apply_contrast(Color.rgb, CONTRAST-(rainStrength/3)),0.1,2);

    vec3 MinBright = vec3(TONEMAP_MIN_R, TONEMAP_MIN_G, TONEMAP_MIN_B);
    Color.rgb = max(Color.rgb, MinBright);
    Color.rgb = mix(Color.rgb, vec3(0.08), 0.05);
    Color.rgb *= vec3(1.02, 1.00, 0.97);
  
    Color.rgb = mix(Color.rgb, colorBleed(uv), 0.6);
  


    #ifdef ANAMORPHIC_EFFECT
    Color.rgb=anamorphicEffect(Color.rgb,uv); 
    #endif

    #ifdef FILM_GRAIN
    Color.rgb = film_grain(Color.rgb, gl_FragCoord.xy);
    #endif

    
    Color.rgb=applyWarmTint(Color.rgb,1);
    Color.rgb = apply_vignette(Color.rgb, texcoord);

    #ifdef VHS_DROPOUT

    float y = floor(uv.y * 240.0);
    float base = randLine(y * 0.25, floor(frameTimeCounter * 13.0));

    float d = step(1.0 - 0.001, base);

    if (d > 0.0) {
        Color.rgb *= 0.3;                  // darken
        Color.rgb += vec3(0.1, 0.1, 0.1);   // gray noise feel
    }

    #endif
    

    Color.rgb *= vec3(1.03, 1.05, 1.00);


    Color.xyz += (bayer8(gl_FragCoord.xy) - 0.5) / 255;

    gl_FragData[0] = Color;
    
}
