// File: chhylp123[P]hifiasm/Correct.cpp
// Function: merge_cigars(Correct_dumy*, Cigar_record*, Round2_alignment*, long long, long long, long long, long long)
int merge_cigars(Correct_dumy* current_dumy, Cigar_record* current_cigar, 
Round2_alignment* second_round, long long total_start_base, long long total_end_base,
long long total_window_start, long long total_window_end)
{
    Cigar_record* new_cigar = &(second_round->tmp_cigar);

    if(new_cigar->length == 1 && Get_Cigar_Type(new_cigar->record[0]) == 0)
    {
        return 1;
    }

    
    long long start_base = total_start_base - total_window_start;
    long long end_base = total_end_base - total_window_start;
    long long x_i, y_i, cigar_i, i;
    x_i = 0;
    y_i = 0;
    int operation;
    int operationLen;

    long long get_x_start, get_x_end, get_y_start, get_y_end;
    get_x_start = get_x_end = get_y_start = get_y_end = -1;

    int start_cigar = -1;
    int end_cigar = -1;

    ///0 is match, 1 is mismatch, 2 is up, 3 is left
    ///obtained x_i may larger than start_base/end_base
    ///when operation == 3
    ///so for operation == 3, we need deal with carefully
    for (i = 0; i < (long long)new_cigar->length; i++)
    {
        operation = Get_Cigar_Type(new_cigar->record[i]);
        operationLen = Get_Cigar_Length(new_cigar->record[i]);
        if (operation == 0)
        {
            for (cigar_i = 0; cigar_i < operationLen; cigar_i++)
            {
                if(x_i >= start_base && get_x_start == -1)
                {
                    get_x_start = x_i;
                    get_y_start = y_i;
                    start_cigar = i;
                }



                if(x_i >= end_base && get_x_end == -1)
                {
                    get_x_end = x_i;
                    get_y_end = y_i;
                    end_cigar = i;
                    break;
                }

                

                x_i++;
                y_i++;
            }
        }
        else if (operation == 1)
        {
            for (cigar_i = 0; cigar_i < operationLen; cigar_i++)
            {
                if(x_i >= start_base && get_x_start == -1)
                {
                    get_x_start = x_i;
                    get_y_start = y_i;
                    start_cigar = i;
                }

                if(x_i >= end_base && get_x_end == -1)
                {
                    get_x_end = x_i;
                    get_y_end = y_i;
                    end_cigar = i;
                    break;
                }

                x_i++;
                y_i++;
            }
        }
        else if (operation == 2)
        {
            y_i += operationLen;
        }
        else if (operation == 3)
        {
            ///obtained x_i may larger than start_base/end_base
            ///when operation == 3
            ///so for operation == 3, we need deal with carefully
            x_i += operationLen;
        }
    }

    ///if there are some gap at the end of x, it very likely miscorrection
    if(get_x_end == -1 || get_x_start == -1)
    {
        return 0;
    }
    
    x_i = 0;
    y_i = 0;

    uint32_t single_record = 0;

    for (i = 0; i < (long long)new_cigar->length; i++)
    {
        operation = Get_Cigar_Type(new_cigar->record[i]);
        operationLen = Get_Cigar_Length(new_cigar->record[i]);

        if (i == start_cigar)
        {
            single_record = 0;
            single_record = operationLen - (get_x_start - x_i);
            single_record = single_record << 2;
            single_record = single_record | operation;
            new_cigar->record[i] = single_record;

            if(operation > 1)
            {
                fprintf(stderr, "error\n");
            }

            if (i == end_cigar)
            {
                x_i = get_x_start;
                single_record = 0;
                single_record = get_x_end - x_i + 1;
                single_record = single_record << 2;
                single_record = single_record | operation;
                new_cigar->record[i] = single_record;
                if(operation > 1)
                {
                    fprintf(stderr, "error\n");
                }
                break;
            }
        }
        else if (i == end_cigar)
        {
            single_record = 0;
            single_record = get_x_end - x_i + 1;
            single_record = single_record << 2;
            single_record = single_record | operation;
            new_cigar->record[i] = single_record;
            if(operation > 1)
            {
                fprintf(stderr, "error\n");
            }
            break;
        }


        if (operation == 0 || operation == 1)
        {
            x_i += operationLen;
            y_i += operationLen;
        }
        else if (operation == 2)
        {
            y_i += operationLen;
        }
        else if (operation == 3)
        {
            x_i += operationLen;
        }
    }

    new_cigar->length = end_cigar - start_cigar + 1;
    ///should be improved
    memmove(new_cigar->record, new_cigar->record + start_cigar, new_cigar->length*sizeof(uint32_t));
    
    long long total_x_start = total_window_start + get_x_start;
    long long x_length = get_x_end -get_x_start + 1;
    long long total_y_start = get_y_start;
    long long y_length = get_y_end -get_y_start + 1;

    add_cigar_to_cigar(current_dumy, current_cigar, second_round,
    total_x_start, x_length, total_y_start, y_length);

    return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq -0x20(%rbp), %rax
addq $0x8dc0, %rax           # imm = 0x8DC0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x1, 0x18(%rax)
jne 0x3a22e
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movl (%rax), %eax
andl $0x3, %eax
cmpl $0x0, %eax
jne 0x3a22e
movl $0x1, -0x4(%rbp)
jmp 0x3a7c2
movq -0x28(%rbp), %rax
subq -0x38(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rax
subq -0x38(%rbp), %rax
movq %rax, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq $-0x1, -0x98(%rbp)
movq $-0x1, -0x90(%rbp)
movq $-0x1, -0x88(%rbp)
movq $-0x1, -0x80(%rbp)
movl $0xffffffff, -0x9c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0xa0(%rbp) # imm = 0xFFFFFFFF
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jge 0x3a47d
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x3, %eax
movl %eax, -0x74(%rbp)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl (%rax,%rcx,4), %eax
shrl $0x2, %eax
movl %eax, -0x78(%rbp)
cmpl $0x0, -0x74(%rbp)
jne 0x3a38c
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movslq -0x78(%rbp), %rcx
cmpq %rcx, %rax
jge 0x3a387
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0x3a328
cmpq $-0x1, -0x80(%rbp)
jne 0x3a328
movq -0x58(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x70(%rbp), %rax
movl %eax, -0x9c(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
jl 0x3a35e
cmpq $-0x1, -0x88(%rbp)
jne 0x3a35e
movq -0x58(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x70(%rbp), %rax
movl %eax, -0xa0(%rbp)
jmp 0x3a387
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x3a2e9
jmp 0x3a46a
cmpl $0x1, -0x74(%rbp)
jne 0x3a43e
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movslq -0x78(%rbp), %rcx
cmpq %rcx, %rax
jge 0x3a43c
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0x3a3dd
cmpq $-0x1, -0x80(%rbp)
jne 0x3a3dd
movq -0x58(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x70(%rbp), %rax
movl %eax, -0x9c(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x50(%rbp), %rax
jl 0x3a413
cmpq $-0x1, -0x88(%rbp)
jne 0x3a413
movq -0x58(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x70(%rbp), %rax
movl %eax, -0xa0(%rbp)
jmp 0x3a43c
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x3a39e
jmp 0x3a468
cmpl $0x2, -0x74(%rbp)
jne 0x3a452
movslq -0x78(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x3a466
cmpl $0x3, -0x74(%rbp)
jne 0x3a464
movslq -0x78(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x3a466
jmp 0x3a468
jmp 0x3a46a
jmp 0x3a46c
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x3a29b
cmpq $-0x1, -0x88(%rbp)
je 0x3a48e
cmpq $-0x1, -0x80(%rbp)
jne 0x3a49a
movl $0x0, -0x4(%rbp)
jmp 0x3a7c2
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movl $0x0, -0xa4(%rbp)
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jge 0x3a6f5
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x3, %eax
movl %eax, -0x74(%rbp)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl (%rax,%rcx,4), %eax
shrl $0x2, %eax
movl %eax, -0x78(%rbp)
movq -0x70(%rbp), %rax
movslq -0x9c(%rbp), %rcx
cmpq %rcx, %rax
jne 0x3a60e
movl $0x0, -0xa4(%rbp)
movslq -0x78(%rbp), %rax
movq -0x80(%rbp), %rcx
subq -0x58(%rbp), %rcx
subq %rcx, %rax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
shll $0x2, %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
orl -0x74(%rbp), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %edx
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
cmpl $0x1, -0x74(%rbp)
jle 0x3a57c
movq 0x389a75(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x348070(%rip), %rsi    # 0x3825e5
movb $0x0, %al
callq 0x22a0
movq -0x70(%rbp), %rax
movslq -0xa0(%rbp), %rcx
cmpq %rcx, %rax
jne 0x3a609
movq -0x80(%rbp), %rax
movq %rax, -0x58(%rbp)
movl $0x0, -0xa4(%rbp)
movq -0x88(%rbp), %rax
subq -0x58(%rbp), %rax
addq $0x1, %rax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
shll $0x2, %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
orl -0x74(%rbp), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %edx
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
cmpl $0x1, -0x74(%rbp)
jle 0x3a604
movq 0x3899ed(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x347fe8(%rip), %rsi    # 0x3825e5
movb $0x0, %al
callq 0x22a0
jmp 0x3a6f5
jmp 0x3a692
movq -0x70(%rbp), %rax
movslq -0xa0(%rbp), %rcx
cmpq %rcx, %rax
jne 0x3a690
movl $0x0, -0xa4(%rbp)
movq -0x88(%rbp), %rax
subq -0x58(%rbp), %rax
addq $0x1, %rax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
shll $0x2, %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
orl -0x74(%rbp), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %edx
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x70(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
cmpl $0x1, -0x74(%rbp)
jle 0x3a68e
movq 0x389963(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x347f5e(%rip), %rsi    # 0x3825e5
movb $0x0, %al
callq 0x22a0
jmp 0x3a6f5
jmp 0x3a692
cmpl $0x0, -0x74(%rbp)
je 0x3a69e
cmpl $0x1, -0x74(%rbp)
jne 0x3a6b8
movslq -0x78(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movslq -0x78(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x3a6e2
cmpl $0x2, -0x74(%rbp)
jne 0x3a6cc
movslq -0x78(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x3a6e0
cmpl $0x3, -0x74(%rbp)
jne 0x3a6de
movslq -0x78(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x3a6e0
jmp 0x3a6e2
jmp 0x3a6e4
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x3a4bc
movl -0xa0(%rbp), %eax
subl -0x9c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rsi
movslq -0x9c(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rdx
shlq $0x2, %rdx
callq 0x2350
movq -0x38(%rbp), %rax
addq -0x80(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x88(%rbp), %rax
subq -0x80(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x98(%rbp), %rax
subq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xc8(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0xb0(%rbp), %rcx
movq -0xb8(%rbp), %r8
movq -0xc0(%rbp), %r9
movq -0xc8(%rbp), %rax
movq %rax, (%rsp)
callq 0x39f60
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nop