// File: gersteinlab[P]MUSIC/src/ms_genome_sequence_tools.cpp
// Function: batch_extract_region_sequences(char*, std::vector<t_annot_region*, std::allocator<t_annot_region*>>*)
void batch_extract_region_sequences(char* chr_data_dir, vector<t_annot_region*>* regions)
{
	//vector<t_annot_region*>* regions = load_BED(regions_bed_fp);

	vector<char*>* chr_ids = get_chr_ids(regions);

	for(int i_chr = 0; i_chr < (int)chr_ids->size(); i_chr++)
	{
		vector<t_annot_region*>* cur_chr_regions = get_regions_per_chromosome(regions, chr_ids->at(i_chr));

		fprintf(stderr, "Extracting sequences in %s\n", chr_ids->at(i_chr));

		// Sort the regions.
		sort(cur_chr_regions->begin(), cur_chr_regions->end(), sort_regions);

		char chr_seq_fp[1000];
		sprintf(chr_seq_fp, "%s/%s.bin", chr_data_dir, chr_ids->at(i_chr));
		if(check_file(chr_seq_fp))
		{
			FILE* f_chr = open_f(chr_seq_fp, "rb");

			// Go over all the regions.
			for(int i_reg = 0; i_reg < (int)cur_chr_regions->size(); i_reg++)
			{
				fprintf(stderr, "%d (%ld)             \r", i_reg, cur_chr_regions->size());

				int l_reg = cur_chr_regions->at(i_reg)->end - cur_chr_regions->at(i_reg)->start + 1;
				int f_start = cur_chr_regions->at(i_reg)->start - 1 + sizeof(int);
				int f_end = f_start + l_reg - 1;

				int length = f_end - f_start + 1;

				char* seq_buffer = new char[length + 2];
				memset(seq_buffer, 0, sizeof(char) * (length + 1));

				// Read the data.
				fseek(f_chr, f_start, SEEK_SET);

				// Fill the buffer.
				fread(seq_buffer, length, 1, f_chr);

				// If the requested strand is on negative strand, do reverse complementing.
				if(cur_chr_regions->at(i_reg)->strand == '-')
				{
					// Replace the sequence buffer with its reverse complement.
					char* reverse_complement_seq = get_reverse_complement(seq_buffer, 0, t_string::string_length(seq_buffer) - 1);
					delete [] seq_buffer;
					seq_buffer = reverse_complement_seq;
				}

				//fprintf(stderr, "%s\t%d\t%d\t.\t.\t%c\t%s\n", cur_chr_regions->at(i_reg)->chrom, 
				//	cur_chr_regions->at(i_reg)->start, cur_chr_regions->at(i_reg)->end, 
				//	cur_chr_regions->at(i_reg)->strand, seq_buffer);
			
				// Save the sequence to data entry of region.
				cur_chr_regions->at(i_reg)->data = (void*)seq_buffer;
			} // i_reg.

			fprintf(stderr, "\n");

			fclose(f_chr);
		}
		else
		{
			fprintf(stderr, "Could not find %s\n", chr_seq_fp);
			for(int i_reg = 0; i_reg < (int)cur_chr_regions->size(); i_reg++)
			{
				cur_chr_regions->at(i_reg)->data = NULL;
			} // i_reg loop.
		}
	} // i_chr loop.
}

// Assembly:
subq $0x4b8, %rsp            # imm = 0x4B8
movq %rdi, 0x4b0(%rsp)
movq %rsi, 0x4a8(%rsp)
movq 0x4a8(%rsp), %rdi
callq 0x2a910
movq %rax, 0x4a0(%rsp)
movl $0x0, 0x49c(%rsp)
movl 0x49c(%rsp), %eax
movl %eax, 0x58(%rsp)
movq 0x4a0(%rsp), %rdi
callq 0xc220
movq %rax, %rcx
movl 0x58(%rsp), %eax
cmpl %ecx, %eax
jge 0x3ddb9
movq 0x4a8(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x4a0(%rsp), %rdi
movslq 0x49c(%rsp), %rsi
callq 0xc240
movq 0x38(%rsp), %rdi
movq (%rax), %rsi
callq 0x2e1e0
movq %rax, 0x490(%rsp)
movq 0x275e4(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x4a0(%rsp), %rdi
movslq 0x49c(%rsp), %rsi
callq 0xc240
movq 0x40(%rsp), %rdi
movq (%rax), %rdx
leaq 0x18cdb(%rip), %rsi     # 0x56703
movb $0x0, %al
callq 0x2250
movq 0x490(%rsp), %rdi
callq 0xc7d0
movq %rax, 0x488(%rsp)
movq 0x490(%rsp), %rdi
callq 0xc760
movq %rax, 0x480(%rsp)
movq 0x488(%rsp), %rdi
movq 0x480(%rsp), %rsi
leaq -0x136d0(%rip), %rdx    # 0x2a3a0
callq 0x31d00
leaq 0x90(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x4b0(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x4a0(%rsp), %rdi
movslq 0x49c(%rsp), %rsi
callq 0xc240
movq 0x48(%rsp), %rdi
movq 0x50(%rsp), %rdx
movq (%rax), %rcx
leaq 0x154d7(%rip), %rsi     # 0x52f8f
movb $0x0, %al
callq 0x2090
leaq 0x90(%rsp), %rdi
callq 0x455a0
testb $0x1, %al
jne 0x3dad5
jmp 0x3dd2d
leaq 0x90(%rsp), %rdi
leaq 0x1881c(%rip), %rsi     # 0x56300
callq 0x455f0
movq %rax, 0x88(%rsp)
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x490(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0x3dd06
movq 0x274b6(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x20(%rsp)
movl 0x84(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x490(%rsp), %rdi
callq 0xc680
movq 0x20(%rsp), %rdi
movl 0x2c(%rsp), %edx
movq %rax, %rcx
leaq 0x18bc2(%rip), %rsi     # 0x5671f
movb $0x0, %al
callq 0x2250
movq 0x490(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0x20(%rax), %eax
movl %eax, 0x30(%rsp)
movq 0x490(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0xc800
movq %rax, %rcx
movl 0x30(%rsp), %eax
movq (%rcx), %rcx
subl 0xc(%rcx), %eax
addl $0x1, %eax
movl %eax, 0x80(%rsp)
movq 0x490(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movl 0xc(%rax), %eax
subl $0x1, %eax
cltq
addq $0x4, %rax
movl %eax, 0x7c(%rsp)
movl 0x7c(%rsp), %eax
addl 0x80(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x78(%rsp)
movl 0x78(%rsp), %eax
subl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
movl 0x74(%rsp), %eax
addl $0x2, %eax
movslq %eax, %rdi
callq 0x2040
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rdi
movl 0x74(%rsp), %eax
addl $0x1, %eax
movslq %eax, %rdx
shlq $0x0, %rdx
xorl %esi, %esi
callq 0x2110
movq 0x88(%rsp), %rdi
movslq 0x7c(%rsp), %rsi
xorl %edx, %edx
callq 0x21b0
movq 0x68(%rsp), %rdi
movslq 0x74(%rsp), %rsi
movq 0x88(%rsp), %rcx
movl $0x1, %edx
callq 0x2270
movq 0x490(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movsbl 0x8(%rax), %eax
cmpl $0x2d, %eax
jne 0x3dcc5
movq 0x68(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x68(%rsp), %rdi
callq 0x47640
movq 0x10(%rsp), %rdi
movl %eax, %edx
subl $0x1, %edx
xorl %esi, %esi
callq 0x3d720
movq %rax, 0x60(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x3dcbb
movq 0x18(%rsp), %rdi
callq 0x2220
movq 0x60(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x490(%rsp), %rdi
movslq 0x84(%rsp), %rsi
callq 0xc800
movq 0x8(%rsp), %rcx
movq (%rax), %rax
movq %rcx, 0x48(%rax)
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x3dafc
movq 0x272d3(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
leaq 0x146b7(%rip), %rsi     # 0x523ce
movb $0x0, %al
callq 0x2250
movq 0x88(%rsp), %rdi
callq 0x2180
jmp 0x3dda1
movq 0x272ac(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
leaq 0x90(%rsp), %rdx
leaq 0x1636d(%rip), %rsi     # 0x540b3
movb $0x0, %al
callq 0x2250
movl $0x0, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
movl %eax, 0x4(%rsp)
movq 0x490(%rsp), %rdi
callq 0xc680
movq %rax, %rcx
movl 0x4(%rsp), %eax
cmpl %ecx, %eax
jge 0x3dd9f
movq 0x490(%rsp), %rdi
movslq 0x5c(%rsp), %rsi
callq 0xc800
movq (%rax), %rax
movq $0x0, 0x48(%rax)
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x3dd55
jmp 0x3dda1
jmp 0x3dda3
movl 0x49c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x49c(%rsp)
jmp 0x3d997
addq $0x4b8, %rsp            # imm = 0x4B8
retq
nopw %cs:(%rax,%rax)