// File: /workspace/github_cpp_makefile_star2_O3/gersteinlab[P]MUSIC/src/ms_annot_region_tools.cpp
// Function: subtract_annot_regions(t_annot_region*, t_annot_region*, bool)
vector<t_annot_region*>* subtract_annot_regions(t_annot_region* region1, t_annot_region* region2, bool strand_specific)
{
	vector<t_annot_region*>* remaining_regions = new vector<t_annot_region*>();	

	if((!strand_specific && region1->strand != region2->strand) || 
		(strcmp(region1->chrom, region2->chrom) != 0))
	{
		t_annot_region* dup_region = duplicate_region(region1);
		remaining_regions->push_back(dup_region);
		return(remaining_regions);
	}

	// Check if there is overlap between region1 and region2.
	int ol_start = MAX(region1->start, region2->start);
	int ol_end = MIN(region1->end, region2->end);

	if(ol_start < ol_end)
	{
		// There is overlap between regions. Take the region that is excluded from the overlap. 
		// There are 4 possibilities of overlap:
		// os=s1<e1=ol: region2 fully contains region1
		// s1<os<e1=ol: region2 overlaps partialy with region1 on right side.
		// s1=os<ol<e1: region2 overlaps partialy with region1 on left side.
		// s1<os<ol<e1: region1 fully contains region2 with extra parts on the sides.
		if(region1->start == ol_start && 
			region1->end == ol_end)
		{
			// Nothing is left in region1 after exclusion.
		}
		else if(region1->start < ol_start && 
			region1->end == ol_end)
		{
			// Left side of region1 is left.
			t_annot_region* dup_region = duplicate_region(region1);
			dup_region->end = ol_start;
			remaining_regions->push_back(dup_region);
		}
		else if(region1->start == ol_start && 
			ol_end < region1->end)
		{
			t_annot_region* dup_region = duplicate_region(region1);
			dup_region->start = ol_end;
			remaining_regions->push_back(dup_region);
		}
		else if(region1->start < ol_start && 
			ol_end < region1->end)
		{
			t_annot_region* dup_region1 = duplicate_region(region1);
			t_annot_region* dup_region2 = duplicate_region(region1);
			dup_region1->end = ol_start;
			dup_region2->start = ol_end;
			remaining_regions->push_back(dup_region1);
			remaining_regions->push_back(dup_region2);
		}
		else
		{
			fprintf(stderr, "Could not resolve the excluded region with overlapping of: %s:%d-%d and %s:%d-%d.\n", region1->chrom, region1->start, region1->end,
				region2->chrom, region2->start, region2->end);
			exit(0);
		}
	}
	else
	{
		t_annot_region* dup_region = duplicate_region(region1);
		remaining_regions->push_back(dup_region);
	}

	return(remaining_regions);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edx, %ebp
movq %rsi, %r13
movq %rdi, %r14
movl $0x18, %edi
callq 0x2180
movq %rax, %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq $0x0, 0x10(%rax)
testl %ebp, %ebp
jne 0x1a00f
movb 0x8(%r14), %al
cmpb 0x8(%r13), %al
jne 0x1a07f
movq (%r14), %r12
movq (%r13), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0x2240
testl %eax, %eax
jne 0x1a07f
movl 0xc(%r14), %ecx
movl 0x20(%r14), %r8d
movl 0xc(%r13), %r10d
movl 0x20(%r13), %r11d
cmpl %r10d, %ecx
movl %r10d, %ebp
cmovgl %ecx, %ebp
cmpl %r11d, %r8d
movl %r11d, %r13d
cmovll %r8d, %r13d
cmpl %r13d, %ebp
jge 0x1a07f
cmpl %r10d, %ecx
setge %al
cmpl %r11d, %r8d
setle %dl
testb %dl, %al
jne 0x1a0ad
cmpl %r11d, %r8d
setg %al
cmpl %ecx, %r10d
setle %dl
orb %al, %dl
jne 0x1a0bf
movq %r14, %rdi
callq 0x16f1f
movq %rax, 0x8(%rsp)
movl %ebp, 0x20(%rax)
jmp 0x1a08c
movq %r14, %rdi
callq 0x16f1f
movq %rax, 0x8(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x1a0a0
movq %rax, (%rsi)
addq $0x8, 0x8(%rbx)
jmp 0x1a0ad
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
callq 0xb74c
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl %r10d, %ecx
setl %al
cmpl %r8d, %r11d
setge %dl
orb %al, %dl
jne 0x1a0ed
movq %r14, %rdi
callq 0x16f1f
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
movl %r13d, 0xc(%rax)
movq %rbx, %rdi
callq 0x1c3e8
jmp 0x1a0ad
cmpl %ecx, %r10d
jle 0x1a163
cmpl %r8d, %r11d
jge 0x1a163
movq %r14, %rdi
callq 0x16f1f
movq %rax, %r15
movq %rax, 0x8(%rsp)
movq %r14, %rdi
callq 0x16f1f
movq %rax, %r14
movq %rax, 0x10(%rsp)
movl %ebp, 0x20(%r15)
movl %r13d, 0xc(%rax)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x1a13a
movq %r15, (%rsi)
movq 0x8(%rbx), %rsi
addq $0x8, %rsi
movq %rsi, 0x8(%rbx)
jmp 0x1a14b
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
callq 0xb74c
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x1a159
movq %r14, (%rsi)
jmp 0x1a099
leaq 0x10(%rsp), %rdx
jmp 0x1a0a5
movq 0x1ee76(%rip), %rax     # 0x38fe0
movq (%rax), %rdi
leaq 0x13c4e(%rip), %rsi     # 0x2ddc2
movq %r12, %rdx
movq %r15, %r9
xorl %eax, %eax
pushq %r11
pushq %r10
callq 0x2250
addq $0x10, %rsp
xorl %edi, %edi
callq 0x21e0