in vec2 uv;
in vec2 uvn;

out vec4 C;

uniform int tex_render;
uniform int tex_prev;
uniform int tex;
uniform float blocks_glitch_amt;
uniform float feedback_glitch_amt;
uniform bool do_bayer_feedback;

#include noise.glsl

float rand(vec3 p3) {
    p3  = fract(p3 * 222.1031);
    p3 += dot(p3, p3.zyx + 31.33);
    return fract((p3.x + p3.y) * p3.z);
}
float rand(vec2 p) {
    vec3 p3  = fract(vec3(p.xyx) * .1031);
    p3 += dot(p3, p3.yzx + 33.33);
    return fract((p3.x + p3.y) * p3.z);
}
vec3 rand(float p) {
    vec3 p3 = fract(vec3(p) * vec3(.1031, .1030, .0973));
    p3 += dot(p3, p3.yzx+33.33);
    return fract((p3.xxy+p3.yzz)*p3.zyx);
}

#include noise.glsl

float Bayer2(vec2 a) {
    a = floor(a);
    return fract(a.x / 2. + a.y * a.y * .75);
}

#define Bayer4(a)   (Bayer2 (.5 *(a)) * .25 + Bayer2(a))
#define Bayer8(a)   (Bayer4 (.5 *(a)) * .25 + Bayer2(a))
#define Bayer16(a)  (Bayer8 (.5 *(a)) * .25 + Bayer2(a))
#define Bayer32(a)  (Bayer16(.5 *(a)) * .25 + Bayer2(a))
#define Bayer64(a)  (Bayer32(.5 *(a)) * .25 + Bayer2(a))

uniform bool is_tri_scene;
uniform int glitch_type;

void main() {
    vec2 u = uvn;

    C = max(texture(textures[tex_render], u),0.);


//    uniform float blocks_glitch_amt;
//    uniform float feedback_glitch_amt;
    if(blocks_glitch_amt > 0.001){
        if(glitch_type == 1){
            C -= C;

            float emd = 0.5;
            float env = mod(T,emd)/emd;
            env = smoothstep(0.0,0.04, env) * smoothstep(1.0,0.0, env);
            
            env *= 0.2;
            env = blocks_glitch_amt;

            vec2 md = vec2(1.0,0.2);
            vec2 muv = u;
            vec2 fluv = floor(muv/md)*md;
            muv = fract(muv/md)*md;



            //        vec2 noise = valueNoise(hash12(fluv.yy)*100.0 + T*10.0, 4.0).xy;
            float noiset = T*23.;
            float noise_param = hash12(fluv.yy)*100.0 + noiset;
            vec2 noise = valueNoise(noise_param, 4.0).xy;
            vec2 noise_prev = valueNoise(noise_param - 0.003, 4.0).xy;

            vec2 delta_noise = noise - noise_prev;
            noise -= 0.5;
            noise *= env;

            float moblur_amt = env;

            int moblur_steps = 9;
            vec2 omuv = muv;
            for(int i = 0; i < moblur_steps; i++){
                vec2 j = omuv;
                j.x += (
                noise.x - 140.0*delta_noise.x * moblur_amt * float(i)/float(moblur_steps))*0.6;

                float flmuv = floor(j.x);
                j.y += flmuv*md.y;

                j += fluv;
                int idx = i%3;
                C[idx] += max(texture(textures[tex_render], j)[idx], 0.)/float(moblur_steps)*3.0;
                muv = j;
            }


            {
                //            C -= C;
                vec2 q = muv;

                md.x /= 8.0;
                md.y /= 4.0;
                q /= md;
                //            q.y *= 2.0;
                vec2 id = q;
                id = floor(id);
                //            

                //            if()

                float hseed = 0.;
                hseed += floor(T*15.0);

                for(int i = 0; i < 15; i++){
                    vec2 offs = floor(q) + md * 0.5;
                    vec2 luv = fract(q);
                    int ax = int(hash13(vec3(id,i + 124) + hseed) > 0.5);
                    int subax = int(hash13(vec3(id,i + 24) + hseed) > 0.5);
                    float chance = hash13(vec3(id,i + 23 + ax) + hseed);
                    chance = pow(chance,2.0 + float(i));

                    ivec2 lid = ivec2(luv*2.0);
                    if(true && lid[subax] == ax && chance < 0.9*env){
                        md[ax] /= 2.0;
                        q = muv / md;
                        id = floor(q);
                        if(i%5 < 2){
                            C.rgb -= 0.8*vec3(hash13(vec3(id,i + 12.4) + hseed));
                        } else if ((i%5 < 4)){
                            int cidx = int(
                            hash13(
                            vec3(id,i + 12.4 + ax)  + hseed
                            )*3.0f
                            );
                            C[cidx] -= (hash13(vec3(id,i + 14 + hseed)))*0.4;
                        } else {
                            C.rgb = vec3(hash13(vec3(id,i + 12.4) + hseed))*0.4;
                        }
                    } else {
                        break;
                    }
                }

                //            C.x = 1.0;

                //            q /= md;

                //            vec2 qmd = 


            }

            //        if(flmuv != 0.0){
            //            C.r = 0.;
            //        }
        }
        //    if(blocks_glitch_amt>0.001){
        else if(blocks_glitch_amt>0.001){
            vec2 md = vec2(0.1,0.1);
            vec2 muv = u;
            vec2 fluv = floor(muv/md)*md;
            muv = fract(muv/md)*md;

            float jigg_amt = 0.005 * blocks_glitch_amt;

            vec2 jiggle = jigg_amt * valueNoise(hash12(fluv)*100.0 + T*10.0, 1.0).xy;
            jiggle = jiggle - 0.5*jigg_amt;
            vec2 prev_jiggle = jigg_amt * valueNoise(hash12(fluv)*100.0 + T*10.0 - 0.04, 1.0).xy;
            prev_jiggle = prev_jiggle - 0.5*jigg_amt;

            //        ;
            //        muv += 0.2 * sin(vec2(rand(fluv),rand(fluv + 124.5))*T+fract(sin(fluv*124.421)*124.532));
            muv += jiggle;
            muv += fluv;

            vec2 jigg_deriv = (jiggle - prev_jiggle)/0.04;
            float bay = Bayer8(U.xy);

            u += bay * jigg_deriv;

            C -= C;
            u = muv;
            float its = 3 * 5;
            for(int ch = 0; ch < 3; ch++){
                for (float i = 0.; i < its; i++){
                    C[ch] += max(texture(textures[tex_render], u + jigg_deriv*float(ch + 1.)*0.4), 0.)[ch];
                }
            }
            C /= its/1;

        }
        
    }
    
    if(true){
        float glitch_feedback_amt = 0.998 * feedback_glitch_amt;
//        float glitch_feedback_amt = 0.99;
//        float glitch_feedback_amt = 0.1;
        
        vec4 prev_frame;
        if(do_bayer_feedback){
            u -= 0.5;
            u /= 1.01;
            u += 0.5;
            prev_frame = texelFetch(
                textures[tex_prev], 
                ivec2(u*R),
                0
            );
            if(!is_tri_scene){
                prev_frame = texture(textures[tex_prev], u);

            }
            
        } else {
            prev_frame = texture(textures[tex_prev], u);
        }
//        vec4 curr_frame = texture(textures[tex_render], u);

        if(do_bayer_feedback){
//            float bay = Bayer16(U/4);
            float bay = Bayer16(u*300.0 + T*10.0);
            
            if (bay > prev_frame.x){
                // fb col
                //            prev_frame.x = 0.2;
//                prev_frame = vec4(0.2, 0.1, 0.5, 1);
            } else {
                //            bg col
                //            prev_frame.x = 1.;
                //            prev_frame.x = C.x;
                prev_frame = C;
            }
        }
        
        vec4 curr_frame = C;
        C = mix(curr_frame,prev_frame, glitch_feedback_amt*(luma(curr_frame.rgb)));
        if(any(isnan(C))){
            C -= C;
        }
    }

//    C = sqrt(C);
//    C = 1.-C;
//    C = FXAA(textures[tex_render], u);
//    C=pow(
//        C,
//        vec4(.4545)
//    );

    C.w = 1.0;
}
