// File: /workspace/github_c_makefile_star2_O3/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
btq $0x20, %rsi
jb 0xbdc0
orl %edx, %eax
je 0xbdef
cmpl $0x1, %edx
movl $0xc, %eax
sbbl $0x0, %eax
jmp 0xbe6d
movl 0x14(%rbx), %edi
shrl $0x1f, %edi
orl %eax, %edi
movl %edi, %eax
orl %edx, %eax
je 0xbdef
movl $0x6, %eax
testl %edi, %edx
jne 0xbe6d
movabsq $0xc000000000, %rax     # imm = 0xC000000000
testq %rax, %rsi
je 0xbe68
orl $0x8, %edx
jmp 0xbe6b
movq %rsi, %rdx
shrq $0x20, %rdx
testb $0x4, %dl
jne 0xbeb3
btq $0x20, %rsi
setae %al
testb $-0x40, %dl
sete %dil
orb %al, %dil
movl $0xb, %eax
jne 0xbe6d
testl %ecx, %ecx
setns %r8b
movl 0x14(%rbx), %edi
movl %ecx, %r9d
xorl %edi, %r9d
orl 0x1c(%rbx), %r9d
sete %r9b
testb %r8b, %r9b
jne 0xbe6d
movl $0x7, %eax
cmpl %edi, %ecx
jne 0xbe6d
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 0xbe72
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
addl $0x2, %eax
jmp 0xbe6d
addl $0xb, %edx
movl %edx, %eax
popq %rbx
popq %r14
popq %rbp
retq
shrl $0x18, %esi
addq 0x30(%rbx), %rsi
movq %rbx, %rdi
callq 0xf7bd
testl %ebp, %ebp
jne 0xbe9b
addl 0x18(%rbx), %eax
cmpl %eax, 0x4(%rbx)
jg 0xbea3
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
jmp 0xbe6d
addl 0x4(%rbx), %eax
cmpl %eax, 0x18(%rbx)
jle 0xbe8d
xorl %eax, %eax
testb $0x1, %r14b
sete %al
leal (%rax,%rax,2), %eax
incl %eax
jmp 0xbe6d
leaq 0x17f75(%rip), %rdi     # 0x23e2f
leaq 0x17e15(%rip), %rsi     # 0x23cd6
leaq 0x17f95(%rip), %rcx     # 0x23e5d
movl $0x267, %edx            # imm = 0x267
callq 0x3230