// File: gersteinlab[P]MUSIC/src/ms_annot_region_tools.cpp
// Function: get_inter_region_distance_distribution(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, std::vector<t_annot_region*, std::allocator<t_annot_region*>>*)
vector<int>* get_inter_region_distance_distribution(vector<t_annot_region*>* annot_regions1, 
	vector<t_annot_region*>* annot_regions2)
{
	int max_dist = 10*1000*1000;

	vector<int>* distances = new vector<int>();

	t_sorted_annot_region_lists* restr_regs1 = restructure_annot_regions(annot_regions1);
	t_sorted_annot_region_lists* restr_regs2 = restructure_annot_regions(annot_regions2);

	for(int i_chr1 = 0; i_chr1 < (int)restr_regs1->chr_ids->size(); i_chr1++)
	{
		fprintf(stderr, "Processing regions in %s\n", restr_regs1->chr_ids->at(i_chr1));

		int i_chr2 = t_string::get_i_str(restr_regs2->chr_ids, restr_regs1->chr_ids->at(i_chr1));
		vector<t_annot_region*>* cur_chr_regs1 = restr_regs1->regions_per_chrom[i_chr1];

		if(i_chr2 < (int)restr_regs2->chr_ids->size())
		{			
			vector<t_annot_region*>* cur_chr_regs2 = restr_regs2->regions_per_chrom[i_chr2];			

			for(int i_reg1 = 0; i_reg1 < (int)cur_chr_regs1->size(); i_reg1++)
			{
				fprintf(stderr, "Searching for %s:%d-%d\n", cur_chr_regs1->at(i_reg1)->chrom, cur_chr_regs1->at(i_reg1)->start, cur_chr_regs1->at(i_reg1)->end);

				int cur_reg_min_distance = max_dist;

				int i_loc_reg2 = locate_posn_region_per_region_starts(cur_chr_regs1->at(i_reg1)->start, cur_chr_regs2, 0, (int)cur_chr_regs2->size()-1);

				while(i_loc_reg2 > 0 &&
					cur_chr_regs2->at(i_loc_reg2)->end > cur_chr_regs1->at(i_reg1)->start)
				{
					i_loc_reg2--;
				}

				while(i_loc_reg2 < (int)cur_chr_regs2->size() &&
					cur_chr_regs2->at(i_loc_reg2)->start < cur_chr_regs1->at(i_reg1)->end)
				{
					// Get the distance of the current region2 to region1.
					int cur_dist = get_reg2reg_distance(cur_chr_regs1->at(i_reg1), cur_chr_regs2->at(i_loc_reg2));

					if(cur_reg_min_distance > cur_dist)
					{
						cur_reg_min_distance = cur_dist;
						//fprintf(stderr, "5' close exon: %s:%d-%d\n", cur_chr_regs2->at(i_loc_reg2)->chrom, cur_chr_regs2->at(i_loc_reg2)->start, cur_chr_regs2->at(i_loc_reg2)->end);
						//getc(stdin);
					}

					i_loc_reg2++;
				} // i_loc_reg2 loop.

				// The above loop is out when the reg2 passes over reg1. Must check it again. On the right.
				if(i_loc_reg2 < (int)cur_chr_regs2->size())
				{
					int cur_dist = get_reg2reg_distance(cur_chr_regs1->at(i_reg1), cur_chr_regs2->at(i_loc_reg2));

					if(cur_reg_min_distance > cur_dist)
					{
						cur_reg_min_distance = cur_dist;
						//fprintf(stderr, "3' close exon: %s:%d-%d\n", cur_chr_regs2->at(i_loc_reg2)->chrom, cur_chr_regs2->at(i_loc_reg2)->start, cur_chr_regs2->at(i_loc_reg2)->end);
						//getc(stdin);
					}
				}

				fprintf(stderr, "%s:%d-%d: %d\n", cur_chr_regs1->at(i_reg1)->chrom, cur_chr_regs1->at(i_reg1)->start, cur_chr_regs1->at(i_reg1)->end, cur_reg_min_distance);

				distances->push_back(cur_reg_min_distance);
			} // i_reg1 loop.
		} // i_chr2 check.
		else
		{

			fprintf(stderr, "Could not find %s in chr2 list.\n", restr_regs1->chr_ids->at(i_chr1));
			getc(stdin);

			// Add 10000000 to the distances.
			for(int i_reg1 = 0; i_reg1 < (int)cur_chr_regs1->size(); i_reg1++)
			{
				distances->push_back(max_dist);
			} // i_reg1 loop.
		}
	} // i_chr1 loop.

	return(distances);
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0x100(%rsp)
movq %rsi, 0xf8(%rsp)
movl $0x989680, 0xf4(%rsp) # imm = 0x989680
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0xa0(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0xa0(%rsp), %rdi
callq 0xc290
movq 0xa0(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0x100(%rsp), %rdi
callq 0x29200
movq %rax, 0xe0(%rsp)
movq 0xf8(%rsp), %rdi
callq 0x29200
movq %rax, 0xd8(%rsp)
movl $0x0, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
movl %eax, 0x9c(%rsp)
movq 0xe0(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0xc220
movq %rax, %rcx
movl 0x9c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2df4d
movq 0x37613(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x88(%rsp)
movq 0xe0(%rsp), %rax
movq 0x18(%rax), %rdi
movslq 0xd4(%rsp), %rsi
callq 0xc240
movq 0x88(%rsp), %rdi
movq (%rax), %rdx
leaq 0x28722(%rip), %rsi     # 0x56125
movb $0x0, %al
callq 0x2250
movq 0xd8(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x90(%rsp)
movq 0xe0(%rsp), %rax
movq 0x18(%rax), %rdi
movslq 0xd4(%rsp), %rsi
callq 0xc240
movq 0x90(%rsp), %rdi
movq (%rax), %rsi
callq 0x47cf0
movl %eax, 0xd0(%rsp)
movq 0xe0(%rsp), %rax
movq (%rax), %rax
movslq 0xd4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xc8(%rsp)
movl 0xd0(%rsp), %eax
movl %eax, 0x98(%rsp)
movq 0xd8(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0xc220
movq %rax, %rcx
movl 0x98(%rsp), %eax
cmpl %ecx, %eax
jge 0x2de90
movq 0xd8(%rsp), %rax
movq (%rax), %rax
movslq 0xd0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0xc0(%rsp)
movl $0x0, 0xbc(%rsp)
movl 0xbc(%rsp), %eax
movl %eax, 0x84(%rsp)
movq 0xc8(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x84(%rsp), %eax
cmpl %ecx, %eax
jge 0x2de8b
movq 0x374e4(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x60(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0x70(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rdx
movl 0x70(%rsp), %ecx
movq (%rax), %rax
movl 0x20(%rax), %r8d
leaq 0x285cb(%rip), %rsi     # 0x5613f
movb $0x0, %al
callq 0x2250
movl 0xf4(%rsp), %eax
movl %eax, 0xb8(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0x74(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0xc0(%rsp), %rdi
callq 0xc680
movl 0x74(%rsp), %edi
movq 0x78(%rsp), %rsi
movl %eax, %ecx
subl $0x1, %ecx
xorl %edx, %edx
callq 0x297a0
movl %eax, 0xb4(%rsp)
xorl %eax, %eax
cmpl $0x0, 0xb4(%rsp)
movb %al, 0x5f(%rsp)
jle 0x2dc36
movq 0xc0(%rsp), %rdi
movslq 0xb4(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %eax
movl %eax, 0x58(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x58(%rsp), %eax
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
setg %al
movb %al, 0x5f(%rsp)
movb 0x5f(%rsp), %al
testb $0x1, %al
jne 0x2dc40
jmp 0x2dc53
movl 0xb4(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x2dbde
jmp 0x2dc55
movl 0xb4(%rsp), %eax
movl %eax, 0x50(%rsp)
movq 0xc0(%rsp), %rdi
callq 0xc680
movl 0x50(%rsp), %ecx
movl %eax, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, 0x57(%rsp)
jge 0x2dcc5
movq 0xc0(%rsp), %rdi
movslq 0xb4(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0x4c(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x4c(%rsp), %eax
movq (%rcx), %rcx
cmpl 0x20(%rcx), %eax
setl %al
movb %al, 0x57(%rsp)
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x2dccf
jmp 0x2dd49
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0xc0(%rsp), %rdi
movslq 0xb4(%rsp), %rsi
callq 0xc800
movq 0x40(%rsp), %rdi
movq (%rax), %rsi
callq 0x2df60
movl %eax, 0xb0(%rsp)
movl 0xb8(%rsp), %eax
cmpl 0xb0(%rsp), %eax
jle 0x2dd33
movl 0xb0(%rsp), %eax
movl %eax, 0xb8(%rsp)
movl 0xb4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
jmp 0x2dc55
movl 0xb4(%rsp), %eax
movl %eax, 0x3c(%rsp)
movq 0xc0(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x3c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2ddd2
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0xc0(%rsp), %rdi
movslq 0xb4(%rsp), %rsi
callq 0xc800
movq 0x30(%rsp), %rdi
movq (%rax), %rsi
callq 0x2df60
movl %eax, 0xac(%rsp)
movl 0xb8(%rsp), %eax
cmpl 0xac(%rsp), %eax
jle 0x2ddd0
movl 0xac(%rsp), %eax
movl %eax, 0xb8(%rsp)
jmp 0x2ddd2
movq 0x37207(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x18(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq (%rax), %rax
movq %rax, 0x20(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
movl %eax, 0x2c(%rsp)
movq 0xc8(%rsp), %rdi
movslq 0xbc(%rsp), %rsi
callq 0xc800
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rdx
movl 0x2c(%rsp), %ecx
movq (%rax), %rax
movl 0x20(%rax), %r8d
movl 0xb8(%rsp), %r9d
leaq 0x276a6(%rip), %rsi     # 0x554ff
movb $0x0, %al
callq 0x2250
movq 0xe8(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0xc340
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x2dac8
jmp 0x2df35
movq 0x37149(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movq 0xe0(%rsp), %rax
movq 0x18(%rax), %rdi
movslq 0xd4(%rsp), %rsi
callq 0xc240
movq 0x10(%rsp), %rdi
movq (%rax), %rdx
leaq 0x28290(%rip), %rsi     # 0x56157
movb $0x0, %al
callq 0x2250
movq 0x37103(%rip), %rax     # 0x64fd8
movq (%rax), %rdi
callq 0x20b0
movl $0x0, 0xa8(%rsp)
movl 0xa8(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0xc8(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x2df33
movq 0xe8(%rsp), %rdi
leaq 0xf4(%rsp), %rsi
callq 0xc340
movl 0xa8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa8(%rsp)
jmp 0x2dee8
jmp 0x2df35
jmp 0x2df37
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x2d995
movq 0xe8(%rsp), %rax
addq $0x108, %rsp            # imm = 0x108
retq
nopl (%rax)