// File: chhylp123[P]hifiasm/Correct.cpp
// Function: fix_boundary(char*, long long, int, long long, long long, long long, long long, long long, long long, long long, All_reads*, Correct_dumy*, int, unsigned int, long long*, int*, int*, int*, int*, unsigned int*)
inline int fix_boundary(char* x_string, long long x_len, int threshold,
long long total_y_start, long long local_y_start, long long local_y_end,
long long old_extra_begin, long long old_extra_end,
long long y_ID, long long Window_Len, All_reads* R_INF,
Correct_dumy* dumy, int y_strand, unsigned int old_error,
long long* r_total_y_start, int* r_start_site, int* r_end_site,
int* r_extra_begin, int* r_extra_end, unsigned int* r_error)
{

    
    int new_extra_begin, new_extra_end;
    long long new_y_start, new_y_length;
    int new_end_site, new_start_site;
    unsigned int new_error;
    char* y_string;


    int path_length;

    ///if the start pos at the left boundary 
    if(local_y_start == 0)
    {
        total_y_start = total_y_start + local_y_start;
        ///if local_y_start == 0 and old_extra_begin != 0
        ///this means total_y_start == 0, so shift to the left cannot get a new start pos
        if(old_extra_begin != 0)
        {
            return 0;
        }

        ///if the begining of alignment is 0, we should try to shift the window to find a better result
        ///shift to the left by threshold-1 bases
        if(!determine_overlap_region(threshold, total_y_start, y_ID, Window_Len, Get_READ_LENGTH((*R_INF), y_ID),
        &new_extra_begin, &new_extra_end, &new_y_start, &new_y_length))
        {
            return 0;
        }

        ///if new_y_start is equal to total_y_start, recalculate makes no sense
        if(new_y_start == total_y_start)
        {
            return 0;
        }

        fill_subregion(dumy->overlap_region_fix, new_y_start, new_y_length, y_strand, R_INF, y_ID, 
        new_extra_begin, new_extra_end);

        y_string = dumy->overlap_region_fix;

        new_end_site = Reserve_Banded_BPM_PATH(y_string, Window_Len, x_string, x_len, threshold, &new_error, &new_start_site,
                    &path_length, dumy->matrix_bit, dumy->path_fix, -1, -1);
        
        if (new_error != (unsigned int)-1 && new_error < old_error)
        {
            (*r_total_y_start) = new_y_start;
            (*r_start_site) = new_start_site;
            (*r_end_site) = new_end_site;
            (*r_extra_begin) = new_extra_begin;
            (*r_extra_end) = new_extra_end;
            (*r_error) = new_error;

            dumy->path_length = path_length;
            memcpy(dumy->path, dumy->path_fix, path_length);
            memcpy(dumy->overlap_region, dumy->overlap_region_fix, Window_Len);
            return 1;
        }
    }
    else if(local_y_end == Window_Len - 1)
    {
        ///if local_y_end == Window_Len - 1 and old_extra_end > 0
        ///this means local_y_end is the end of the y
        ///so shit to the right makes no sense
        if(old_extra_end != 0)
        {
            return 0;
        }
        long long total_y_end = total_y_start + local_y_end;

        total_y_start = total_y_end - x_len + 1;

        if(!determine_overlap_region(threshold, total_y_start, y_ID, Window_Len, Get_READ_LENGTH((*R_INF), y_ID),
        &new_extra_begin, &new_extra_end, &new_y_start, &new_y_length))
        {
            return 0;
        }

        if(new_y_start == total_y_end - local_y_end)
        {
            return 0;
        }

        fill_subregion(dumy->overlap_region_fix, new_y_start, new_y_length, y_strand, R_INF, y_ID, 
        new_extra_begin, new_extra_end);

        y_string = dumy->overlap_region_fix;

        new_end_site = Reserve_Banded_BPM_PATH(y_string, Window_Len, x_string, x_len, threshold, &new_error, &new_start_site,
                    &path_length, dumy->matrix_bit, dumy->path_fix, -1, -1);

        if (new_error != (unsigned int)-1 && new_error < old_error)
        {
            (*r_total_y_start) = new_y_start;
            (*r_start_site) = new_start_site;
            (*r_end_site) = new_end_site;
            (*r_extra_begin) = new_extra_begin;
            (*r_extra_end) = new_extra_end;
            (*r_error) = new_error;

            dumy->path_length = path_length;
            memcpy(dumy->path, dumy->path_fix, path_length);
            memcpy(dumy->overlap_region, dumy->overlap_region_fix, Window_Len);
            return 1;
        }


    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0xa8, %rsp
movq 0x78(%rbp), %rax
movq 0x70(%rbp), %rax
movq 0x68(%rbp), %rax
movq 0x60(%rbp), %rax
movq 0x58(%rbp), %rax
movq 0x50(%rbp), %rax
movl 0x48(%rbp), %eax
movl 0x40(%rbp), %eax
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)
movl %edx, -0x24(%rbp)
movq %rcx, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq %r9, -0x40(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0xc37f3
movq -0x30(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, 0x10(%rbp)
je 0xc3633
movl $0x0, -0xc(%rbp)
jmp 0xc3a01
movl -0x24(%rbp), %edi
movq -0x30(%rbp), %rsi
movq 0x20(%rbp), %rdx
movq 0x28(%rbp), %rcx
movq 0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rbp), %r8
movq (%rax,%r8,8), %r8
leaq -0x44(%rbp), %r9
leaq -0x48(%rbp), %r11
leaq -0x50(%rbp), %r10
leaq -0x58(%rbp), %rax
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x32290
cmpl $0x0, %eax
jne 0xc3686
movl $0x0, -0xc(%rbp)
jmp 0xc3a01
movq -0x50(%rbp), %rax
cmpq -0x30(%rbp), %rax
jne 0xc369c
movl $0x0, -0xc(%rbp)
jmp 0xc3a01
movq 0x38(%rbp), %rdi
addq $0xdfc, %rdi            # imm = 0xDFC
movq -0x50(%rbp), %rsi
movq -0x58(%rbp), %rdx
movl 0x40(%rbp), %eax
movb %al, %cl
movq 0x30(%rbp), %r8
movq 0x20(%rbp), %r9
movl -0x44(%rbp), %r10d
movl -0x48(%rbp), %eax
movzbl %cl, %ecx
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x32160
movq 0x38(%rbp), %rax
addq $0xdfc, %rax            # imm = 0xDFC
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
movq 0x28(%rbp), %rax
movl %eax, %esi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rax
movl %eax, %ecx
movl -0x24(%rbp), %eax
movw %ax, %r8w
movq 0x38(%rbp), %r10
addq $0xff0, %r10            # imm = 0xFF0
movq 0x38(%rbp), %rax
addq $0xc08, %rax            # imm = 0xC08
leaq -0x64(%rbp), %r9
leaq -0x60(%rbp), %rbx
leaq -0x74(%rbp), %r11
movzwl %r8w, %r8d
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl $0xffffffff, 0x20(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
callq 0x9e3d0
movl %eax, -0x5c(%rbp)
cmpl $-0x1, -0x64(%rbp)
je 0xc37ee
movl -0x64(%rbp), %eax
cmpl 0x48(%rbp), %eax
jae 0xc37ee
movq -0x50(%rbp), %rcx
movq 0x50(%rbp), %rax
movq %rcx, (%rax)
movl -0x60(%rbp), %ecx
movq 0x58(%rbp), %rax
movl %ecx, (%rax)
movl -0x5c(%rbp), %ecx
movq 0x60(%rbp), %rax
movl %ecx, (%rax)
movl -0x44(%rbp), %ecx
movq 0x68(%rbp), %rax
movl %ecx, (%rax)
movl -0x48(%rbp), %ecx
movq 0x70(%rbp), %rax
movl %ecx, (%rax)
movl -0x64(%rbp), %ecx
movq 0x78(%rbp), %rax
movl %ecx, (%rax)
movl -0x74(%rbp), %ecx
movq 0x38(%rbp), %rax
movl %ecx, 0x7d70(%rax)
movq 0x38(%rbp), %rdi
addq $0xa14, %rdi            # imm = 0xA14
movq 0x38(%rbp), %rsi
addq $0xc08, %rsi            # imm = 0xC08
movslq -0x74(%rbp), %rdx
callq 0x2180
movq 0x38(%rbp), %rdi
addq $0x50, %rdi
movq 0x38(%rbp), %rsi
addq $0xdfc, %rsi            # imm = 0xDFC
movq 0x28(%rbp), %rdx
callq 0x2180
movl $0x1, -0xc(%rbp)
jmp 0xc3a01
jmp 0xc39fa
movq -0x40(%rbp), %rax
movq 0x28(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0xc39f8
cmpq $0x0, 0x18(%rbp)
je 0xc381b
movl $0x0, -0xc(%rbp)
jmp 0xc3a01
movq -0x30(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
subq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movl -0x24(%rbp), %edi
movq -0x30(%rbp), %rsi
movq 0x20(%rbp), %rdx
movq 0x28(%rbp), %rcx
movq 0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rbp), %r8
movq (%rax,%r8,8), %r8
leaq -0x44(%rbp), %r9
leaq -0x48(%rbp), %r11
leaq -0x50(%rbp), %r10
leaq -0x58(%rbp), %rax
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x32290
cmpl $0x0, %eax
jne 0xc388a
movl $0x0, -0xc(%rbp)
jmp 0xc3a01
movq -0x50(%rbp), %rax
movq -0x80(%rbp), %rcx
subq -0x40(%rbp), %rcx
cmpq %rcx, %rax
jne 0xc38a7
movl $0x0, -0xc(%rbp)
jmp 0xc3a01
movq 0x38(%rbp), %rdi
addq $0xdfc, %rdi            # imm = 0xDFC
movq -0x50(%rbp), %rsi
movq -0x58(%rbp), %rdx
movl 0x40(%rbp), %eax
movb %al, %cl
movq 0x30(%rbp), %r8
movq 0x20(%rbp), %r9
movl -0x44(%rbp), %r10d
movl -0x48(%rbp), %eax
movzbl %cl, %ecx
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x32160
movq 0x38(%rbp), %rax
addq $0xdfc, %rax            # imm = 0xDFC
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
movq 0x28(%rbp), %rax
movl %eax, %esi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rax
movl %eax, %ecx
movl -0x24(%rbp), %eax
movw %ax, %r8w
movq 0x38(%rbp), %r10
addq $0xff0, %r10            # imm = 0xFF0
movq 0x38(%rbp), %rax
addq $0xc08, %rax            # imm = 0xC08
leaq -0x64(%rbp), %r9
leaq -0x60(%rbp), %rbx
leaq -0x74(%rbp), %r11
movzwl %r8w, %r8d
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl $0xffffffff, 0x20(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
callq 0x9e3d0
movl %eax, -0x5c(%rbp)
cmpl $-0x1, -0x64(%rbp)
je 0xc39f6
movl -0x64(%rbp), %eax
cmpl 0x48(%rbp), %eax
jae 0xc39f6
movq -0x50(%rbp), %rcx
movq 0x50(%rbp), %rax
movq %rcx, (%rax)
movl -0x60(%rbp), %ecx
movq 0x58(%rbp), %rax
movl %ecx, (%rax)
movl -0x5c(%rbp), %ecx
movq 0x60(%rbp), %rax
movl %ecx, (%rax)
movl -0x44(%rbp), %ecx
movq 0x68(%rbp), %rax
movl %ecx, (%rax)
movl -0x48(%rbp), %ecx
movq 0x70(%rbp), %rax
movl %ecx, (%rax)
movl -0x64(%rbp), %ecx
movq 0x78(%rbp), %rax
movl %ecx, (%rax)
movl -0x74(%rbp), %ecx
movq 0x38(%rbp), %rax
movl %ecx, 0x7d70(%rax)
movq 0x38(%rbp), %rdi
addq $0xa14, %rdi            # imm = 0xA14
movq 0x38(%rbp), %rsi
addq $0xc08, %rsi            # imm = 0xC08
movslq -0x74(%rbp), %rdx
callq 0x2180
movq 0x38(%rbp), %rdi
addq $0x50, %rdi
movq 0x38(%rbp), %rsi
addq $0xdfc, %rsi            # imm = 0xDFC
movq 0x28(%rbp), %rdx
callq 0x2180
movl $0x1, -0xc(%rbp)
jmp 0xc3a01
jmp 0xc39f8
jmp 0xc39fa
movl $0x0, -0xc(%rbp)
movl -0xc(%rbp), %eax
addq $0xa8, %rsp
popq %rbx
popq %rbp
retq
nop