// File: chhylp123[P]hifiasm/Correct.cpp
// Function: ug_lalign(overlap_region_alloc*, Candidates_list*, ul_idx_t const*, ug_opt_t const*, char*, unsigned long, UC_Read*, UC_Read*, Correct_dumy*, bit_extz_t*, overlap_region*, double, long, long, unsigned long, unsigned long, void*)
void ug_lalign(overlap_region_alloc* ol, Candidates_list *cl, const ul_idx_t *uref, const ug_opt_t *uopt, 
        char *qstr, uint64_t ql, UC_Read* qu, UC_Read* tu, Correct_dumy* dumy, bit_extz_t *exz,  
        overlap_region *aux_o, double e_rate, int64_t wl, int64_t sid, uint64_t khit, 
        uint64_t chain_cut, void *km)
{
    uint64_t i, bs, k, ovl, pid, kl, kn; Window_Pool w; double err; 
    overlap_region t; overlap_region *z; char *in = qstr;
    ol->mapped_overlaps_length = 0;
    if(ol->length <= 0) return;

    ///base alignment
    clear_Correct_dumy(dumy, ol, km); err = e_rate; 
    init_Window_Pool(&w, ql, wl, (int)(1.0/err));
    bs = (w.window_length)+(THRESHOLD_MAX_SIZE<<1)+1;
    resize_UC_Read(tu, bs<<1);

    if(!aux_o) {    
        if(qu) {
            resize_UC_Read(qu, ql); qu->length = ql; memcpy(qu->seq, qstr, ql); in = qu->seq;
        } 
        for (i = 0; i < ol->length; i++) {
            z = &(ol->list[i]); ovl = z->x_pos_e+1-z->x_pos_s; 
            z->shared_seed = z->non_homopolymer_errors;///for index
            pid = cl->list[z->shared_seed].readID; kl = cl->length; kn = 0;
            for (k = z->shared_seed; k < kl && cl->list[k].readID == pid && kn < chain_cut; k++) kn++;
            if(kn < chain_cut) continue;
            
            if(!align_ul_ed_post_extz(z, uref, NULL, in/**qu->seq**/, tu->seq, exz, err, w.window_length, -1, 0, km)) {
                continue;
            }
            if(uref && simi_pass(ovl, z->align_length, uref?1:0, -1, NULL)) {
                z->is_match = 3; ol->mapped_overlaps_length += z->align_length;
            }
        }

        // if(uref && ol->mapped_overlaps_length > 0) {
        //     set_herror_win(ol, dumy, v_idx, err, ql, w.window_length);
        // }

        double e_max = err*1.5, rr; int64_t re;
        for (i = k = 0; i < ol->length; i++) {
            z = &(ol->list[i]); ovl = z->x_pos_e + 1 - z->x_pos_s;
            rr = gen_extend_err_exz(z, uref, NULL, NULL, in/**qu->seq**/, tu->seq, exz, NULL/**v_idx?v_idx->a.a:NULL**/, w.window_length, -1, err, (e_max+0.000001), THRESHOLD_MAX_SIZE, 1, &re);
            z->is_match = 0;///must be here;
            
            // if(z->x_id == 57 && z->y_id == 2175) { 
            //     fprintf(stderr, "+utg%.6u%c\t%u\t%u\t%u\t%c\tutg%.6u%c\t%u\t%u\t%u\talign_length::%u\terr::%f\trr::%f\twn::%u\tk::%lu\ti::%lu\n", 
            //         z->x_id+1, "lc"[uref->ug->u.a[z->x_id].circ], uref->ug->u.a[z->x_id].len, 
            //         z->x_pos_s, z->x_pos_e+1, "+-"[z->y_pos_strand],
            //         z->y_id+1, "lc"[uref->ug->u.a[z->y_id].circ], uref->ug->u.a[z->y_id].len, 
            //         z->y_pos_s, z->y_pos_e+1, z->align_length, err, rr, (uint32_t)z->w_list.n/**gen_nkhits(cl, z)**/,
            //         k, i);
            // }
            if (rr <= err) {
                if(k != i) {
                    t = ol->list[k];
                    ol->list[k] = ol->list[i];
                    ol->list[i] = t;
                }
                ol->list[k].is_match = 1; ol->list[k].non_homopolymer_errors = re;
                k++;
            } 
        }

        ol->length = k;
        // if(sid == 57) { 
        //     fprintf(stderr, "+utg%.6ld%c\tol->length::%lu\n", sid+1, "lc"[uref->ug->u.a[sid].circ], ol->length);
        // }
        if(ol->length <= 0) return;
    } else {
        // if(ol->length <= 1) return;
        if(ol->length <= 0) return;
        if(qu) {
            resize_UC_Read(qu, ql); qu->length = ql; memcpy(qu->seq, qstr, ql); in = qu->seq;
        } 
        for (i = k = 0; i < ol->length; i++) {
            z = &(ol->list[i]); 
            // if(z->x_id == 57 && z->y_id == 2175) { 
            //     fprintf(stderr, "-1-utg%.6u%c\t%u\t%u\t%u\t%c\tutg%.6u%c\t%u\t%u\t%u\talign_length::%u\terr::%f\twn::%u\tk::%lu\ti::%lu\n", 
            //         z->x_id+1, "lc"[uref->ug->u.a[z->x_id].circ], uref->ug->u.a[z->x_id].len, 
            //         z->x_pos_s, z->x_pos_e+1, "+-"[z->y_pos_strand],
            //         z->y_id+1, "lc"[uref->ug->u.a[z->y_id].circ], uref->ug->u.a[z->y_id].len, 
            //         z->y_pos_s, z->y_pos_e+1, z->align_length, err, (uint32_t)z->w_list.n/**gen_nkhits(cl, z)**/,
            //         k, i);
            // }
            if(!ul_raw_aln(z, cl, uref, in/**qu->seq**/, tu, exz, err, wl, ql, sid, khit, aux_o)) {
                z->is_match = 0;
                continue;
            }

            // if(z->x_id == 57 && z->y_id == 2175) { 
            //     fprintf(stderr, "-2-utg%.6u%c\t%u\t%u\t%u\t%c\tutg%.6u%c\t%u\t%u\t%u\talign_length::%u\terr::%f\twn::%u\tk::%lu\ti::%lu\n", 
            //         z->x_id+1, "lc"[uref->ug->u.a[z->x_id].circ], uref->ug->u.a[z->x_id].len, 
            //         z->x_pos_s, z->x_pos_e+1, "+-"[z->y_pos_strand],
            //         z->y_id+1, "lc"[uref->ug->u.a[z->y_id].circ], uref->ug->u.a[z->y_id].len, 
            //         z->y_pos_s, z->y_pos_e+1, z->align_length, err, (uint32_t)z->w_list.n/**gen_nkhits(cl, z)**/,
            //         k, i);
            // }
            if(k != i) {
                t = ol->list[k];
                ol->list[k] = ol->list[i];
                ol->list[i] = t;
            }
            ol->list[k].is_match = 1; 
            k++;
        }
        ol->length = k;

        // if(sid == 57) { 
        //     fprintf(stderr, "-utg%.6ld%c\tol->length::%lu\n", sid+1, "lc"[uref->ug->u.a[sid].circ], ol->length);
        // }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x1c0, %rsp            # imm = 0x1C0
movq 0x58(%rbp), %rax
movq 0x50(%rbp), %rax
movq 0x48(%rbp), %rax
movq 0x40(%rbp), %rax
movq 0x38(%rbp), %rax
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movq %rdx, -0x28(%rbp)
movq %rcx, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq %r9, -0x40(%rbp)
movsd %xmm0, -0x48(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x18(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, 0x10(%rax)
ja 0x9bc1a
jmp 0x9c296
movq 0x20(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq 0x58(%rbp), %rdx
callq 0x4c460
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0xc0(%rbp)
movq -0x40(%rbp), %rsi
movq 0x38(%rbp), %rdx
movsd 0x2e63b8(%rip), %xmm0   # 0x382000
divsd -0xc0(%rbp), %xmm0
cvttsd2si %xmm0, %eax
movslq %eax, %rcx
leaq -0xb8(%rbp), %rdi
callq 0x9f470
movq -0xb0(%rbp), %rax
addq $0x3e, %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movq 0x18(%rbp), %rdi
movq -0x58(%rbp), %rsi
shlq %rsi
callq 0xa62c0
cmpq $0x0, 0x30(%rbp)
jne 0x9c0df
cmpq $0x0, 0x10(%rbp)
je 0x9bcd3
movq 0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0xa62c0
movq -0x40(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq 0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x2180
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x178(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x9bed0
movq -0x18(%rbp), %rax
movq (%rax), %rax
imulq $0xa8, -0x50(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x170(%rbp)
movq -0x170(%rbp), %rax
movl 0x8(%rax), %eax
addl $0x1, %eax
movq -0x170(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0x68(%rbp)
movq -0x170(%rbp), %rax
movl 0x30(%rax), %ecx
movq -0x170(%rbp), %rax
movl %ecx, 0x24(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x170(%rbp), %rcx
movslq 0x24(%rcx), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %eax, %eax
movq %rax, -0x70(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x78(%rbp)
movq $0x0, -0x80(%rbp)
movq -0x170(%rbp), %rax
movslq 0x24(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rcx
xorl %eax, %eax
cmpq -0x78(%rbp), %rcx
movb %al, -0x191(%rbp)
jae 0x9bdce
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x60(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %eax, %eax
movl %eax, %ecx
xorl %eax, %eax
cmpq -0x70(%rbp), %rcx
movb %al, -0x191(%rbp)
jne 0x9bdce
movq -0x80(%rbp), %rax
cmpq 0x50(%rbp), %rax
setb %al
movb %al, -0x191(%rbp)
movb -0x191(%rbp), %al
testb $0x1, %al
jne 0x9bdda
jmp 0x9bdf4
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x9bd80
movq -0x80(%rbp), %rax
cmpq 0x50(%rbp), %rax
jae 0x9be03
jmp 0x9bebf
movq -0x170(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x178(%rbp), %rcx
movq 0x18(%rbp), %rax
movq (%rax), %r8
movq 0x28(%rbp), %r9
movsd -0xc0(%rbp), %xmm0
movq -0xb0(%rbp), %r10
movq 0x58(%rbp), %rax
xorl %edx, %edx
movsd 0x2e643b(%rip), %xmm1   # 0x382278
movq %r10, (%rsp)
movq $0x0, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x50850
cmpl $0x0, %eax
jne 0x9be5b
jmp 0x9bebf
cmpq $0x0, -0x28(%rbp)
je 0x9bebd
movq -0x68(%rbp), %rdi
movq -0x170(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, %esi
movq -0x28(%rbp), %rcx
xorl %edx, %edx
movl $0x1, %eax
cmpq $0x0, %rcx
cmovnel %eax, %edx
movsd 0x2e63ec(%rip), %xmm0   # 0x382278
xorl %eax, %eax
movl %eax, %ecx
callq 0xa7100
cmpl $0x0, %eax
je 0x9bebd
movq -0x170(%rbp), %rax
movb $0x3, 0x2c(%rax)
movq -0x170(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
addq 0x18(%rax), %rcx
movq %rcx, 0x18(%rax)
jmp 0x9bebf
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x9bcdb
movsd 0x2e6328(%rip), %xmm0   # 0x382200
mulsd -0xc0(%rbp), %xmm0
movsd %xmm0, -0x180(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x9c0be
movq -0x18(%rbp), %rax
movq (%rax), %rax
imulq $0xa8, -0x50(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x170(%rbp)
movq -0x170(%rbp), %rax
movl 0x8(%rax), %eax
addl $0x1, %eax
movq -0x170(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0x68(%rbp)
movq -0x170(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x178(%rbp), %r8
movq 0x18(%rbp), %rax
movq (%rax), %r9
movq 0x28(%rbp), %r11
movq -0xb0(%rbp), %r10
movsd -0xc0(%rbp), %xmm1
movsd 0x2e630c(%rip), %xmm2   # 0x382280
addsd -0x180(%rbp), %xmm2
xorl %eax, %eax
movl %eax, %ecx
movsd 0x2e62f0(%rip), %xmm0   # 0x382278
leaq -0x190(%rbp), %rax
movq %rcx, %rdx
movq %r11, (%rsp)
movq $0x0, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq $0x1f, 0x18(%rsp)
movq $0x1, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0x52e60
movsd %xmm0, -0x188(%rbp)
movq -0x170(%rbp), %rax
movb $0x0, 0x2c(%rax)
movsd -0x188(%rbp), %xmm1
movsd -0xc0(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x9c0ab
movq -0x60(%rbp), %rax
cmpq -0x50(%rbp), %rax
je 0x9c06b
movq -0x18(%rbp), %rax
movq (%rax), %rsi
imulq $0xa8, -0x60(%rbp), %rax
addq %rax, %rsi
leaq -0x168(%rbp), %rdi
movl $0xa8, %edx
callq 0x2180
movq -0x18(%rbp), %rax
movq (%rax), %rsi
imulq $0xa8, -0x50(%rbp), %rax
addq %rax, %rsi
movq -0x18(%rbp), %rax
movq (%rax), %rdi
imulq $0xa8, -0x60(%rbp), %rax
addq %rax, %rdi
movl $0xa8, %edx
callq 0x2180
movq -0x18(%rbp), %rax
movq (%rax), %rdi
imulq $0xa8, -0x50(%rbp), %rax
addq %rax, %rdi
leaq -0x168(%rbp), %rsi
movl $0xa8, %edx
callq 0x2180
movq -0x18(%rbp), %rax
movq (%rax), %rax
imulq $0xa8, -0x60(%rbp), %rcx
addq %rcx, %rax
movb $0x1, 0x2c(%rax)
movq -0x190(%rbp), %rax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq (%rax), %rax
imulq $0xa8, -0x60(%rbp), %rdx
addq %rdx, %rax
movl %ecx, 0x30(%rax)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x9c0ad
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x9bef8
movq -0x60(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, 0x10(%rax)
ja 0x9c0da
jmp 0x9c296
jmp 0x9c296
movq -0x18(%rbp), %rax
cmpq $0x0, 0x10(%rax)
ja 0x9c0ef
jmp 0x9c296
cmpq $0x0, 0x10(%rbp)
je 0x9c131
movq 0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0xa62c0
movq -0x40(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq 0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x2180
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x178(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0x9c28a
movq -0x18(%rbp), %rax
movq (%rax), %rax
imulq $0xa8, -0x50(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x170(%rbp)
movq -0x170(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x178(%rbp), %rcx
movq 0x18(%rbp), %r8
movq 0x28(%rbp), %r9
movsd -0xc0(%rbp), %xmm0
movq 0x38(%rbp), %r14
movq -0x40(%rbp), %rbx
movq 0x40(%rbp), %r11
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %rax
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x98210
cmpq $0x0, %rax
jne 0x9c1d9
movq -0x170(%rbp), %rax
movb $0x0, 0x2c(%rax)
jmp 0x9c279
movq -0x60(%rbp), %rax
cmpq -0x50(%rbp), %rax
je 0x9c257
movq -0x18(%rbp), %rax
movq (%rax), %rsi
imulq $0xa8, -0x60(%rbp), %rax
addq %rax, %rsi
leaq -0x168(%rbp), %rdi
movl $0xa8, %edx
callq 0x2180
movq -0x18(%rbp), %rax
movq (%rax), %rsi
imulq $0xa8, -0x50(%rbp), %rax
addq %rax, %rsi
movq -0x18(%rbp), %rax
movq (%rax), %rdi
imulq $0xa8, -0x60(%rbp), %rax
addq %rax, %rdi
movl $0xa8, %edx
callq 0x2180
movq -0x18(%rbp), %rax
movq (%rax), %rdi
imulq $0xa8, -0x50(%rbp), %rax
addq %rax, %rdi
leaq -0x168(%rbp), %rsi
movl $0xa8, %edx
callq 0x2180
movq -0x18(%rbp), %rax
movq (%rax), %rax
imulq $0xa8, -0x60(%rbp), %rcx
addq %rcx, %rax
movb $0x1, 0x2c(%rax)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x9c141
movq -0x60(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbx
popq %r14
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)