// File: /workspace/github_c_makefile_star2_O2/sc932[P]ALE/src/ALEhelpers.c
// Function: getPairedMateOrientation
enum MATE_ORIENTATION getPairedMateOrientation(bam1_t *read1) {
    char paired = (read1->core.flag & BAM_FPAIRED) == BAM_FPAIRED;
    char read1unmap = ((read1->core.flag & BAM_FUNMAP)  == BAM_FUNMAP)  | (read1->core.tid < 0);
    char read2unmap = ((read1->core.flag & BAM_FMUNMAP) == BAM_FMUNMAP) | ( paired && read1->core.mtid < 0);

    if (read1unmap | read2unmap) {
        // read or mate is not mapped
        if (paired) {
        	// paired
        	if (read1unmap && read2unmap) {
        		// neither read is mapped
        		return UNMAPPED_PAIR;
        	} else {
        		// only one read in the pair is mapped
        		if ((read1->core.flag & (BAM_FREAD1|BAM_FREAD2)) != 0) {
        			return read1unmap ? UNMAPPED_MATE : SINGLE_UNMAPPED_MATE;
        		} else {
        			// not simply a pair of two reads, treat like single (think PacBio...)
        			return read1unmap ? UNMAPPED_SINGLE : SINGLE_READ;
        		}
        	}
        } else {
        	// not paired, so single.
        	return read1unmap ? UNMAPPED_SINGLE : SINGLE_READ;
        }
    }

    // this read (and potential mate) is mapped
    assert((read1->core.flag & BAM_FUNMAP) != BAM_FUNMAP);

    if (!paired) {
    	//printf("%s is single\n", bam1_qname(read1));
        return SINGLE_READ;
    }
    if (((read1->core.flag & (BAM_FREAD1 | BAM_FREAD2)) == 0) || (read1->core.isize == 0 && read1->core.tid >= 0 && read1->core.tid == read1->core.mtid)) {
        // required for PacBio reads that claim they are pairs but are not in a strict sense
    	//printf("%s is single (forced)\n", bam1_qname(read1));
    	return SINGLE_READ;
    }
    assert((read1->core.flag & BAM_FPAIRED) == BAM_FPAIRED);

    char isProper = ((read1->core.flag & BAM_FPROPER_PAIR) == BAM_FPROPER_PAIR);
    if (read1->core.tid == read1->core.mtid) {
        // reads map to same contig
        int read1Dir = (read1->core.flag & BAM_FREVERSE) == BAM_FREVERSE ? 1 : 0;
        int read2Dir = (read1->core.flag & BAM_FMREVERSE) == BAM_FMREVERSE ? 1 : 0;
        if (read1Dir == read2Dir)
        	return (isProper ? VALID_FF : NOT_PROPER_FF);
        else {
        	// TODO rethink this if read sizes are different could use read1->core.isize instead
        	int readLength = getSeqMapLenBAM(read1);
        	if (read1Dir == 0) {
        		if (read1->core.pos <= read1->core.mpos + readLength)
        			return (isProper ? VALID_FR : NOT_PROPER_FR);
                else
        		    return (isProper ? VALID_RF : NOT_PROPER_RF);
        	} else {
        		if (read1->core.mpos <= read1->core.pos + readLength)
        			return (isProper ? VALID_FR : NOT_PROPER_FR);
                else
        		    return (isProper ? VALID_RF : NOT_PROPER_RF);
        	}
        }
    } else {
        // reads map to different contig
        return CHIMER;
    }

}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x8(%rdi), %r14
movq %r14, %rdx
shrq $0x22, %rdx
andl $0x1, %edx
movl (%rdi), %ecx
movl %ecx, %eax
shrl $0x1f, %eax
orl %edx, %eax
movq %r14, %rdx
shrq $0x23, %rdx
andl $0x1, %edx
btq $0x20, %r14
jb 0x9a6a
orl %eax, %edx
je 0x9a83
cmpl $0x1, %eax
pushq $0xc
popq %rax
sbbl $0x0, %eax
jmp 0x9b0e
movl 0x14(%rbx), %esi
shrl $0x1f, %esi
orl %edx, %esi
movl %esi, %edx
orl %eax, %edx
je 0x9a83
testl %esi, %eax
je 0x9af2
pushq $0x6
jmp 0x9b0d
movq %r14, %rdx
shrq $0x20, %rdx
testb $0x4, %dl
jne 0x9b4d
btq $0x20, %r14
setae %al
testb $-0x40, %dl
sete %sil
orb %al, %sil
pushq $0xb
popq %rax
jne 0x9b0e
testl %ecx, %ecx
setns %dil
movl 0x14(%rbx), %esi
movl %ecx, %r8d
xorl %esi, %r8d
orl 0x1c(%rbx), %r8d
sete %r8b
testb %dil, %r8b
jne 0x9b0e
cmpl %esi, %ecx
jne 0x9b0b
shrq $0x21, %r14
movl %edx, %ebp
shrl $0x4, %ebp
andl $0x1, %ebp
btl $0x5, %edx
movl %ebp, %eax
sbbl $0x0, %eax
jne 0x9b13
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
addl $0x2, %eax
jmp 0x9b0e
movabsq $0xc000000000, %rcx     # imm = 0xC000000000
testq %rcx, %r14
je 0x9b06
orl $0x8, %eax
jmp 0x9b0e
addl $0xb, %eax
jmp 0x9b0e
pushq $0x7
popq %rax
popq %rbx
popq %r14
popq %rbp
retq
movq %rbx, %rdi
callq 0x9986
testl %ebp, %ebp
jne 0x9b35
addl 0x18(%rbx), %eax
cmpl %eax, 0x4(%rbx)
jg 0x9b3d
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
jmp 0x9b0e
addl 0x4(%rbx), %eax
cmpl %eax, 0x18(%rbx)
jle 0x9b27
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
incl %eax
jmp 0x9b0e
leaq 0x162ab(%rip), %rdi     # 0x1fdff
leaq 0x1614b(%rip), %rsi     # 0x1fca6
leaq 0x162cb(%rip), %rcx     # 0x1fe2d
movl $0x267, %edx            # imm = 0x267
callq 0x3230