// File: zeeev[P]DASVC/bamtools/src/api/BamAlignment.cpp
// Function: BamTools::BamAlignment::GetSoftClips(std::vector<int, std::allocator<int>>&, std::vector<int, std::allocator<int>>&, std::vector<int, std::allocator<int>>&, bool) const
bool BamAlignment::GetSoftClips(vector<int>& clipSizes,
                                vector<int>& readPositions,
                                vector<int>& genomePositions,
                                bool usePadded) const
{
    // initialize positions & flags
    int refPosition  = Position;
    int readPosition = 0;
    bool softClipFound = false;
    bool firstCigarOp  = true;

    // iterate over cigar operations
    vector<CigarOp>::const_iterator cigarIter = CigarData.begin();
    vector<CigarOp>::const_iterator cigarEnd  = CigarData.end();
    for ( ; cigarIter != cigarEnd; ++cigarIter) {
        const CigarOp& op = (*cigarIter);

        switch ( op.Type ) {

            // increase both read & genome positions on CIGAR chars [DMXN=]
            case Constants::BAM_CIGAR_DEL_CHAR      :
            case Constants::BAM_CIGAR_MATCH_CHAR    :
            case Constants::BAM_CIGAR_MISMATCH_CHAR :
            case Constants::BAM_CIGAR_REFSKIP_CHAR  :
            case Constants::BAM_CIGAR_SEQMATCH_CHAR :
                refPosition  += op.Length;
                readPosition += op.Length;
                break;

            // increase read position on insertion, genome position only if @usePadded is true
            case Constants::BAM_CIGAR_INS_CHAR :
                readPosition += op.Length;
                if ( usePadded )
                    refPosition += op.Length;
                break;

            case Constants::BAM_CIGAR_SOFTCLIP_CHAR :

                softClipFound = true;

                //////////////////////////////////////////////////////////////////////////////
                // if we are dealing with the *first* CIGAR operation
                // for this alignment, we increment the read position so that
                // the read and genome position of the clip are referring to the same base.
                // For example, in the alignment below, the ref position would be 4, yet
                //              the read position would be 0. Thus, to "sync" the two,
                //              we need to increment the read position by the length of the
                //              soft clip.
                // Read:  ATCGTTTCGTCCCTGC
                // Ref:   GGGATTTCGTCCCTGC
                // Cigar: SSSSMMMMMMMMMMMM
                //
                // NOTE: This only needs to be done if the soft clip is the _first_ CIGAR op.
                //////////////////////////////////////////////////////////////////////////////
                if ( firstCigarOp )
                    readPosition += op.Length;

                // track the soft clip's size, read position, and genome position
                clipSizes.push_back(op.Length);
                readPositions.push_back(readPosition);
                genomePositions.push_back(refPosition);

            // any other CIGAR operations have no effect
            default :
                break;
        }

        // clear our "first pass" flag
        firstCigarOp = false;
    }

    // return whether any soft clips found
    return softClipFound;
}

// Assembly:
subq $0x68, %rsp
movb %r8b, %al
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movq %rcx, 0x48(%rsp)
andb $0x1, %al
movb %al, 0x47(%rsp)
movq 0x60(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movl 0xac(%rdi), %eax
movl %eax, 0x40(%rsp)
movl $0x0, 0x3c(%rsp)
movb $0x0, 0x3b(%rsp)
movb $0x1, 0x3a(%rsp)
addq $0xb8, %rdi
callq 0x75e20
movq 0x10(%rsp), %rdi
movq %rax, 0x30(%rsp)
addq $0xb8, %rdi
callq 0x76450
movq %rax, 0x28(%rsp)
leaq 0x30(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x75bf0
testb $0x1, %al
jne 0x88006
jmp 0x8811f
leaq 0x30(%rsp), %rdi
callq 0x765d0
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
movsbl (%rax), %eax
movl %eax, 0xc(%rsp)
subl $0x3d, %eax
je 0x88066
jmp 0x88028
movl 0xc(%rsp), %eax
subl $0x44, %eax
je 0x88066
jmp 0x88033
movl 0xc(%rsp), %eax
subl $0x49, %eax
je 0x8808b
jmp 0x8803e
movl 0xc(%rsp), %eax
addl $-0x4d, %eax
subl $0x2, %eax
jb 0x88066
jmp 0x8804c
movl 0xc(%rsp), %eax
subl $0x53, %eax
je 0x880b4
jmp 0x88057
movl 0xc(%rsp), %eax
subl $0x58, %eax
jne 0x88109
jmp 0x88066
movq 0x20(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x40(%rsp), %eax
movl %eax, 0x40(%rsp)
movq 0x20(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x3c(%rsp), %eax
movl %eax, 0x3c(%rsp)
jmp 0x8810b
movq 0x20(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x3c(%rsp), %eax
movl %eax, 0x3c(%rsp)
testb $0x1, 0x47(%rsp)
je 0x880b2
movq 0x20(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x40(%rsp), %eax
movl %eax, 0x40(%rsp)
jmp 0x8810b
movb $0x1, 0x3b(%rsp)
testb $0x1, 0x3a(%rsp)
je 0x880d0
movq 0x20(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x3c(%rsp), %eax
movl %eax, 0x3c(%rsp)
movq 0x58(%rsp), %rdi
movq 0x20(%rsp), %rax
movl 0x4(%rax), %eax
movl %eax, 0x1c(%rsp)
leaq 0x1c(%rsp), %rsi
callq 0x719e0
movq 0x50(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
callq 0x719e0
movq 0x48(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x719e0
jmp 0x8810b
movb $0x0, 0x3a(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x72bc0
jmp 0x87fee
movb 0x3b(%rsp), %al
andb $0x1, %al
addq $0x68, %rsp
retq
nopw (%rax,%rax)