// File: zeeev[P]DASVC/bamtools/src/utils/bamtools_pileup_engine.cpp
// Function: BamTools::PileupEngine::PileupEnginePrivate::AddAlignment(BamTools::BamAlignment const&)
bool PileupEngine::PileupEnginePrivate::AddAlignment(const BamAlignment& al) {
  
    // if first time
    if ( IsFirstAlignment ) {
      
        // set initial markers 
        CurrentId       = al.RefID;
        CurrentPosition = al.Position;
        
        // store first entry
        CurrentAlignments.clear();
        CurrentAlignments.push_back(al);
        
        // set flag & return
        IsFirstAlignment = false;
        return true;
    }
  
    // if same reference
    if ( al.RefID == CurrentId ) {
      
        // if same position, store and move on
        if ( al.Position == CurrentPosition )
            CurrentAlignments.push_back(al);
        
        // if less than CurrentPosition - sorting error => ABORT
        else if ( al.Position < CurrentPosition ) {
            cerr << "Pileup::Run() : Data not sorted correctly!" << endl;
            return false;
        }
        
        // else print pileup data until 'catching up' to CurrentPosition
        else {
            while ( al.Position > CurrentPosition ) {
                ApplyVisitors();
                ++CurrentPosition;
            }
            CurrentAlignments.push_back(al);
        }
    } 

    // if reference ID less than CurrentId - sorting error => ABORT
    else if ( al.RefID < CurrentId ) {
        cerr << "Pileup::Run() : Data not sorted correctly!" << endl;
        return false;
    }

    // else moved forward onto next reference
    else {
        
        // print any remaining pileup data from previous reference
        while ( !CurrentAlignments.empty() ) {
            ApplyVisitors();
            ++CurrentPosition;
        }
        
        // store first entry on this new reference, update markers
        CurrentAlignments.clear();
        CurrentAlignments.push_back(al);
        CurrentId = al.RefID;
        CurrentPosition = al.Position;
    }
  
    return true;
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x18(%rsp)
movq %rsi, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
testb $0x1, 0x40(%rax)
je 0x11134d
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rax
movl 0xa8(%rax), %eax
movl %eax, (%rdi)
movq 0x10(%rsp), %rax
movl 0xac(%rax), %eax
movl %eax, 0x4(%rdi)
addq $0x8, %rdi
callq 0xdd200
movq 0x8(%rsp), %rdi
addq $0x8, %rdi
movq 0x10(%rsp), %rsi
callq 0xdd0b0
movq 0x8(%rsp), %rax
movb $0x0, 0x40(%rax)
movb $0x1, 0x27(%rsp)
jmp 0x1114d5
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movl 0xa8(%rax), %eax
cmpl (%rcx), %eax
jne 0x11141e
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movl 0xac(%rax), %eax
cmpl 0x4(%rcx), %eax
jne 0x111392
movq 0x8(%rsp), %rdi
addq $0x8, %rdi
movq 0x10(%rsp), %rsi
callq 0xdd0b0
jmp 0x111419
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movl 0xac(%rax), %eax
cmpl 0x4(%rcx), %eax
jge 0x1113d3
movq 0x53c32(%rip), %rdi     # 0x164fe0
leaq 0x22ee9(%rip), %rsi     # 0x13429e
callq 0x86700
movq %rax, %rdi
movq 0x53bac(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x27(%rsp)
jmp 0x1114d5
jmp 0x1113d5
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movl 0xac(%rax), %eax
cmpl 0x4(%rcx), %eax
jle 0x111404
movq 0x8(%rsp), %rdi
callq 0x1114e0
movq 0x8(%rsp), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
jmp 0x1113d5
movq 0x8(%rsp), %rdi
addq $0x8, %rdi
movq 0x10(%rsp), %rsi
callq 0xdd0b0
jmp 0x111419
jmp 0x1114d0
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movl 0xa8(%rax), %eax
cmpl (%rcx), %eax
jge 0x11145b
movq 0x53ba7(%rip), %rdi     # 0x164fe0
leaq 0x22e5e(%rip), %rsi     # 0x13429e
callq 0x86700
movq %rax, %rdi
movq 0x53b21(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x27(%rsp)
jmp 0x1114d5
jmp 0x11145d
movq 0x8(%rsp), %rdi
addq $0x8, %rdi
callq 0xdd130
xorb $-0x1, %al
testb $0x1, %al
jne 0x111473
jmp 0x11148d
movq 0x8(%rsp), %rdi
callq 0x1114e0
movq 0x8(%rsp), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
jmp 0x11145d
movq 0x8(%rsp), %rdi
addq $0x8, %rdi
callq 0xdd200
movq 0x8(%rsp), %rdi
addq $0x8, %rdi
movq 0x10(%rsp), %rsi
callq 0xdd0b0
movq 0x8(%rsp), %rax
movq 0x10(%rsp), %rcx
movl 0xa8(%rcx), %ecx
movl %ecx, (%rax)
movq 0x10(%rsp), %rcx
movl 0xac(%rcx), %ecx
movl %ecx, 0x4(%rax)
jmp 0x1114d0
movb $0x1, 0x27(%rsp)
movb 0x27(%rsp), %al
andb $0x1, %al
addq $0x28, %rsp
retq