#version 330 core
in vec2 vTex;
out vec4 FragColor;

uniform sampler2D iChannel0;
uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;
uniform float uStartDelay;

float rand(vec2 co){
    return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
}

vec4 interlace(vec2 co, vec4 col) {
    int iy = int(floor(co.y));
    if (iy % 3 == 0) {
        return col * ((sin(iTime * 4.0) * 0.1) + 0.75) + vec4(rand(vec2(iTime, iTime)) * 0.05);
    }
    return col;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // normalized uv
    vec2 uv = fragCoord / iResolution.xy;

    // passthrough until startDelay
    if (iTime < uStartDelay)
    {
        fragColor = texture(iChannel0, uv);
        return;
    }

    bool normal = false;

    vec2 uvneg = vec2(fragCoord.x / iResolution.x - (rand(vec2(fragCoord.y + iTime*0.0001, 0.0))*0.06), fragCoord.y / iResolution.y);
    vec2 uvnegR = vec2(uvneg.x + (rand(vec2(iTime*0.005, iResolution.x))*0.1), uvneg.y);
    vec2 uvnegG = vec2(uvneg.x + (rand(vec2(iTime*0.005, iResolution.y))*0.1), uvneg.y);
    vec2 uvnegB = vec2(uvneg.x + (rand(vec2(iTime*0.005, iResolution.z))*0.1), uvneg.y);

    vec2 uvpos = vec2(fragCoord.x / iResolution.x + (rand(vec2(fragCoord.y + iTime*0.0001, 0.0))*0.03), fragCoord.y / iResolution.y);
    vec2 uvposR = vec2(uvpos.x + (rand(vec2(iTime*0.005, iResolution.x))*0.1), uvpos.y);
    vec2 uvposG = vec2(uvpos.x + (rand(vec2(iTime*0.005, iResolution.y))*0.1), uvpos.y);
    vec2 uvposB = vec2(uvpos.x + (rand(vec2(iTime*0.005, iResolution.z))*0.1), uvpos.y);

    vec2 uvNormal = vec2(fragCoord.x / iResolution.x + (rand(vec2(fragCoord.y + iTime*0.001, 0.0))*0.006), fragCoord.y / iResolution.y);

    float displace = 0.005;
    if (rand(vec2(iTime*0.001, iResolution.x)) > 0.8) {
        displace = rand(vec2(iTime*0.1, iResolution.y)) / 10.0 + (uv.y / 5.0);
    }

    vec2 uvGlitch = vec2(uv.x + (rand(vec2(iTime*0.005, iResolution.x))*displace), uv.y);
    float startGlitch = rand(vec2(iTime*0.004, iResolution.y));
    float startGlitch2 = rand(vec2(iTime*0.004, iResolution.x));

    float Pi = 6.28318530718;

    float dir = 16.0;
    float qual = 10.0;
    float size = rand(vec2(iTime, fragCoord.y)) * 20.0;

    vec2 Radius = vec2(size) / iResolution.xy;

    vec4 Color = texture(iChannel0, uv);
    vec4 col = texture(iChannel0, uv);

    for (float d = 0.0; d < Pi; d += Pi / dir)
    {
        for (float i = 1.0/qual; i <= 1.0; i += 1.0/qual)
        {
            float sin_d = sin(d);
            vec2 offset = vec2(cos(d), sin_d) * Radius * i;
            float ytest = uv.y + (sin_d) * Radius.y * i;

            if (ytest < startGlitch + 0.02 && ytest > startGlitch - rand(vec2(iTime*0.002, iResolution.y))/5.00) Color.r += texture(iChannel0, uvnegR + offset).r;
            else if (ytest < startGlitch + 0.04 && ytest > startGlitch - rand(vec2(iTime*0.002, iResolution.x))/5.2) Color.r += texture(iChannel0, uvposR + offset).r;

            if (ytest < startGlitch && ytest > startGlitch - rand(vec2(iTime*0.002, iResolution.y))/2.0) Color.g += texture(iChannel0, uvnegG + offset).g;
            else if (ytest < startGlitch2 && ytest > startGlitch2 - rand(vec2(iTime*0.002, iResolution.x))/3.0) Color.g += texture(iChannel0, uvposG + offset).g;

            if (ytest < startGlitch + 0.01 && ytest > startGlitch - rand(vec2(iTime*0.002, iResolution.y))/4.0) Color.b += texture(iChannel0, uvnegB + offset).b;
            else if (ytest < startGlitch2 + 0.03 && ytest > startGlitch2 - rand(vec2(iTime*0.002, iResolution.x))/5.4) Color.b += texture(iChannel0, uvposB + offset).b;
            else {
                Color.g += texture(iChannel0, vec2((uvNormal + offset + displace).x, uvNormal.y + rand(vec2(iTime*0.001, iResolution.y))*0.075)).g;
                Color.b += texture(iChannel0, uvGlitch).b;
                Color.r += texture(iChannel0, uvGlitch + offset).r;
                normal = true;
            }
        }
    }

    Color /= qual * dir - 15.0;
    vec4 finalCol = interlace(fragCoord, Color);

    // mix over original using uAlpha
    vec3 orig = texture(iChannel0, uv).rgb;
    vec3 outcol = mix(orig, finalCol.rgb, clamp(uAlpha, 0.0, 1.0));
    fragColor = vec4(outcol, clamp(uAlpha, 0.0, 1.0));
}

void main(){ mainImage(FragColor, gl_FragCoord.xy); }
