// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x418, %rsp            # imm = 0x418
movq %rdi, 0x18(%rsp)
movq %rsi, 0x20(%rsp)
movq %rsi, %rdi
callq 0x137a1
movq %rax, %r14
movq 0x17b9d(%rip), %r15     # 0x34fe0
leaq 0x30(%rsp), %r12
xorl %r13d, %r13d
movq %rax, 0x10(%rsp)
movq 0x8(%r14), %rax
subq (%r14), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %r13
jge 0x1d67f
movq %r14, %rdi
movq %r13, %rsi
callq 0x7342
movq (%rax), %rsi
movq 0x20(%rsp), %rdi
callq 0x15b31
movq %rax, %rbp
movq (%r15), %rbx
movq %r14, %rdi
movq %r13, %rsi
callq 0x7342
movq (%rax), %rdx
movq %rbx, %rdi
leaq 0xae66(%rip), %rsi      # 0x28302
xorl %eax, %eax
callq 0x2240
movq (%rbp), %rdi
movq 0x8(%rbp), %rsi
leaq -0xa01b(%rip), %rdx     # 0x13497
callq 0x17bcf
movq %r14, %rdi
movq %r13, 0x28(%rsp)
movq %r13, %rsi
callq 0x7342
movq (%rax), %rcx
movq %r12, %rdi
leaq 0x7abf(%rip), %rsi      # 0x24f93
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0x2080
movq %r12, %rdi
callq 0x20257
testb %al, %al
je 0x1d63e
movq %r12, %rdi
leaq 0xaa36(%rip), %rsi      # 0x27f30
callq 0x2027c
movq %rax, %r14
xorl %r12d, %r12d
movq 0x8(%rbp), %rcx
subq (%rbp), %rcx
movq %rcx, %rax
shrq $0x3, %rax
cltq
cmpq %rax, %r12
jge 0x1d614
sarq $0x3, %rcx
movq (%r15), %rdi
leaq 0xadf1(%rip), %rsi      # 0x2831e
movl %r12d, %edx
xorl %eax, %eax
callq 0x2240
movq %rbp, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0x20(%rax), %r15
movq %rbp, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
movslq 0xc(%rax), %rax
subq %rax, %r15
movq %rbp, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
movl 0xc(%rax), %r13d
addl $0x3, %r13d
leal 0x1(%r15), %eax
movl %eax, 0xc(%rsp)
movq %r15, %rdi
addq $0x3, %rdi
callq 0x2040
movq %rax, %rbx
leal 0x2(%r15), %eax
movslq %eax, %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x20f0
movslq %r13d, %rsi
movq %r14, %rdi
xorl %edx, %edx
callq 0x2190
movslq 0xc(%rsp), %rsi
movq %rbx, %rdi
pushq $0x1
popq %rdx
movq %r14, %rcx
callq 0x2250
movq %rbp, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
cmpb $0x2d, 0x8(%rax)
jne 0x1d5f3
movq %rbx, %rdi
callq 0x20d90
leal -0x1(%rax), %edx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1d36d
movq %rax, %r15
movq %rbx, %rdi
callq 0x2210
movq %r15, %rbx
movq %rbp, %rdi
movq %r12, %rsi
callq 0x7404
movq (%rax), %rax
movq %rbx, 0x48(%rax)
incq %r12
movq 0x179d1(%rip), %r15     # 0x34fe0
jmp 0x1d505
movq (%r15), %rsi
pushq $0xa
popq %rdi
callq 0x2200
movq %r14, %rdi
callq 0x2160
movq 0x10(%rsp), %r14
leaq 0x30(%rsp), %r12
movq 0x28(%rsp), %r13
incq %r13
jmp 0x1d450
movq (%r15), %rdi
leaq 0x88ef(%rip), %rsi      # 0x25f37
movq %r12, %rdx
xorl %eax, %eax
callq 0x2240
xorl %ebx, %ebx
movq 0x8(%rbp), %rax
subq (%rbp), %rax
shrq $0x3, %rax
cltq
cmpq %rax, %rbx
jge 0x1d631
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x7404
movq (%rax), %rax
andq $0x0, 0x48(%rax)
incq %rbx
jmp 0x1d654
addq $0x418, %rsp            # imm = 0x418
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq