// File: chhylp123[P]hifiasm/Correct.cpp
// Function: addSNPtohaplotype_advance(long long, int, long long, long long, long long, long long, window_list*, window_list_alloc*, window_list*, window_list_alloc*, window_list*, window_list_alloc*, haplotype_evdience_alloc*, int, char*, char*, ul_idx_t const*, int, int, void*)
void addSNPtohaplotype_advance(
long long window_offset, int overlapID,
long long x_total_start, long long x_length, 
long long y_total_start, long long y_length, 
window_list* current_cigar, window_list_alloc *current_cigar_s, 
window_list* beg_cigar, window_list_alloc *beg_cigar_s,
window_list* end_cigar, window_list_alloc *end_cigar_s,
haplotype_evdience_alloc* hap, int snp_threshold, char* x_T_string, char* y_T_string, const ul_idx_t *uref, int strand, int yid, void *km)
{
    long long x_total_end = x_total_start + x_length - 1;
    long long inner_offset = x_total_start - window_offset;
    ///long long useless_side, xleftLen, xrightLen, x_interval_beg, x_interval_end;
    long long L_useless_side, R_useless_side, xleftLen, xrightLen, x_interval_beg, x_interval_end;
    long long current_cigar_beg, current_cigar_end;

    ///for current_cigar, [current_cigar_beg, current_cigar_end]
    current_cigar_beg = 0;
    current_cigar_end = x_length - 1;
    ///if the beg_cigar is available
    if(beg_cigar != NULL && beg_cigar->y_end!=-1)
    {
        ///useless_side = beg_cigar->error_threshold;
        L_useless_side = beg_cigar->extra_begin;
        R_useless_side = beg_cigar->extra_end;
        ///again, xleftLen does not include x_total_start itself, but includes beg_cigar->x_start
        xleftLen = x_total_start - beg_cigar->x_start;
        ///xrightLen includes both x_total_start and beg_cigar->x_end
        xrightLen = beg_cigar->x_end - x_total_start + 1;
        ///actually xleftLen could be no larger than useless_side
        ///but such window has already been filtered out at calculate_boundary_cigars
        ///if(xleftLen > useless_side && xrightLen > useless_side)
        if(xleftLen > L_useless_side && xrightLen > R_useless_side) {
            ///[x_interval_beg, x_interval_end] are the offsets to beg_cigar->x_start
            ///they are local postions, instead of global positions

            x_interval_beg = xleftLen;
            ///x_interval_end = x_interval_beg + (xrightLen - useless_side) - 1;
            x_interval_end = x_interval_beg + (xrightLen - R_useless_side) - 1;
            ///current_cigar_beg is the offset of the current cigar
            ///that is the beg of current_cigar_beg
            ///current_cigar_beg = xrightLen - useless_side;
            current_cigar_beg = xrightLen - R_useless_side;

            // markSNP_detail(cigar_record, hap->flag + inner_offset, x_interval_beg, 
            // x_interval_end, x_interval_beg);
            addSNPtohaplotype_details(beg_cigar, beg_cigar_s, hap->flag + inner_offset, 
            x_T_string + beg_cigar->x_start, y_T_string + beg_cigar->y_start, 
            beg_cigar->x_start, beg_cigar->y_start, x_interval_beg, x_interval_end, 
            overlapID, x_interval_beg, hap, snp_threshold, uref, strand, yid, km);
        }
    }


    if(end_cigar!=NULL && end_cigar->y_end!=-1)
    {
        ///useless_side = end_cigar->error_threshold;
        L_useless_side = end_cigar->extra_begin;
        R_useless_side = end_cigar->extra_end;
        ///again, xleftLen does not include x_total_end, but includes end_cigar->x_start
        ///it seems to be not what we want
        xleftLen = x_total_end - end_cigar->x_start;
        ///xrightLen includes both x_total_end and end_cigar->x_end
        ///it is also not what we want
        xrightLen = end_cigar->x_end - x_total_end + 1;
        ///we hope that x_total_end should be included in xleftLen, instead of xrightLen
        ///that means xleftLen should + 1, while xrightLen should -1
        ///but it is fine here 

        ///actually xrightLen could be no larger than useless_side
        ///but such window has already been filtered out in calculate_boundary_cigars
        ///if(xleftLen > useless_side && xrightLen > useless_side)
        if(xleftLen > L_useless_side && xrightLen > R_useless_side)
        {
            ///[x_interval_beg, x_interval_end] are the offsets to beg_cigar->x_start
            ///they are local postions, instead of global positions
            x_interval_end = xleftLen;
            ///the real left part length is (xleftLen + 1)
            ///so the useful left part length is ((xleftLen + 1) - useless_side)
            ///x_interval_beg = x_interval_end - ((xleftLen + 1) - useless_side) + 1;
            x_interval_beg = x_interval_end - ((xleftLen + 1) - L_useless_side) + 1;
            ///current_cigar_end = (x_length - 1) - ((xleftLen + 1) - useless_side);
            current_cigar_end = (x_length - 1) - ((xleftLen + 1) - L_useless_side);
            
            // markSNP_detail(cigar_record, hap->flag + end_cigar->x_start - window_offset,
            // x_interval_beg, x_interval_end, 0);
            addSNPtohaplotype_details(end_cigar, end_cigar_s, hap->flag + end_cigar->x_start - window_offset,
            x_T_string + end_cigar->x_start, y_T_string + end_cigar->y_start, 
            end_cigar->x_start, end_cigar->y_start, x_interval_beg, x_interval_end, 
            overlapID, 0, hap, snp_threshold, uref, strand, yid, km);
        }
    }

    // markSNP_detail(&(current_cigar->cigar), hap->flag + inner_offset, current_cigar_beg, 
    // current_cigar_end, 0);
    addSNPtohaplotype_details(current_cigar, current_cigar_s, hap->flag + inner_offset, 
    x_T_string + current_cigar->x_start, y_T_string + current_cigar->y_start, 
    current_cigar->x_start, current_cigar->y_start, current_cigar_beg, 
    current_cigar_end, overlapID, 0, hap, snp_threshold, uref, strand, yid, km);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x128, %rsp            # imm = 0x128
movq 0x78(%rbp), %rax
movl 0x70(%rbp), %eax
movl 0x68(%rbp), %eax
movq 0x60(%rbp), %rax
movq 0x58(%rbp), %rax
movq 0x50(%rbp), %rax
movl 0x48(%rbp), %eax
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, -0x30(%rbp)
movl %esi, -0x34(%rbp)
movq %rdx, -0x40(%rbp)
movq %rcx, -0x48(%rbp)
movq %r8, -0x50(%rbp)
movq %r9, -0x58(%rbp)
movq -0x40(%rbp), %rax
addq -0x48(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, -0x68(%rbp)
movq $0x0, -0xa0(%rbp)
movq -0x48(%rbp), %rax
subq $0x1, %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, 0x20(%rbp)
je 0x3c284
movq 0x20(%rbp), %rax
cmpl $-0x1, 0xc(%rax)
je 0x3c284
movq 0x20(%rbp), %rax
movswq 0x10(%rax), %rax
movq %rax, -0x70(%rbp)
movq 0x20(%rbp), %rax
movswq 0x12(%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x40(%rbp), %rax
movq 0x20(%rbp), %rcx
movslq (%rcx), %rcx
subq %rcx, %rax
movq %rax, -0x80(%rbp)
movq 0x20(%rbp), %rax
movslq 0x4(%rax), %rax
subq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x70(%rbp), %rax
jle 0x3c282
movq -0x88(%rbp), %rax
cmpq -0x78(%rbp), %rax
jle 0x3c282
movq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq -0x88(%rbp), %rcx
subq -0x78(%rbp), %rcx
addq %rcx, %rax
subq $0x1, %rax
movq %rax, -0x98(%rbp)
movq -0x88(%rbp), %rax
subq -0x78(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq 0x20(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq 0x40(%rbp), %rdx
addq $0x18, %rdx
addq -0x68(%rbp), %rdx
movq 0x50(%rbp), %rcx
movq 0x20(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rcx
movq 0x58(%rbp), %r8
movq 0x20(%rbp), %rax
movslq 0x8(%rax), %rax
addq %rax, %r8
movq 0x20(%rbp), %rax
movslq (%rax), %r9
movq 0x20(%rbp), %rax
movslq 0x8(%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xb8(%rbp)
movl -0x34(%rbp), %r13d
movq -0x90(%rbp), %r12
movq 0x40(%rbp), %r15
movslq 0x48(%rbp), %r14
movq 0x60(%rbp), %rbx
movl 0x68(%rbp), %r11d
movl 0x70(%rbp), %r10d
movq 0x78(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, (%rsp)
movq -0xc0(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xb8(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0xb0(%rbp), %rax
movl %r13d, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movl %r11d, 0x40(%rsp)
movl %r10d, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x3bc30
jmp 0x3c284
cmpq $0x0, 0x30(%rbp)
je 0x3c42f
movq 0x30(%rbp), %rax
cmpl $-0x1, 0xc(%rax)
je 0x3c42f
movq 0x30(%rbp), %rax
movswq 0x10(%rax), %rax
movq %rax, -0x70(%rbp)
movq 0x30(%rbp), %rax
movswq 0x12(%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x60(%rbp), %rax
movq 0x30(%rbp), %rcx
movslq (%rcx), %rcx
subq %rcx, %rax
movq %rax, -0x80(%rbp)
movq 0x30(%rbp), %rax
movslq 0x4(%rax), %rax
subq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x70(%rbp), %rax
jle 0x3c42d
movq -0x88(%rbp), %rax
cmpq -0x78(%rbp), %rax
jle 0x3c42d
movq -0x80(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq -0x80(%rbp), %rcx
addq $0x1, %rcx
subq -0x70(%rbp), %rcx
subq %rcx, %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
movq -0x48(%rbp), %rax
subq $0x1, %rax
movq -0x80(%rbp), %rcx
addq $0x1, %rcx
subq -0x70(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq 0x30(%rbp), %rdi
movq 0x38(%rbp), %rsi
movq 0x40(%rbp), %rdx
addq $0x18, %rdx
movq 0x30(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rdx
xorl %eax, %eax
subq -0x30(%rbp), %rax
addq %rax, %rdx
movq 0x50(%rbp), %rcx
movq 0x30(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rcx
movq 0x58(%rbp), %r8
movq 0x30(%rbp), %rax
movslq 0x8(%rax), %rax
addq %rax, %r8
movq 0x30(%rbp), %rax
movslq (%rax), %r9
movq 0x30(%rbp), %rax
movslq 0x8(%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x98(%rbp), %r13
movl -0x34(%rbp), %r12d
movq 0x40(%rbp), %r15
movslq 0x48(%rbp), %r14
movq 0x60(%rbp), %rbx
movl 0x68(%rbp), %r11d
movl 0x70(%rbp), %r10d
movq 0x78(%rbp), %rax
movq %rax, -0xd0(%rbp)
xorl %eax, %eax
movq -0xe0(%rbp), %rax
movq %rax, (%rsp)
movq -0xd8(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xd0(%rbp), %rax
movq %r13, 0x10(%rsp)
movl %r12d, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movl %r11d, 0x40(%rsp)
movl %r10d, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x3bc30
jmp 0x3c42f
movq 0x10(%rbp), %rdi
movq 0x18(%rbp), %rsi
movq 0x40(%rbp), %rdx
addq $0x18, %rdx
addq -0x68(%rbp), %rdx
movq 0x50(%rbp), %rcx
movq 0x10(%rbp), %rax
movslq (%rax), %rax
addq %rax, %rcx
movq 0x58(%rbp), %r8
movq 0x10(%rbp), %rax
movslq 0x8(%rax), %rax
addq %rax, %r8
movq 0x10(%rbp), %rax
movslq (%rax), %r9
movq 0x10(%rbp), %rax
movslq 0x8(%rax), %rax
movq %rax, -0xf8(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xa8(%rbp), %r13
movl -0x34(%rbp), %r12d
movq 0x40(%rbp), %r15
movslq 0x48(%rbp), %r14
movq 0x60(%rbp), %rbx
movl 0x68(%rbp), %r11d
movl 0x70(%rbp), %r10d
movq 0x78(%rbp), %rax
movq %rax, -0xe8(%rbp)
xorl %eax, %eax
movq -0xf8(%rbp), %rax
movq %rax, (%rsp)
movq -0xf0(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xe8(%rbp), %rax
movq %r13, 0x10(%rsp)
movl %r12d, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
movq %r15, 0x28(%rsp)
movq %r14, 0x30(%rsp)
movq %rbx, 0x38(%rsp)
movl %r11d, 0x40(%rsp)
movl %r10d, 0x48(%rsp)
movq %rax, 0x50(%rsp)
callq 0x3bc30
addq $0x128, %rsp            # imm = 0x128
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopw %cs:(%rax,%rax)