in vec2 uv;
in vec2 uvn;

out vec4 C;

uniform int input_tex;
uniform int blue_noise_tex;
uniform vec2 output_res;


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))

vec4 samp_chan(int chan_idx){
    ivec2 iR = ivec2(output_res);
    vec4 C = vec4(0);

    ivec2 chan_u = ivec2(
        chan_idx % iR.x,
        chan_idx / iR.x
    );
    vec2 chan_uv = vec2(chan_u + 0.5)/output_res;
//    C = texelFetch(textures[input_tex],chan_u,0);
    C = texture(textures[input_tex],chan_uv,0);
//    C = texture(textures[input_tex],u);

    vec4 dith = texelFetch(textures[blue_noise_tex],ivec2(U)%64,0);
    dith = Bayer32(U)*vec4(1);

    float quant = 0.05;

    vec4 fr = 1.-abs(fract(C/quant) - 0.5)/0.5;
    //fr = vec4(0.5);
    C += (dith*2. - 1.)*quant*0.5*fr;

    C = round(C/quant)*quant;

    return C;
}

void main() {
    vec2 u = uvn;
    ivec2 id = ivec2(U);

    ivec2 iR = ivec2(output_res);


    int offs = 5;
    int chan = id.y%4;
    int chan_id = id.y/4;
    int chan_idx = id.x + chan_id*4*iR.x;
    chan_idx += chan * iR.x;

    int interl_idx;

    {
        int rows_per_chan = iR.y/4;
        interl_idx = chan_id * iR.x;
        interl_idx += chan * rows_per_chan * iR.x;
    }
    

    int orig_chan_idx = chan_idx;

    #define add_offs(offs, t,tb) chan_idx += offs * int(interl_idx > int(output_res.x*output_res.y*t) && interl_idx < int(output_res.x*output_res.y*(t+tb)) );
    float glitch_amt = 0.5 + 0.5*sin(T*1.);
//    glitch_amt = pow(glitch_amt,5.);
    glitch_amt = 0.;
    for(float i = 1; i < 40; i++){
        float s = floor(T/0.1);
        float idx = fract(sin(i*12.436+s)*2.31326);
        float idxb = fract(sin(i*5.436+s)*9.81326);
        float idxc = fract(sin(i*532.836)*52.81326);
        idxc = pow(idxc, 2.)*glitch_amt*2.0;
        idxb = pow(idxb, 6.)*4.0;
        
         int pxcnt = int(idxb*100*glitch_amt);
         add_offs(-pxcnt*int(sign(idx - 0.5)), idx, idxc*0.2);
//        add_offs(pxcnt, idx);
    }
    //add_offs(14, .8 );
//    add_offs(14, .46 );
//    add_offs(-14, .5 );
//    add_offs(24, .1 );
//    add_offs(-4, .14 );
//    add_offs(44, .75 );
//    add_offs(-54, .84 );


//    if(chan == 0){
//        ivec2 chan_u = ivec2(
//            chan_idx % iR.x,
//            (chan_idx / iR.x) % iR.y
//        );
//        //C = texelFetch(iChannel0,chan_u,0);
//        //C = texture(iChannel0,uv);
//
//    } else {
//        //C = vec4(0);
//    }
    C = samp_chan(chan_idx);

    if(chan_idx/iR.x != orig_chan_idx/iR.x){
        C = vec4(0.5);
    }
    if(interl_idx > int(output_res.x*output_res.y/2.0)){
        //C -= C;
    }

    if(false){
        C = texture(textures[input_tex],u);

        vec4 dith = texelFetch(textures[blue_noise_tex],ivec2(U)%64,0);
        dith = Bayer32(U)*vec4(1);

        float quant = 0.05;

        vec4 fr = 1.-abs(fract(C/quant) - 0.5)/0.5;
        //fr = vec4(0.5);
        C += (dith*2. - 1.)*quant*0.5*fr;

        C = round(C/quant)*quant;
        
    }
    
//    C=vec4(pow(max(C.rgb,0.),vec3(1./.4545)),1);
    
//    C=vec4(pow(max(C.rgb,0.),vec3(.4545)),1);
    C.w = 1.0;
}
