// File: chhylp123[P]hifiasm/Correct.cpp
// Function: ul_local_aln(overlap_region*, Candidates_list*, ul_idx_t const*, char*, UC_Read*, bit_extz_t*, double, long, unsigned long, double, kv_ul_ov_t*, kv_ul_ov_t*, kv_rtrace_t*, unsigned long, unsigned long, unsigned long, unsigned long, overlap_region*)
uint64_t ul_local_aln(overlap_region *z, Candidates_list *cl, const ul_idx_t *udb, char* qstr, UC_Read *tu, 
bit_extz_t *exz, double e_rate, int64_t w_l, uint64_t min_ovlp, double o_rate, kv_ul_ov_t *rln, kv_ul_ov_t *cln,
kv_rtrace_t *trace, uint64_t ql, uint64_t rid, uint64_t oid, uint64_t khit, overlap_region *aux_o)
{   
    uint64_t ol, aln_ol, cn, k, mm, rln_0; ul_contain *ct = udb->ct; utg_ct_t *ca; ul_ov_t *p;
    if(!aux_o) {
        align_ul_ed_post_extz(z, udb, NULL, qstr, tu->seq, exz, e_rate, w_l, -1, 1, NULL); 
        ol = z->x_pos_e+1-z->x_pos_s, aln_ol = z->align_length;
        if(aln_ol >= (ol*o_rate)) return 1;
        if(aln_ol <= min_ovlp) return 0;
        // fprintf(stderr, "***[M::%s::aln_ol->%lu] utg%.6dl(%c), align::%u, q::[%u, %u), t::[%u, %u)\n", __func__, aln_ol,
        //         (int32_t)z->y_id + 1, "+-"[z->y_pos_strand], z->align_length,
        //         z->x_pos_s, z->x_pos_e+1, z->y_pos_s, z->y_pos_e+1);
        mm = win_cluster_fliter(z->w_list.a, z->w_list.n, min_ovlp, o_rate/2);
        // print_aln_windows(z);
        // fprintf(stderr, "***[M::%s::] mm::%lu\n", __func__, mm);
        return mm;
    } else {
        ol = z->x_pos_e+1-z->x_pos_s; aln_ol = z->align_length;
        if(aln_ol <= min_ovlp) return 0;
        // if(z->y_id == 700) {
        //     fprintf(stderr, "+[M::%s::aln_ol->%lu::o_rate->%f] utg%.6dl(%c), align::%u, q::[%u, %u), t::[%u, %u), ql::%lu\n", 
        //             __func__, aln_ol, o_rate, 
        //             (int32_t)z->y_id + 1, "+-"[z->y_pos_strand], z->align_length,
        //             z->x_pos_s, z->x_pos_e+1, z->y_pos_s, z->y_pos_e+1, ql);
        //     print_aln_windows(z);
        // }
        rln_0 = rln->n;
        if((ol*o_rate) <= aln_ol) {
            kv_pushp(ul_ov_t, *rln, &p); memset(p, 0, sizeof(*p));
            ///[ts, te) -> whole interval rid at the unitig adjusted by the reverse 
            p->ts = z->y_pos_s; p->te = z->y_pos_e+1; 
            p->qs = z->x_pos_s; p->qe = z->x_pos_e+1;
            p->rev = z->y_pos_strand; p->el = 0; p->tn = p->qn = (uint32_t)-1;
        } else {
            cn = ((uint32_t)(ct->idx.a[z->y_id])); 
            ca = ct->rids.a + ((ct->idx.a[z->y_id])>>32);
            gen_sub_ov_adv(udb, z, o_rate, NULL, 0, rln);
            gen_sub_ov_adv(udb, z, o_rate, ca, cn, rln);
        }

        if(rln->n <= rln_0) return 0;
        radix_sort_ul_ov_srt_qs1(rln->a+rln_0, rln->a+rln->n);
        // if(z->y_id == 700) {
        //     for (k = 0; k < rln->n; k++) {
        //         p = &(rln->a[k]);
        //         fprintf(stderr, "+[M::%s::k->%lu] candidate_q::[%u, %u)\n", __func__, k, p->qs, p->qe);
        //     }
        // }

        for (k = mm = rln_0, p = NULL; k < rln->n; k++) {
            if((!p) || (rln->a[k].qs >= p->qe)) p = NULL;
            if(p) {
                if((rln->a[k].qs<p->qe)&&(rln->a[k].qe>p->qe)) {
                    p->qe = rln->a[k].qe; 
                }
            } else {
                p = &(rln->a[mm++]); *p = rln->a[k];
            }
        }
        rln->n = mm;
        // if(z->y_id == 700) {
        //     for (k = 0; k < rln->n; k++) {
        //         p = &(rln->a[k]);
        //         fprintf(stderr, "-[M::%s::k->%lu] candidate_q::[%u, %u)\n", __func__, k, p->qs, p->qe);
        //     }
        // }

        return_t_chain(z, cl);
        cigar_gen_by_chain_adv_local(z, cl, rln->a+rln_0, rln->n-rln_0, w_l, udb, NULL, NULL, qstr, tu, exz, aux_o, e_rate, ql, rid, khit);
        
        // fprintf(stderr, "-[M::%s::aln_ol->%lu] utg%.6dl(%c), align::%u, q::[%u, %u), t::[%u, %u)\n", __func__, aln_ol,
        //         (int32_t)z->y_id + 1, "+-"[z->y_pos_strand], z->align_length,
        //         z->x_pos_s, z->x_pos_e+1, z->y_pos_s, z->y_pos_e+1);
        // print_aln_windows(z);


        rln->n = rln_0;
        cn = ((uint32_t)(ct->idx.a[z->y_id])); 
        ca = ct->rids.a + ((ct->idx.a[z->y_id])>>32);
        gen_sub_ov_adv_cigar(udb, z, qstr, tu, exz, ql, o_rate, e_rate, NULL, 0, rid, oid, trace, rln);
        gen_sub_ov_adv_cigar(udb, z, qstr, tu, exz, ql, o_rate, e_rate, ca, cn, rid, oid, trace, cln);
        return 1;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
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, -0x38(%rbp)
movq %rsi, -0x40(%rbp)
movq %rdx, -0x48(%rbp)
movq %rcx, -0x50(%rbp)
movq %r8, -0x58(%rbp)
movq %r9, -0x60(%rbp)
movsd %xmm0, -0x68(%rbp)
movsd %xmm1, -0x70(%rbp)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, 0x58(%rbp)
jne 0x97c0b
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x50(%rbp), %rcx
movq -0x58(%rbp), %rax
movq (%rax), %r8
movq -0x60(%rbp), %r9
movsd -0x68(%rbp), %xmm0
movq 0x10(%rbp), %rdx
movq %rsp, %rax
movq %rdx, (%rax)
movq $0x0, 0x10(%rax)
movq $0x1, 0x8(%rax)
xorl %eax, %eax
movl %eax, %edx
movsd 0x2ea73e(%rip), %xmm1   # 0x382278
callq 0x50850
movq -0x38(%rbp), %rax
movl 0x4(%rax), %ecx
movl 0x8(%rax), %eax
subl %ecx, %eax
incl %eax
movq %rax, -0x78(%rbp)
movq -0x38(%rbp), %rax
movl 0x28(%rax), %eax
movq %rax, -0x80(%rbp)
movaps 0x2ea4ad(%rip), %xmm3   # 0x382010
movq -0x80(%rbp), %xmm0
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x2ea4ac(%rip), %xmm2   # 0x382020
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq -0x78(%rbp), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
mulsd -0x70(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jb 0x97bb3
movq $0x1, -0x30(%rbp)
jmp 0x981f0
movq -0x80(%rbp), %rax
cmpq 0x18(%rbp), %rax
ja 0x97bca
movq $0x0, -0x30(%rbp)
jmp 0x981f0
movq -0x38(%rbp), %rax
movq 0x58(%rax), %rdi
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rsi
movq 0x18(%rbp), %rdx
movsd -0x70(%rbp), %xmm0
movsd 0x2ea6fd(%rip), %xmm1   # 0x3822e8
divsd %xmm1, %xmm0
callq 0x97540
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x981f0
movq -0x38(%rbp), %rax
movl 0x8(%rax), %eax
addl $0x1, %eax
movq -0x38(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0x78(%rbp)
movq -0x38(%rbp), %rax
movl 0x28(%rax), %eax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
cmpq 0x18(%rbp), %rax
ja 0x97c44
movq $0x0, -0x30(%rbp)
jmp 0x981f0
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xa0(%rbp)
movaps 0x2ea3b6(%rip), %xmm3   # 0x382010
movq -0x78(%rbp), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x2ea3b5(%rip), %xmm2   # 0x382020
subpd %xmm2, %xmm1
movaps %xmm1, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm0, %xmm1
movsd -0x70(%rbp), %xmm0
mulsd %xmm0, %xmm1
movq -0x80(%rbp), %xmm0
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm2
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x97df1
jmp 0x97ca7
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x97d14
movq 0x20(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x97cd8
movq 0x20(%rbp), %rax
movq 0x10(%rax), %rax
shlq %rax
movq %rax, -0xc0(%rbp)
jmp 0x97ce6
movl $0x2, %eax
movq %rax, -0xc0(%rbp)
jmp 0x97ce6
movq -0xc0(%rbp), %rcx
movq 0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
movq 0x20(%rbp), %rax
movq (%rax), %rdi
movq 0x20(%rbp), %rax
imulq $0x1c, 0x10(%rax), %rsi
callq 0x2360
movq %rax, %rcx
movq 0x20(%rbp), %rax
movq %rcx, (%rax)
movq 0x20(%rbp), %rax
movq (%rax), %rax
movq 0x20(%rbp), %rdx
movq 0x8(%rdx), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, 0x8(%rdx)
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rdi
xorl %esi, %esi
movl $0x1c, %edx
callq 0x2100
movq -0x38(%rbp), %rax
movl 0x14(%rax), %ecx
movq -0xb8(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x38(%rbp), %rax
movl 0x18(%rax), %ecx
addl $0x1, %ecx
movq -0xb8(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x38(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0xb8(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movq -0xb8(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x38(%rbp), %rax
movl 0x1c(%rax), %edx
movq -0xb8(%rbp), %rax
movl 0x18(%rax), %ecx
andl $0x1, %edx
shll $0x1f, %edx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
orl %edx, %ecx
movl %ecx, 0x18(%rax)
movq -0xb8(%rbp), %rax
movl 0x18(%rax), %ecx
andl $0xbfffffff, %ecx       # imm = 0xBFFFFFFF
orl $0x0, %ecx
movl %ecx, 0x18(%rax)
movq -0xb8(%rbp), %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movq -0xb8(%rbp), %rax
movl $0xffffffff, 0xc(%rax)  # imm = 0xFFFFFFFF
jmp 0x97e84
movq -0xa8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x38(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, %eax
movq %rax, -0x88(%rbp)
movq -0xa8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0xa8(%rbp), %rcx
movq 0x10(%rcx), %rcx
movq -0x38(%rbp), %rdx
movl 0x10(%rdx), %edx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rsi
movsd -0x70(%rbp), %xmm0
movq 0x20(%rbp), %r8
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x8d5d0
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rsi
movsd -0x70(%rbp), %xmm0
movq -0xb0(%rbp), %rdx
movq -0x88(%rbp), %rcx
movq 0x20(%rbp), %r8
callq 0x8d5d0
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpq -0xa0(%rbp), %rax
ja 0x97ea2
movq $0x0, -0x30(%rbp)
jmp 0x981f0
movq 0x20(%rbp), %rax
movq (%rax), %rdi
imulq $0x1c, -0xa0(%rbp), %rax
addq %rax, %rdi
movq 0x20(%rbp), %rax
movq (%rax), %rsi
movq 0x20(%rbp), %rax
imulq $0x1c, 0x8(%rax), %rax
addq %rax, %rsi
callq 0x30750
movq -0xa0(%rbp), %rax
movq %rax, -0x98(%rbp)
movq %rax, -0x90(%rbp)
movq $0x0, -0xb8(%rbp)
movq -0x90(%rbp), %rax
movq 0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x9801c
cmpq $0x0, -0xb8(%rbp)
je 0x97f2c
movq 0x20(%rbp), %rax
movq (%rax), %rax
imulq $0x1c, -0x90(%rbp), %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movq -0xb8(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jb 0x97f37
movq $0x0, -0xb8(%rbp)
cmpq $0x0, -0xb8(%rbp)
je 0x97fa4
movq 0x20(%rbp), %rax
movq (%rax), %rax
imulq $0x1c, -0x90(%rbp), %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movq -0xb8(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jae 0x97fa2
movq 0x20(%rbp), %rax
movq (%rax), %rax
imulq $0x1c, -0x90(%rbp), %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movq -0xb8(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jbe 0x97fa2
movq 0x20(%rbp), %rax
movq (%rax), %rax
imulq $0x1c, -0x90(%rbp), %rcx
addq %rcx, %rax
movl 0x8(%rax), %ecx
movq -0xb8(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x98003
movq 0x20(%rbp), %rax
movq (%rax), %rax
movq -0x98(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x98(%rbp)
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
movq 0x20(%rbp), %rax
movq (%rax), %rcx
imulq $0x1c, -0x90(%rbp), %rax
addq %rax, %rcx
movq -0xb8(%rbp), %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rax)
movl 0x18(%rcx), %ecx
movl %ecx, 0x18(%rax)
jmp 0x98005
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x97eec
movq -0x98(%rbp), %rcx
movq 0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x8db80
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq 0x20(%rbp), %rax
movq (%rax), %rdx
imulq $0x1c, -0xa0(%rbp), %rax
addq %rax, %rdx
movq 0x20(%rbp), %rax
movq 0x8(%rax), %rcx
subq -0xa0(%rbp), %rcx
movq 0x10(%rbp), %r8
movq -0x48(%rbp), %r9
movq -0x50(%rbp), %r12
movq -0x58(%rbp), %r15
movq -0x60(%rbp), %r14
movq 0x58(%rbp), %rbx
movsd -0x68(%rbp), %xmm0
movq 0x38(%rbp), %r11
movq 0x40(%rbp), %r10
movq 0x50(%rbp), %rax
xorl %r13d, %r13d
movq $0x0, (%rsp)
movq $0x0, 0x8(%rsp)
movq %r12, 0x10(%rsp)
movq %r15, 0x18(%rsp)
movq %r14, 0x20(%rsp)
movq %rbx, 0x28(%rsp)
movq %r11, 0x30(%rsp)
movq %r10, 0x38(%rsp)
movq %rax, 0x40(%rsp)
callq 0x68d10
movq -0xa0(%rbp), %rcx
movq 0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0xa8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x38(%rbp), %rcx
movl 0x10(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, %eax
movq %rax, -0x88(%rbp)
movq -0xa8(%rbp), %rax
movq 0x28(%rax), %rax
movq -0xa8(%rbp), %rcx
movq 0x10(%rcx), %rcx
movq -0x38(%rbp), %rdx
movl 0x10(%rdx), %edx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq -0x58(%rbp), %rcx
movq -0x60(%rbp), %r8
movq 0x38(%rbp), %r9
movsd -0x70(%rbp), %xmm0
movsd -0x68(%rbp), %xmm1
movq 0x40(%rbp), %rbx
movq 0x48(%rbp), %r11
movq 0x30(%rbp), %r10
movq 0x20(%rbp), %rax
xorl %r14d, %r14d
movq $0x0, (%rsp)
movq $0x0, 0x8(%rsp)
movq %rbx, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movq %r10, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0x96b90
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq -0x58(%rbp), %rcx
movq -0x60(%rbp), %r8
movq 0x38(%rbp), %r9
movsd -0x70(%rbp), %xmm0
movsd -0x68(%rbp), %xmm1
movq -0xb0(%rbp), %r15
movq -0x88(%rbp), %r14
movq 0x40(%rbp), %rbx
movq 0x48(%rbp), %r11
movq 0x30(%rbp), %r10
movq 0x28(%rbp), %rax
movq %r15, (%rsp)
movq %r14, 0x8(%rsp)
movq %rbx, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movq %r10, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0x96b90
movq $0x1, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopw %cs:(%rax,%rax)