// File: chhylp123[P]hifiasm/Correct.cpp
// Function: hc_aln_exz_adv_hc(overlap_region*, ul_idx_t const*, hpc_t*, All_reads*, char*, UC_Read*, long, long, long, long, long, long, bit_extz_t*, long, double, long, long, long, long, overlap_region*)
int64_t hc_aln_exz_adv_hc(overlap_region *z, const ul_idx_t *uref, hpc_t *hpc_g, All_reads *rref, 
char* qstr, UC_Read *tu, int64_t qs, int64_t qe, int64_t ts, int64_t te, int64_t mode, int64_t wl, 
bit_extz_t *exz, int64_t q_tot, double e_rate, int64_t maxl, int64_t maxe, int64_t force_l, 
int64_t estimate_err, overlap_region *aux_o)
{
    clear_align(*exz); exz->thre = 0; 
    if(((ts == -1) && (te == -1))) mode = 3;///set to semi-global
    int64_t thre, ql = qe - qs, thre0, pts = -1, pte = -1, pthre = -1, full = 0;
    if(ql == 0 && (te-ts) == 0) return 1;
    if((ql <= 0) || (te-ts) <= 0) return 0;
    if(estimate_err < 0) estimate_err = cal_estimate_err_hc(z, wl, qs, qe, ts, te, e_rate, &full);
    

    
    // if(ql <= 16) {
    if(estimate_err == 0) {
        if(full) {
            // if(!cal_exact_exz(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, q_tot, mode)) {
            //     fprintf(stderr, "[M::%s::ql::%ld::%c] xid::%d, yid::%d, qs::[%ld, %ld), ts::[%ld, %ld), mode::%ld, est_err::%ld, e_rate::%f, maxe::%ld\n", 
            //                                             __func__, ql, "+-"[z->y_pos_strand], z->x_id, z->y_id, qs, qe, ts, te, mode, estimate_err, e_rate, maxe);
            //     exit(1);
            // }
            set_exact_exz(exz, qs, qe, ts, te); push_alnw(aux_o, exz);
            return 1;
        } else if(cal_exact_exz(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, q_tot, mode)) {
            // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
            // fprintf(stderr, ", err::%d, thre::%d, scale::0(+)\n", exz->err, exz->thre);
            push_alnw(aux_o, exz);
            return 1;
        }
    }

    if(ql <= maxl && (estimate_err>>1) <= maxe) {
        thre = scale_ed_thre(estimate_err, maxe); 
        if(cal_exz_infi_adv(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, thre, &pthre, q_tot, mode)) {
            // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
            // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(+)\n", exz->err, exz->thre, thre);
            push_alnw(aux_o, exz);
            return 1;
        }

        thre0 = thre; thre = ql*e_rate; thre = scale_ed_thre(thre, maxe); 
        if(thre > thre0) {
            if(cal_exz_infi_adv(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, thre, &pthre, q_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(-)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }

        thre0 = thre; thre <<= 1; thre = scale_ed_thre(thre, maxe); 
        if(thre > thre0) {
            if(cal_exz_infi_adv(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, thre, &pthre, q_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(-)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }

        thre0 = thre; thre = ql*0.51; thre = scale_ed_thre(thre, maxe); 
        if(thre > thre0) {
            if(cal_exz_infi_adv(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, thre, &pthre, q_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(*)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }

        if(ql <= force_l) {
            thre = maxe; 
            if(cal_exz_infi_adv(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, thre, &pthre, q_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(*)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }
    }
    // fprintf(stderr, ", err::%d, thre::%d\n", INT32_MAX, exz->thre);
    // if(mode == 0) {
    //     fprintf(stderr, "[M::%s::] pstr::%.*s\n", __func__, (int32_t)tu->length, tu->seq);
    //     fprintf(stderr, "[M::%s::] tstr::%.*s\n", __func__, (int32_t)(qe-qs), qstr+qs);
    // }
    return 0;
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq 0x70(%rbp), %rax
movq 0x68(%rbp), %rax
movq 0x60(%rbp), %rax
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)
movq 0x40(%rbp), %rax
movl $0x7fffffff, 0x2c(%rax) # imm = 0x7FFFFFFF
movq 0x40(%rbp), %rax
movl $0x0, 0x28(%rax)
cmpq $-0x1, 0x20(%rbp)
jne 0x61c81
cmpq $-0x1, 0x28(%rbp)
jne 0x61c81
movq $0x3, 0x30(%rbp)
movq 0x18(%rbp), %rax
subq 0x10(%rbp), %rax
movq %rax, -0x78(%rbp)
movq $-0x1, -0x88(%rbp)
movq $-0x1, -0x90(%rbp)
movq $-0x1, -0x98(%rbp)
movq $0x0, -0xa0(%rbp)
cmpq $0x0, -0x78(%rbp)
jne 0x61cdb
movq 0x28(%rbp), %rax
subq 0x20(%rbp), %rax
cmpq $0x0, %rax
jne 0x61cdb
movq $0x1, -0x30(%rbp)
jmp 0x62350
cmpq $0x0, -0x78(%rbp)
jle 0x61cf0
movq 0x28(%rbp), %rax
subq 0x20(%rbp), %rax
cmpq $0x0, %rax
jg 0x61cfd
movq $0x0, -0x30(%rbp)
jmp 0x62350
cmpq $0x0, 0x68(%rbp)
jge 0x61d35
movq -0x38(%rbp), %rdi
movq 0x38(%rbp), %rsi
movq 0x10(%rbp), %rdx
movq 0x18(%rbp), %rcx
movq 0x20(%rbp), %r8
movq 0x28(%rbp), %r9
movsd -0x68(%rbp), %xmm0
leaq -0xa0(%rbp), %rax
movq %rax, (%rsp)
callq 0x5e0e0
movq %rax, 0x68(%rbp)
cmpq $0x0, 0x68(%rbp)
jne 0x61e22
cmpq $0x0, -0xa0(%rbp)
je 0x61d7d
movq 0x40(%rbp), %rdi
movq 0x10(%rbp), %rsi
movq 0x18(%rbp), %rdx
movq 0x20(%rbp), %rcx
movq 0x28(%rbp), %r8
callq 0x61ae0
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq 0x40(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x60(%rbp), %rax
movq 0x10(%rbp), %r13
movq 0x18(%rbp), %r12
movq 0x20(%rbp), %r15
movq 0x28(%rbp), %r14
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %r11
movq %r11, -0xa8(%rbp)
leaq -0x88(%rbp), %rbx
leaq -0x90(%rbp), %r11
movq %rax, (%rsp)
movq -0xa8(%rbp), %rax
movq %r13, 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 0x5f880
cmpq $0x0, %rax
je 0x61e1e
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
jmp 0x61e20
jmp 0x61e22
movq -0x78(%rbp), %rax
cmpq 0x50(%rbp), %rax
jg 0x62348
movq 0x68(%rbp), %rax
sarq %rax
cmpq 0x58(%rbp), %rax
jg 0x62348
movq 0x68(%rbp), %rax
movl %eax, %edi
movq 0x58(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x70(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq 0x40(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x60(%rbp), %rax
movq 0x10(%rbp), %r10
movq %r10, -0xc0(%rbp)
movq 0x18(%rbp), %r10
movq %r10, -0xb8(%rbp)
movq 0x20(%rbp), %r13
movq 0x28(%rbp), %r12
movq -0x70(%rbp), %rbx
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %r11
movq %r11, -0xb0(%rbp)
leaq -0x88(%rbp), %r15
leaq -0x90(%rbp), %r14
leaq -0x98(%rbp), %r11
movq %rax, (%rsp)
movq -0xc0(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xb8(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0xb0(%rbp), %rax
movq %r13, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movq %r11, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x5eff0
cmpq $0x0, %rax
je 0x61f28
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
movq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
cvtsi2sdq -0x78(%rbp), %xmm0
mulsd -0x68(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl %eax, %edi
movq 0x58(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x80(%rbp), %rax
jle 0x6203b
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq 0x40(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x60(%rbp), %rax
movq 0x10(%rbp), %r10
movq %r10, -0xd8(%rbp)
movq 0x18(%rbp), %r10
movq %r10, -0xd0(%rbp)
movq 0x20(%rbp), %r13
movq 0x28(%rbp), %r12
movq -0x70(%rbp), %rbx
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %r11
movq %r11, -0xc8(%rbp)
leaq -0x88(%rbp), %r15
leaq -0x90(%rbp), %r14
leaq -0x98(%rbp), %r11
movq %rax, (%rsp)
movq -0xd8(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xd0(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0xc8(%rbp), %rax
movq %r13, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movq %r11, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x5eff0
cmpq $0x0, %rax
je 0x62039
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
jmp 0x6203b
movq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x70(%rbp), %rax
shlq %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl %eax, %edi
movq 0x58(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x80(%rbp), %rax
jle 0x62145
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq 0x40(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x60(%rbp), %rax
movq 0x10(%rbp), %r10
movq %r10, -0xf0(%rbp)
movq 0x18(%rbp), %r10
movq %r10, -0xe8(%rbp)
movq 0x20(%rbp), %r13
movq 0x28(%rbp), %r12
movq -0x70(%rbp), %rbx
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %r11
movq %r11, -0xe0(%rbp)
leaq -0x88(%rbp), %r15
leaq -0x90(%rbp), %r14
leaq -0x98(%rbp), %r11
movq %rax, (%rsp)
movq -0xf0(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xe8(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0xe0(%rbp), %rax
movq %r13, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movq %r11, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x5eff0
cmpq $0x0, %rax
je 0x62143
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
jmp 0x62145
movq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
cvtsi2sdq -0x78(%rbp), %xmm0
movsd 0x32015d(%rip), %xmm1   # 0x3822b8
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl %eax, %edi
movq 0x58(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x80(%rbp), %rax
jle 0x6225f
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq 0x40(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x60(%rbp), %rax
movq 0x10(%rbp), %r10
movq %r10, -0x108(%rbp)
movq 0x18(%rbp), %r10
movq %r10, -0x100(%rbp)
movq 0x20(%rbp), %r13
movq 0x28(%rbp), %r12
movq -0x70(%rbp), %rbx
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %r11
movq %r11, -0xf8(%rbp)
leaq -0x88(%rbp), %r15
leaq -0x90(%rbp), %r14
leaq -0x98(%rbp), %r11
movq %rax, (%rsp)
movq -0x108(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0x100(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0xf8(%rbp), %rax
movq %r13, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movq %r11, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x5eff0
cmpq $0x0, %rax
je 0x6225d
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
jmp 0x6225f
movq -0x78(%rbp), %rax
cmpq 0x60(%rbp), %rax
jg 0x62346
movq 0x58(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq 0x40(%rbp), %r8
movq -0x58(%rbp), %r9
movq -0x60(%rbp), %rax
movq 0x10(%rbp), %r10
movq %r10, -0x120(%rbp)
movq 0x18(%rbp), %r10
movq %r10, -0x118(%rbp)
movq 0x20(%rbp), %r13
movq 0x28(%rbp), %r12
movq -0x70(%rbp), %rbx
movq 0x48(%rbp), %r10
movq 0x30(%rbp), %r11
movq %r11, -0x110(%rbp)
leaq -0x88(%rbp), %r15
leaq -0x90(%rbp), %r14
leaq -0x98(%rbp), %r11
movq %rax, (%rsp)
movq -0x120(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0x118(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0x110(%rbp), %rax
movq %r13, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movq %r11, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x5eff0
cmpq $0x0, %rax
je 0x62344
movq 0x70(%rbp), %rdi
movq 0x40(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x30(%rbp)
jmp 0x62350
jmp 0x62346
jmp 0x62348
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopw %cs:(%rax,%rax)