#include scene_sessions24/util.glsl
#include scene_sessions24/silly.frag
#include scene_sessions24/segcirc.frag
#include scene_sessions24/quadtree.frag
#include scene_sessions24/fisheye.frag
#include scene_sessions24/fractal.frag
#include scene_sessions24/tanstretch.frag
#include scene_sessions24/flying.frag
#include scene_sessions24/spiral.frag
#include scene_sessions24/cube.frag
#include scene_sessions24/hexagon.frag

in vec2 uv;

out vec4 C;

uniform float u_t;
uniform int u_scene;
uniform int u_scene_b;
uniform float u_scene_mix;

uniform vec3 colBG;
uniform vec3 colA;
uniform vec3 colB;

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

float cros(vec2 p) {
    vec2 q = abs(p);
    return min(q.x,q.y);
}

float box(vec2 p) {
    vec2 q = abs(p/sqrt(2.));
    return max(q.x,q.y);
}

float heart(vec2 p) {
    float stem = box((p-vec2(0,.2))*rot(PI/4.))*sqrt(2.);
    float circs = length(abs(p+vec2(0,.2))-vec2(.4,0.));
    return min(stem, circs)-.5;
}

vec3 scene(vec2 UV, float t) {
    float repeat = 1.;
    vec2 i_uv = floor(UV*repeat);
    vec2 f_uv = fract(UV*repeat); f_uv = (f_uv-0.5)*2.;

    float scaled_t = t/BEAT_DUR;
    float i_t = floor(scaled_t);
    float f_t = fract(scaled_t);

    float ang = rand(i_uv+vec2(777.62,867.29))+sign(rand(i_uv)-.5)*(i_t+elastic(f_t))*.177;
    vec2 shape_uv = f_uv * rot(ang*TAU);
    
    vec3 bg = colBG;
    vec3 hl = mix(colA, colB, step(.5,rand(i_uv)));
    
    float val = 1.;
    int shape = int(rand(i_uv+vec2(362.63, 216.46))*4.);
    if(shape==0) {
        val = step(.5, box(shape_uv));
    }else if(shape==1){
        val = step(.4, cros(shape_uv));
    }else if(shape==2){
        val = step(0., heart(shape_uv));
    }
    return mix(hl,bg,val);
}

vec2 apply(int which, vec2 p, float t) {
    vec2 mod_uv = p;
    if(which == 0){
        mod_uv = silly_main(p, t);
    }
    else if(which == 1){
        mod_uv = segcirc_main(p, t);
    }
    else if(which == 2){
        mod_uv = quadtree_main(p, t);
    }
    else if(which == 3){
        mod_uv = fisheye_main(p, t);
    }
    else if(which == 4){
        mod_uv = fractal_main(p, t);
    }
    else if(which == 5){
        mod_uv = tanstretch_main(p, t);
    }
    else if(which == 6){
        mod_uv = flying_main(p, t);
    }
    else if(which == 7){
        mod_uv = spiral_main(p, t);
    }
    else if(which == 8){
        mod_uv = cube_main(p, t);
    }
    else{
        mod_uv = hexagon_main(p, t);
    }
    return mod_uv; 
}

void main() {
    vec2 UV = vec2(uv.x*R.x/R.y, uv.y);
    float moblur = u_t-pow(Bayer2(U)/90.,0.9);

    vec2 mod_uv;
    int seg = int(u_t*.25);
    int seg_b = 0;
    float scene_mix = u_scene_mix;

    { //sequencing
        // intro
        if(u_t*.125 < 1.0){
            seg = 6;
            seg_b = 6;
            scene_mix = 0.;
        }
        else if(u_t*.125 < 2.0){
            seg = 6;
            seg_b = 8;
            scene_mix = sine_ease(fract(u_t*.125 - 2.0));
        }
        else if(u_t*.125 < 3.0){
            seg = 8;
            seg_b = 0;
            scene_mix = 0.;
        }
        else if(u_t*.125 < 4.0){
            seg = 8;
            seg_b = 0;
            scene_mix = sine_ease(fract(u_t*.125 - 4.0));
        }
        // drop 1
        else if(u_t*.125 < 4.5){
            seg = 2;
            seg_b = 0;
            scene_mix = 0.;
        }
        else if(u_t*.125 < 5.0){
            seg = 7;
            seg_b = 0;
            scene_mix = 0.;
        }
        else if(u_t*.125 < 5.5){
            seg = 0;
            seg_b = 0;
            scene_mix = 0.;
        }
        else if(u_t*.125 < 6.0){
            seg = 9;
            seg_b = 0;
            scene_mix = 0.;
        }
        // drop 2
        else if(u_t*.125 < 6.5){
            seg = 9;
            seg_b = 3;
            scene_mix = sine_ease(fract(u_t*.125 - 6.0)*2.0);
        }
        else if(u_t*.125 < 7.0){
            seg = 1;
            seg_b = 6;
            scene_mix = sine_ease(fract(u_t*.125 - 6.5)*2.0);
        }
        else if(u_t*.125 < 7.5){
            seg = 6;
            seg_b = 1;
            scene_mix = sine_ease(fract(u_t*.125 - 7.0)*2.0);
        }
        else if(u_t*.125 < 8.0){
            seg = 1;
            seg_b = 2;
            scene_mix = sine_ease(fract(u_t*.125 - 7.5)*2.0);
        }
        else if(u_t*.125 < 9.0){
            seg = 2;
            seg_b = 0;
            scene_mix = 0;
        }
        else if(u_t*.125 < 10.0){
            seg = 2;
            seg_b = 5;
            scene_mix = sine_ease(fract(u_t*.125 - 10.0));
        }
        else if(u_t*.125 < 10.25){
            seg = 5;
            seg = 6;
            scene_mix = sine_ease(fract(u_t*.125 - 10.0)*4.0);
        }
        else{
            seg = 6;
            seg = 0;
            scene_mix = 0.;
        }
        mod_uv = mix(apply(seg, UV, moblur), apply(seg_b, UV, moblur), scene_mix);

    }

    // if(u_scene>=0 || u_scene_b>=0){
    //     seg = u_scene;
    //     seg_b = u_scene_b;
    //     mod_uv = mix(apply(seg, UV, moblur), apply(seg_b, UV, moblur), scene_mix);
    // }
    // else{
    //     mod_uv = apply(seg, UV, moblur);
    // }
    0;

    vec3 col = scene(mod_uv, moblur*2.5);

    C = vec4(col, 1.0);
}