// File: gersteinlab[P]MUSIC/src/ms_annot_region_tools.cpp
// Function: restructure_annot_regions(std::vector<t_annot_region*, std::allocator<t_annot_region*>>*)
t_sorted_annot_region_lists* restructure_annot_regions(vector<t_annot_region*>* regions)
{
	// This is the list of regions per chromosome.
	vector<char*>* chr_ids = get_chr_ids(regions);
	t_sorted_annot_region_lists* region_lists = new t_sorted_annot_region_lists();

	// The chromosome id list is built up dynamically in the region list loop.
	//region_lists->chr_ids = new vector<char*>();
	region_lists->chr_ids = chr_ids;
	region_lists->neg_strand_regions_per_chrom = new vector<t_annot_region*>*[(int)chr_ids->size() + 2];
	region_lists->pos_strand_regions_per_chrom = new vector<t_annot_region*>*[(int)chr_ids->size() + 2];
	region_lists->regions_per_chrom = new vector<t_annot_region*>*[(int)chr_ids->size() + 2];

	for(int i_chr = 0; i_chr < (int)chr_ids->size(); i_chr++)
	{
		region_lists->pos_strand_regions_per_chrom[i_chr] = new vector<t_annot_region*>();
		region_lists->neg_strand_regions_per_chrom[i_chr] = new vector<t_annot_region*>();
		region_lists->regions_per_chrom[i_chr] = new vector<t_annot_region*>();
	} // i_chr loop.

	// Go over all the regions and separate them into appropriate list.
	for(int i_reg = 0; i_reg < (int)regions->size(); i_reg++)
	{
		int i_chr = t_string::get_i_str(chr_ids, regions->at(i_reg)->chrom);

		if(i_chr < (int)chr_ids->size())
		{
			region_lists->regions_per_chrom[i_chr]->push_back(regions->at(i_reg));

			if(regions->at(i_reg)->strand == '+')
			{
				region_lists->pos_strand_regions_per_chrom[i_chr]->push_back(regions->at(i_reg));
			}
			else if(regions->at(i_reg)->strand == '-')
			{
				region_lists->neg_strand_regions_per_chrom[i_chr]->push_back(regions->at(i_reg));
			}
			else
			{
				printf("Unknown strand char %c @ %s(%d).\n", regions->at(i_reg)->strand, __FILE__, __LINE__);
				exit(0);
			}
		}
	} // i_reg loop.

	// Sort the regions per chromosome and all the regions.
	for(int i_chr = 0; i_chr < (int)chr_ids->size(); i_chr++)
	{
		sort(region_lists->pos_strand_regions_per_chrom[i_chr]->begin(), region_lists->pos_strand_regions_per_chrom[i_chr]->end(), sort_regions);
		sort(region_lists->neg_strand_regions_per_chrom[i_chr]->begin(), region_lists->neg_strand_regions_per_chrom[i_chr]->end(), sort_regions);
		sort(region_lists->regions_per_chrom[i_chr]->begin(), region_lists->regions_per_chrom[i_chr]->end(), sort_regions);
	} // i_chr loop.

	// Finally sort the regions.
	return(region_lists);
}

// Assembly:
subq $0xb8, %rsp
movq %rdi, 0xb0(%rsp)
movq 0xb0(%rsp), %rdi
callq 0x2a910
movq %rax, 0xa8(%rsp)
movl $0x20, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x58(%rsp)
xorl %esi, %esi
movl $0x20, %edx
callq 0x2110
movq 0x58(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa8(%rsp), %rcx
movq 0xa0(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0xa8(%rsp), %rdi
callq 0xc220
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0xa8(%rsp), %rdi
callq 0xc220
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0xa8(%rsp), %rdi
callq 0xc220
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movq %rcx, (%rax)
movl $0x0, 0x9c(%rsp)
movl 0x9c(%rsp), %eax
movl %eax, 0x54(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xc220
movq %rax, %rcx
movl 0x54(%rsp), %eax
cmpl %ecx, %eax
jge 0x2943e
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x38(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0x38(%rsp), %rdi
callq 0xc670
movq 0x38(%rsp), %rdx
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0x9c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x40(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0x40(%rsp), %rdi
callq 0xc670
movq 0x40(%rsp), %rdx
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x9c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x48(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0x48(%rsp), %rdi
callq 0xc670
movq 0x48(%rsp), %rdx
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0x9c(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0x29333
movl $0x0, 0x98(%rsp)
movl 0x98(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0x2962e
movq 0xa8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq 0x28(%rsp), %rdi
movq (%rax), %rax
movq (%rax), %rsi
callq 0x47cf0
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
movl %eax, 0x30(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xc220
movq %rax, %rcx
movl 0x30(%rsp), %eax
cmpl %ecx, %eax
jge 0x29616
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0x94(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x20(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0xc8c0
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2b, %eax
jne 0x29573
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0x94(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x18(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0xc8c0
jmp 0x29614
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2d, %eax
jne 0x295d5
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x94(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0xc8c0
jmp 0x29612
movq 0xb0(%rsp), %rdi
movslq 0x98(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movsbl 0x8(%rax), %esi
leaq 0x2c789(%rip), %rdi     # 0x55d81
leaq 0x2c7a4(%rip), %rdx     # 0x55da3
movl $0x241, %ecx            # imm = 0x241
movb $0x0, %al
callq 0x2050
xorl %edi, %edi
callq 0x21f0
jmp 0x29614
jmp 0x29616
jmp 0x29618
movl 0x98(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x98(%rsp)
jmp 0x29449
movl $0x0, 0x90(%rsp)
movl 0x90(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0xa8(%rsp), %rdi
callq 0xc220
movq %rax, %rcx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x2978e
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0x90(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc7d0
movq %rax, 0x88(%rsp)
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0x90(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc760
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
leaq 0xcdf(%rip), %rdx       # 0x2a3a0
callq 0x31d00
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x90(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc7d0
movq %rax, 0x78(%rsp)
movq 0xa0(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x90(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc760
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rdi
movq 0x70(%rsp), %rsi
leaq 0xc85(%rip), %rdx       # 0x2a3a0
callq 0x31d00
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0x90(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc7d0
movq %rax, 0x68(%rsp)
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0x90(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc760
movq %rax, 0x60(%rsp)
movq 0x68(%rsp), %rdi
movq 0x60(%rsp), %rsi
leaq 0xc2d(%rip), %rdx       # 0x2a3a0
callq 0x31d00
movl 0x90(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x90(%rsp)
jmp 0x29639
movq 0xa0(%rsp), %rax
addq $0xb8, %rsp
retq
nop