// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0x1, %eax
cmpl $0x1, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0x4, %eax
cmpl $0x4, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movq -0x10(%rbp), %rcx
cmpl $0x0, (%rcx)
setl %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movb %al, -0x12(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0x8, %eax
cmpl $0x8, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x28(%rbp)
movsbl -0x11(%rbp), %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x21(%rbp)
je 0xdf73
movq -0x10(%rbp), %rax
cmpl $0x0, 0x14(%rax)
setl %al
movb %al, -0x21(%rbp)
movl -0x28(%rbp), %eax
movb -0x21(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movb %al, -0x13(%rbp)
movsbl -0x12(%rbp), %eax
movsbl -0x13(%rbp), %ecx
orl %ecx, %eax
cmpl $0x0, %eax
je 0xe02b
cmpb $0x0, -0x11(%rbp)
je 0xe00f
movsbl -0x12(%rbp), %eax
cmpl $0x0, %eax
je 0xdfbb
movsbl -0x13(%rbp), %eax
cmpl $0x0, %eax
je 0xdfbb
movl $0x6, -0x4(%rbp)
jmp 0xe246
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0xc0, %eax
cmpl $0x0, %eax
je 0xdff3
movsbl -0x12(%rbp), %edx
movl $0x8, %eax
movl $0x9, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movsbl -0x12(%rbp), %edx
movl $0xb, %eax
movl $0xc, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movsbl -0x12(%rbp), %edx
movl $0xb, %eax
movl $0xc, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0x4, %eax
cmpl $0x4, %eax
je 0xe047
jmp 0xe066
leaq 0x23921(%rip), %rdi     # 0x3196f
leaq 0x237c1(%rip), %rsi     # 0x31816
movl $0x267, %edx            # imm = 0x267
leaq 0x2393c(%rip), %rcx     # 0x3199d
callq 0x3220
cmpb $0x0, -0x11(%rbp)
jne 0xe078
movl $0xb, -0x4(%rbp)
jmp 0xe246
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0xc0, %eax
cmpl $0x0, %eax
je 0xe0b6
movq -0x10(%rbp), %rax
cmpl $0x0, 0x1c(%rax)
jne 0xe0c2
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jl 0xe0c2
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x14(%rcx), %eax
jne 0xe0c2
movl $0xb, -0x4(%rbp)
jmp 0xe246
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0x1, %eax
cmpl $0x1, %eax
jne 0xe0de
jmp 0xe0fd
leaq 0x238f1(%rip), %rdi     # 0x319d6
leaq 0x2372a(%rip), %rsi     # 0x31816
movl $0x272, %edx            # imm = 0x272
leaq 0x238a5(%rip), %rcx     # 0x3199d
callq 0x3220
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
andl $0x2, %eax
cmpl $0x2, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movb %al, -0x14(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x14(%rcx), %eax
jne 0xe23f
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
movl %eax, %edx
andl $0x10, %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x10, %edx
cmovel %ecx, %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
andq $0xffff, %rax           # imm = 0xFFFF
movl %eax, %edx
andl $0x20, %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x20, %edx
cmovel %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jne 0xe1a5
movsbl -0x14(%rbp), %edx
movl $0x5, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movq -0x10(%rbp), %rdi
callq 0xdd80
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x18(%rbp)
jne 0xe1fb
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
movl 0x18(%rcx), %ecx
addl -0x20(%rbp), %ecx
cmpl %ecx, %eax
jg 0xe1e2
movsbl -0x14(%rbp), %edx
movl $0x3, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movsbl -0x14(%rbp), %edx
movl $0x4, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
movq -0x10(%rbp), %rcx
movl 0x4(%rcx), %ecx
addl -0x20(%rbp), %ecx
cmpl %ecx, %eax
jg 0xe226
movsbl -0x14(%rbp), %edx
movl $0x3, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movsbl -0x14(%rbp), %edx
movl $0x4, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe246
movl $0x7, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nop