// File: /workspace/github_cpp_makefile_star2_O1/zeeev[P]DASVC/bamtools/src/utils/bamtools_pileup_engine.cpp
// Function: BamTools::PileupEngine::PileupEnginePrivate::ParseAlignmentCigar(BamTools::BamAlignment const&)
void PileupEngine::PileupEnginePrivate::ParseAlignmentCigar(const BamAlignment& al) {
  
    // skip if unmapped
    if ( !al.IsMapped() ) return;
    
    // intialize local variables
    int  genomePosition      = al.Position;
    int  positionInAlignment = 0;
    bool isNewReadSegment    = true;
    bool saveAlignment       = true;    
    PileupAlignment pileupAlignment(al);
    
    // iterate over CIGAR operations
    const int numCigarOps = (const int)al.CigarData.size();
    for (int i = 0; i < numCigarOps; ++i ) { 
        const CigarOp& op = al.CigarData.at(i);
      
        // if op is MATCH
        if ( op.Type == 'M' ) {
          
            // if match op overlaps current position
            if ( genomePosition + (int)op.Length > CurrentPosition ) {
              
                // set pileup data
                pileupAlignment.IsCurrentDeletion   = false;
                pileupAlignment.IsNextDeletion      = false;
                pileupAlignment.IsNextInsertion     = false;
                pileupAlignment.PositionInAlignment = positionInAlignment + (CurrentPosition - genomePosition);
                
                // check for beginning of read segment
                if ( genomePosition == CurrentPosition && isNewReadSegment ) 
                    pileupAlignment.IsSegmentBegin = true;
                
                // if we're at the end of a match operation
                if ( genomePosition + (int)op.Length - 1 == CurrentPosition ) {
                    
                    // if not last operation
                    if ( i < numCigarOps - 1 ) {
                        
                        // check next CIGAR op
                        const CigarOp& nextOp = al.CigarData.at(i+1);
                        
                        // if next CIGAR op is DELETION
                        if ( nextOp.Type == 'D') {
                            pileupAlignment.IsNextDeletion = true;
                            pileupAlignment.DeletionLength = nextOp.Length;
                        }
                        
                        // if next CIGAR op is INSERTION
                        else if ( nextOp.Type == 'I' ) {
                            pileupAlignment.IsNextInsertion = true;
                            pileupAlignment.InsertionLength = nextOp.Length;
                        }
                            
                        // if next CIGAR op is either DELETION or INSERTION
                        if ( nextOp.Type == 'D' || nextOp.Type == 'I' ) {

                            // if there is a CIGAR op after the DEL/INS
                            if ( i < numCigarOps - 2 ) {
                                const CigarOp& nextNextOp = al.CigarData.at(i+2);
                                
                                // if next CIGAR op is clipping or ref_skip
                                if ( nextNextOp.Type == 'S' || 
                                     nextNextOp.Type == 'N' ||
                                     nextNextOp.Type == 'H' )
                                    pileupAlignment.IsSegmentEnd = true;
                            } 
                            else {
                                pileupAlignment.IsSegmentEnd = true;
                                
                                // if next CIGAR op is clipping or ref_skip
                                if ( nextOp.Type == 'S' || 
                                     nextOp.Type == 'N' ||
                                     nextOp.Type == 'H' )
                                    pileupAlignment.IsSegmentEnd = true;
                            }
                        }
                        
                        // otherwise
                        else { 
                        
                            // if next CIGAR op is clipping or ref_skip
                            if ( nextOp.Type == 'S' || 
                                 nextOp.Type == 'N' ||
                                 nextOp.Type == 'H' )
                                pileupAlignment.IsSegmentEnd = true;
                        }
                    }
                    
                    // else this is last operation
                    else pileupAlignment.IsSegmentEnd = true;
                }
            }
          
            // increment markers
            genomePosition      += op.Length;
            positionInAlignment += op.Length;
        } 
        
        // if op is DELETION
        else if ( op.Type == 'D' ) {
          
            // if deletion op overlaps current position
            if ( genomePosition + (int)op.Length > CurrentPosition ) {
              
                // set pileup data
                pileupAlignment.IsCurrentDeletion   = true;
                pileupAlignment.IsNextDeletion      = false;
                pileupAlignment.IsNextInsertion     = true;
                pileupAlignment.PositionInAlignment = positionInAlignment + (CurrentPosition - genomePosition);
            }
            
            // increment marker
            genomePosition += op.Length;
        }

        // if op is REF_SKIP
        else if ( op.Type == 'N' ) {
            genomePosition += op.Length;
        }
        
        // if op is INSERTION or SOFT_CLIP
        else if ( op.Type == 'I' || op.Type == 'S' ) {
            positionInAlignment += op.Length;
        }
        
        // checl for beginning of new read segment
        if ( op.Type == 'N' ||
             op.Type == 'S' ||
             op.Type == 'H' )
            isNewReadSegment = true;
        else 
            isNewReadSegment = false;
      
        // if we've moved beyond current position
        if ( genomePosition > CurrentPosition ) {
            if ( op.Type == 'N' ) saveAlignment = false; // ignore alignment if REF_SKIP
            break;
        }
    }

    // save pileup position if flag is true
    if ( saveAlignment )
        CurrentPileupData.PileupAlignments.push_back( pileupAlignment );
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x188, %rsp            # imm = 0x188
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x270d0
testb %al, %al
je 0x6585d
movl 0xac(%r14), %r15d
leaq 0x18(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x272b0
movl $0xffffffff, 0x158(%r12) # imm = 0xFFFFFFFF
xorl %eax, %eax
movw %ax, 0x15c(%r12)
movb $0x0, 0x15e(%r12)
movw %ax, 0x168(%r12)
movq $0x0, 0x160(%r12)
movq 0xb8(%r14), %rdi
movq 0xc0(%r14), %rcx
subq %rdi, %rcx
movq %rcx, %rdx
sarq $0x3, %rdx
testl %edx, %edx
jle 0x65842
movl 0x4(%rbx), %r8d
shlq $0x1d, %rcx
movabsq $-0x200000000, %rsi     # imm = 0xFFFFFFFE00000000
addq %rcx, %rsi
sarq $0x20, %rsi
movq %rsi, 0x8(%rsp)
movabsq $-0x100000000, %rsi     # imm = 0xFFFFFFFF00000000
addq %rcx, %rsi
sarq $0x20, %rsi
movq %rsi, 0x10(%rsp)
movl %edx, %r11d
andl $0x7fffffff, %r11d      # imm = 0x7FFFFFFF
decq %r11
movb $0x1, %sil
xorl %r12d, %r12d
xorl %r10d, %r10d
movb $0x1, %bpl
cmpq %r12, %rdx
je 0x6586f
movb (%rdi,%r12,8), %cl
movzbl %cl, %r9d
cmpl $0x4c, %r9d
jle 0x656ee
cmpl $0x53, %r9d
je 0x656fa
cmpl $0x4e, %r9d
je 0x65701
cmpl $0x4d, %r9d
jne 0x65706
movl 0x4(%rdi,%r12,8), %r9d
leal (%r9,%r15), %r14d
cmpl %r8d, %r14d
jle 0x657d9
movw $0x0, 0x174(%rsp)
movb $0x0, 0x176(%rsp)
movl %r10d, %r13d
subl %r15d, %r13d
addl %r8d, %r13d
movl %r13d, 0x170(%rsp)
cmpl %r8d, %r15d
setne %r15b
notb %sil
orb %r15b, %sil
testb $0x1, %sil
jne 0x65699
movb $0x1, 0x180(%rsp)
leal -0x1(%r14), %esi
cmpl %r8d, %esi
jne 0x657d9
cmpq 0x10(%rsp), %r12
jge 0x657d1
leaq 0x1(%r12), %rsi
cmpq %rsi, %rdx
jbe 0x65880
movzbl 0x8(%rdi,%r12,8), %esi
cmpl $0x48, %esi
jle 0x65783
cmpl $0x49, %esi
je 0x6578f
cmpl $0x4e, %esi
je 0x657d1
cmpl $0x53, %esi
je 0x657d1
jmp 0x657d9
cmpl $0x44, %r9d
je 0x65752
cmpl $0x49, %r9d
jne 0x65706
addl 0x4(%rdi,%r12,8), %r10d
jmp 0x65706
addl 0x4(%rdi,%r12,8), %r15d
movl %r15d, %r14d
addb $-0x48, %cl
cmpb $0xc, %cl
setb %sil
movl $0x841, %r9d            # imm = 0x841
shrl %cl, %r9d
cmpb $0x4e, (%rdi,%r12,8)
movzbl %bpl, %ecx
movl %ecx, %ebp
cmovel %eax, %ebp
cmpl %r8d, %r14d
cmovlel %ecx, %ebp
jg 0x6583c
andb %r9b, %sil
leaq 0x1(%r12), %rcx
movl %r14d, %r15d
cmpq %r12, %r11
movq %rcx, %r12
jne 0x65610
jmp 0x6583c
movl 0x4(%rdi,%r12,8), %r14d
addl %r15d, %r14d
cmpl %r8d, %r14d
jle 0x65709
movw $0x1, 0x174(%rsp)
movb $0x1, 0x176(%rsp)
movl %r10d, %esi
subl %r15d, %esi
addl %r8d, %esi
movl %esi, 0x170(%rsp)
jmp 0x65709
cmpl $0x44, %esi
je 0x657a6
cmpl $0x48, %esi
je 0x657d1
jmp 0x657d9
movb $0x1, 0x176(%rsp)
movl 0xc(%rdi,%r12,8), %r15d
movl %r15d, 0x17c(%rsp)
jmp 0x657bb
movb $0x1, 0x175(%rsp)
movl 0xc(%rdi,%r12,8), %r15d
movl %r15d, 0x178(%rsp)
leal -0x44(%rsi), %r15d
cmpl $0xf, %r15d
ja 0x657d9
movl $0x8410, %r13d          # imm = 0x8410
btl %r15d, %r13d
jae 0x657e1
movb $0x1, 0x181(%rsp)
addl %r9d, %r10d
jmp 0x65709
movl $0x21, %r13d
btl %r15d, %r13d
jae 0x657d9
cmpq 0x8(%rsp), %r12
jge 0x6581e
leaq 0x2(%r12), %rsi
cmpq %rsi, %rdx
jbe 0x6588e
movzbl 0x10(%rdi,%r12,8), %esi
addl $-0x48, %esi
cmpl $0xb, %esi
ja 0x657d9
movl $0x841, %r15d           # imm = 0x841
btl %esi, %r15d
jb 0x657d1
jmp 0x657d9
movb $0x1, 0x181(%rsp)
addl $-0x48, %esi
cmpl $0xb, %esi
ja 0x657d9
movl $0x841, %r15d           # imm = 0x841
btl %esi, %r15d
jb 0x657d1
jmp 0x657d9
testb $0x1, %bpl
je 0x65853
addq $0x28, %rbx
leaq 0x18(%rsp), %rsi
movq %rbx, %rdi
callq 0x65a24
leaq 0x18(%rsp), %rdi
callq 0x27930
addq $0x188, %rsp            # imm = 0x188
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xcef0(%rip), %rdi      # 0x72766
movq %rdx, %rsi
xorl %eax, %eax
callq 0x278c0
leaq 0xcedf(%rip), %rdi      # 0x72766
xorl %eax, %eax
callq 0x278c0
leaq 0xced1(%rip), %rdi      # 0x72766
xorl %eax, %eax
callq 0x278c0
jmp 0x658a2
jmp 0x658a2
jmp 0x658a2
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x27930
movq %rbx, %rdi
callq 0x27b20
movq %rax, %rdi
callq 0x2e1ed
nop