// File: gersteinlab[P]MUSIC/src/ms_annot_region_tools.cpp
// Function: merge_annot_regions(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*, int, bool)
vector<t_annot_region*>* merge_annot_regions(vector<t_annot_region*>* total_annot_regions,
											int max_gap, 
											bool match_strands) // Maximum distance between two annotated regions that are in the merged region.
{
	//printf("Merging %d regions.\n", total_annot_regions->size());

	//fprintf(stderr, "All region list contains %d regions.\n", total_annot_regions->size());

	vector<t_annot_region*>* merged_annot_regions = NULL;

	// Merged annot. regions.
	if(match_strands)
	{
		//printf("Merging with strand information.");
		// Merge plus strand regions.
		vector<t_annot_region*>* plus_strand_regions = get_regions_per_strand(total_annot_regions,
																			'+');
		//printf("%d plus strand regions.\n", plus_strand_regions->size());
		vector<t_annot_region*>* merged_plus_strand_regions = merge_annot_regions(plus_strand_regions, max_gap);

		// Merge negative strand regions.
		vector<t_annot_region*>* neg_strand_regions = get_regions_per_strand(total_annot_regions,
																			'-');
		//printf("%d negative strand regions.\n", neg_strand_regions->size());
		vector<t_annot_region*>* merged_neg_strand_regions = merge_annot_regions(neg_strand_regions, max_gap);

		// Pool the merged plus and minus strand regions.
		merged_annot_regions = new vector<t_annot_region*>();
		for(int i_reg = 0; i_reg < (int)merged_plus_strand_regions->size(); i_reg++)
		{
			merged_annot_regions->push_back(merged_plus_strand_regions->at(i_reg));
		} // i_reg loop

		for(int i_reg = 0; i_reg < (int)merged_neg_strand_regions->size(); i_reg++)
		{
			merged_annot_regions->push_back(merged_neg_strand_regions->at(i_reg));
		} // i_reg loop

		merged_plus_strand_regions->clear();
		delete(merged_plus_strand_regions);

		merged_neg_strand_regions->clear();
		delete(merged_neg_strand_regions);
	}
	else
	{
		 merged_annot_regions = merge_annot_regions(total_annot_regions, max_gap);
	}

	//printf("Merged into %d regions\n", merged_annot_regions->size());
	return(merged_annot_regions);
}

// Assembly:
subq $0x78, %rsp
movb %dl, %al
movq %rdi, 0x70(%rsp)
movl %esi, 0x6c(%rsp)
andb $0x1, %al
movb %al, 0x6b(%rsp)
movq $0x0, 0x60(%rsp)
testb $0x1, 0x6b(%rsp)
je 0x2f53e
movq 0x70(%rsp), %rdi
movl $0x2b, %esi
callq 0x2ed10
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x308f0
movq %rax, 0x50(%rsp)
movq 0x70(%rsp), %rdi
movl $0x2d, %esi
callq 0x2ed10
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x308f0
movq %rax, 0x40(%rsp)
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x30(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0x30(%rsp), %rdi
callq 0xc670
movq 0x30(%rsp), %rax
movq %rax, 0x60(%rsp)
movl $0x0, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x50(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2f481
movq 0x60(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x50(%rsp), %rdi
movslq 0x3c(%rsp), %rsi
callq 0xc800
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0xc8c0
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x2f431
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x40(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2f4d9
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x40(%rsp), %rdi
movslq 0x38(%rsp), %rsi
callq 0xc800
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0xc8c0
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x2f489
movq 0x50(%rsp), %rdi
callq 0x31d90
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x2f50c
movq 0x8(%rsp), %rdi
callq 0xc970
movq 0x8(%rsp), %rdi
movl $0x18, %esi
callq 0x21a0
movq 0x40(%rsp), %rdi
callq 0x31d90
movq 0x40(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x2f53c
movq (%rsp), %rdi
callq 0xc970
movq (%rsp), %rdi
movl $0x18, %esi
callq 0x21a0
jmp 0x2f551
movq 0x70(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x308f0
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
addq $0x78, %rsp
retq
nopl (%rax,%rax)