
struct Vert{
    vec4 pos;
    vec4 color;
    float width;
    float pad;
    int start_idx;
    int end_idx;
    int prev_vert_id;
    int next_vert_id;
    int transform_buff_idx;
    bool final_vert;
};

//uniform Vert* vert_buff;
//uniform mat4* transforms_buff;

layout(std430, binding = 13) buffer afffsdg {
    Vert[] vert_buff;
};
layout(std430, binding = 10) buffer ggafffsdg {
    mat4[] transforms_buff;
};


out vec3 out_pos;
out vec4 color;



const int subdivs = 10;

bool is_last_vert = false;

Vert verts[4];
vec3 get_vert(int curve_id, out float width, Vert vert_in){
//    int curve_id = gl_VertexID/6;
//    int curve_id_next = curve_id + 1;
//    int curve_id_next_next = curve_id + 2;
//
//    int curve_vert_id_curr = curve_id/subdivs;
    
    int subdiv_id = (curve_id)%subdivs;
    int vert_id = curve_id/subdivs;


//    print(vert_in.end_idx);
    if(vert_id > vert_in.end_idx ){
//        print(3);
//        vert_id -= (vert_in.end_idx - vert_in.start_idx);
    }
//    vert_in.
    
    if(is_last_vert){
//        print(vert_id);
//        print(curve_id);
    }
    
    float fac = float(subdiv_id)/float(subdivs);

    Vert curr_vert = vert_buff[vert_id];
//    Vert prev_vert = vert_buff[max(vert_id - 1, 0)];
//    Vert prev_vert = ;
    
    ;
//    Vert next_vert = vert_buff[vert_id + 1];
//    Vert next_next_vert = vert_buff[vert_id + 2];
    Vert next_vert = vert_buff[curr_vert.next_vert_id];
//    Vert next_next_vert = vert_buff[curr_vert.next_vert_id + 1];

    width = curr_vert.width.x;

    float visc = 0.25*0.5;
    visc *= 1.5;
    vec3 curr_tan = visc*(next_vert.pos.xyz - vert_buff[curr_vert.prev_vert_id].pos.xyz) ;
    vec3 next_tan = visc*(
        curr_vert.pos.xyz - vert_buff[next_vert.next_vert_id].pos.xyz
    );
    
//    bool do_loop_curr = curr_vert.loop_data >= 0;
//    bool do_loop_next = next_vert.loop_data >= 0;
//    if(do_loop_curr){
////        curr_tan = visc*(next_vert.pos.xyz - vert_buff[curr_vert.loop_data-1].pos.xyz);
////        next_tan = visc*(curr_vert.pos.xyz - next_vert.pos.xyz);
//    } else if(do_loop_next){
////        curr_vert.pos.y += 0.1;
////        print(next_vert.loop_data);
////        next_vert = vert_buff[next_vert.loop_data-1];
////        next_next_vert = vert_buff[next_vert.loop_data-1+1];
////        next_next_vert = vert_buff[next_vert.loop_data + 1];
////        next_tan = visc*(curr_vert.pos.xyz - vert_buff[next_vert.loop_data].pos.xyz);
////        curr_vert = vert_buff[next_vert.loop_data-1+2];
//
//        if(subdiv_id > 8){
////            print(curr_vert.pos.xyz);
////            print(next_vert.pos.xyz);
//            is_last_vert = true;
//        }
////        next_tan = -visc*(
////            vert_buff[next_vert.loop_data-1+1].pos.xyz - curr_vert.pos.xyz
////        );
////        next_vert = vert_buff[next_vert.loop_data-1];
//    }

    vec3 p0 = curr_vert.pos.xyz;
    vec3 p1 = curr_vert.pos.xyz + curr_tan;
    vec3 p2 = next_vert.pos.xyz + next_tan;
    vec3 p3 = next_vert.pos.xyz;
    
    vec3 p;
    
    float x = fac;
    p = 
        p0 * (-(x*x*x) + 3.*x*x - 3.*x + 1)
        + p1 * (3*(x*x*x) - 6.*x*x + 3*x)
        + p2 * (-3*(x*x*x) + 3*x*x)
        + p3 * (x * x * x);
//    if(vert_id == 0){
//        return vec3(0);
//    }
    return p;
}

void new_new_shader(){
    int subdiv_id = (gl_VertexID/6)%subdivs;
    
    int vert_id = gl_VertexID/6/subdivs;
    int sub_tri_id = (gl_VertexID/3) % 2;
    int sub_vert_id = gl_VertexID % 3;

    int prev_vert_id = max(vert_id - 1,0);
    int next_vert_id = vert_id + 1;
    int next_next_vert_id = vert_id + 2;

    Vert curr_vert = vert_buff[vert_id];
    if(curr_vert.final_vert){
        gl_Position = vec4(0);
        return;
    }
    Vert prev_vert = vert_buff[curr_vert.prev_vert_id];
    Vert next_vert = vert_buff[curr_vert.next_vert_id];
//    Vert next_next_vert = vert_buff[curr_vert.next_vert_id + 1];
//    Vert next_next_vert = vert_buff[next_vert.next_vert_id];
//    Vert prev_vert = vert_buff[prev_vert_id];
//    Vert next_vert = vert_buff[next_vert_id];
//    Vert next_next_vert = vert_buff[next_next_vert_id];


    int curve_id = gl_VertexID/6;
    int curve_id_next = curve_id + 1;
    int curve_id_next_next = curve_id + 2;

    int curve_vert_id_curr = curve_id/subdivs;
//    int curve_vert_id_next_offs = (curve_id + 1)/subdivs - curve_vert_id_curr;
//    int curve_vert_id_next_next_offs = (curve_id + 2)/subdivs - curve_vert_id_curr;

//    is_last_vert = subdiv_id >= 9 && curve_vert_id_curr == 9;

//    bool do_loop_next = next_vert.loop_data >= 0;
//    if(do_loop_next){

//    bool do_loop_end = next_vert.loop_data == 1;
//    do_loop_end = gl_VertexID < 100;
    if(true){
//        next_width = vert_buff[next_vert.loop_data].width.x;
        if(is_last_vert){
//            print(next_vert.loop_data);
        }
//        next_vert = vert_buff[next_vert.loop_data];
//        curve_id_next -= 0;
//        curve_id_next = next_vert.loop_data * subdivs;

        //        next_width = 0.004;
        //        next_tan = visc*(curr_vert.pos.xyz - vert_buff[next_vert.loop_data].pos.xyz);
    }
    
//    verts = Vert[](
//        prev_vert,
//        curr_vert,
//        next_vert,
//        next_next_vert
//    );
    


    float curr_width;
    float next_width;
    float next_next_width;
//    curve_id/subdivs - offs;
    vec3 curr_bez_p = get_vert(
        curve_id, 
        curr_width,
        curr_vert
    );
    vec3 next_bez_p = get_vert(
        curve_id_next, 
        next_width,
        curr_vert
    );
    vec3 next_next_bez_p = get_vert(
        curve_id_next_next, 
        next_next_width,
        curr_vert
    );

    
    
    vec3 curr_vert_pos = curr_bez_p;
    vec3 next_vert_pos = next_bez_p;
    vec3 next_next_vert_pos = next_next_bez_p;
    

    mat4 transform = mat4(1);
    int transform_buff_idx = vert_buff[vert_id].transform_buff_idx;
    if(transform_buff_idx >= 0){
        transform = transforms_buff[transform_buff_idx];
    }

    float zoffs = 0.06;
    vec4 curr_vert_proj = P * (V * transform * vec4(curr_vert_pos,1) + vec4(0,0,zoffs,0));
    vec4 next_vert_proj = P * (V * transform * vec4(next_vert_pos,1) + vec4(0,0,zoffs,0));
    vec4 next_next_vert_proj = P * (V * transform * vec4(next_next_vert_pos,1) + vec4(0,0,zoffs,0));

    vec3 curr_vert_ndc = curr_vert_proj.xyz / curr_vert_proj.w;
    vec3 next_vert_ndc = next_vert_proj.xyz / next_vert_proj.w;
    vec3 next_next_vert_ndc = next_next_vert_proj.xyz / next_next_vert_proj.w;



    float tan_sc = 1.;
    vec2 w = vec2(1,R.x/R.y)*tan_sc;
    
    vec2 curr_bitan = normalize((next_vert_ndc.xy - curr_vert_ndc.xy)/w);
    vec2 next_bitan = normalize((next_next_vert_ndc.xy - next_vert_ndc.xy)/w);

//    curr_bitan *= tan_sc;
//    next_bitan *= tan_sc;

    vec2 curr_norm = vec2(curr_bitan.y, -curr_bitan.x) * w * curr_width;
    vec2 next_norm = -vec2(next_bitan.y, -next_bitan.x) * w * next_width;
    
//    curr_nowm 
//    w = 1./w;
    
    vec2 v_A_0_ndc = curr_vert_ndc.xy + vec2(curr_norm);
    vec2 v_A_1_ndc = curr_vert_ndc.xy - vec2(curr_norm);

    vec2 v_B_0_ndc = next_vert_ndc.xy + vec2(next_norm);
    vec2 v_B_1_ndc = next_vert_ndc.xy - vec2(next_norm);


    vec4 v_A_0 = vec4(v_A_0_ndc * curr_vert_proj.w, curr_vert_proj.zw);
    vec4 v_A_1 = vec4(v_A_1_ndc * curr_vert_proj.w, curr_vert_proj.zw);
    vec4 v_B_0 = vec4(v_B_0_ndc * next_vert_proj.w, next_vert_proj.zw);
    vec4 v_B_1 = vec4(v_B_1_ndc * next_vert_proj.w, next_vert_proj.zw);

    vec4 pp;
    if(sub_tri_id == 0){
        if(sub_vert_id == 0){
            pp = v_A_0;
            color = curr_vert.color;
        } else if(sub_vert_id == 1) {
            pp = v_B_0;
            color = next_vert.color;
        } else {
            pp = v_A_1;
            color = curr_vert.color;
        }
    } else {
        if(sub_vert_id == 0){
            pp = v_A_0;
            color = curr_vert.color;
        } else if(sub_vert_id == 1) {
            pp = v_B_1;
            color = next_vert.color;
        } else {
            pp = v_B_0;
            color = next_vert.color;
        }
    }
    //    const vec4 offs = vec4(0,0,0.000,0);
    //    const vec4 sc = vec4(vec3(1.,1.,1.)*0.999,1);
    //    pp -= offs;
    //    pp *= sc;
//    color = vec4()

    gl_Position = pp;
//    color.rgb = 0.5 + 0.5 * sin(vec3(3,2,1) + float(gl_VertexID/3) + T);
//    color.rgb = pow(color.rgb,vec3(14));

//    if(is_last_vert || do_loop_end){
//    if(is_last_vert){
////        print(next_vert.loop_data);
//        //        gl_Position -= gl_Position;
//        color -= color;
//        color.a = 1;
//        color.r = 1.0;
////        print(pp);
//        gl_Position.xy*=1.;
//    }
    
    color.a = 1.0;
    //    color = vec4(1,1,1,1);
    //    vec4 v_A_0 = vec4(v_A_0_ndc*A_proj.w,A_proj.zw);
    //    gl_Position
}

void main() {
//    orig_shader();
    new_new_shader();

}
