// File: /workspace/github_c_makefile_star2_O1/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), %rsi
movq %rsi, %rax
shrq $0x22, %rax
andl $0x1, %eax
movl (%rdi), %ecx
movl %ecx, %edx
shrl $0x1f, %edx
orl %eax, %edx
movq %rsi, %rax
shrq $0x23, %rax
andl $0x1, %eax
xorl %edi, %edi
btq $0x20, %rsi
jae 0xbb31
movl 0x14(%rbx), %edi
shrl $0x1f, %edi
orl %eax, %edi
movl %edi, %eax
orl %edx, %eax
je 0xbb54
btq $0x20, %rsi
jb 0xbbce
cmpl $0x1, %edx
movl $0xc, %eax
sbbl $0x0, %eax
jmp 0xbbf4
movq %rsi, %rdx
shrq $0x20, %rdx
testb $0x4, %dl
jne 0xbc3a
btq $0x20, %rsi
setae %al
testb $-0x40, %dl
sete %dil
orb %al, %dil
movl $0xb, %eax
jne 0xbbf4
cmpl $0x0, 0x1c(%rbx)
sete %dil
testl %ecx, %ecx
setns %r8b
andb %dil, %r8b
cmpb $0x1, %r8b
jne 0xbb99
cmpl 0x14(%rbx), %ecx
je 0xbbf4
movl $0x7, %eax
cmpl 0x14(%rbx), %ecx
jne 0xbbf4
movq %rsi, %r14
shrq $0x21, %r14
movl %edx, %ebp
shrl $0x4, %ebp
andl $0x1, %ebp
btl $0x5, %edx
movl %ebp, %eax
sbbl $0x0, %eax
jne 0xbbf9
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
addl $0x2, %eax
jmp 0xbbf4
testl %edx, %edx
je 0xbbdb
movl $0x6, %eax
testl %edi, %edi
jne 0xbbf4
movabsq $0xc000000000, %rax     # imm = 0xC000000000
testq %rax, %rsi
je 0xbbef
orl $0x8, %edx
jmp 0xbbf2
addl $0xb, %edx
movl %edx, %eax
popq %rbx
popq %r14
popq %rbp
retq
shrl $0x18, %esi
addq 0x30(%rbx), %rsi
movq %rbx, %rdi
callq 0xf3c6
testl %ebp, %ebp
jne 0xbc22
addl 0x18(%rbx), %eax
cmpl %eax, 0x4(%rbx)
jg 0xbc2a
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
jmp 0xbbf4
addl 0x4(%rbx), %eax
cmpl %eax, 0x18(%rbx)
jle 0xbc14
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
incl %eax
jmp 0xbbf4
leaq 0x1815e(%rip), %rdi     # 0x23d9f
leaq 0x17ffe(%rip), %rsi     # 0x23c46
leaq 0x1817e(%rip), %rcx     # 0x23dcd
movl $0x267, %edx            # imm = 0x267
callq 0x3230