// File: /workspace/github_cpp_makefile_star2_O3/gersteinlab[P]MUSIC/src/ms_genome_sequence_tools.cpp
// Function: extract_sequence(char*, char*, int, int, char, bool)
char* extract_sequence(char* chr_data_dir, char* raw_chr_name, int start, int end, char strand, bool upper_case)
{
	char chr_seq_fp[1000];
	sprintf(chr_seq_fp, "%s/%s.bin", chr_data_dir, raw_chr_name);
	FILE* f_chr = fopen(chr_seq_fp, "rb");

	if(f_chr == NULL)
	{
		// Try to fix the chromosome file path: Add 'chr' to beginning.
		sprintf(chr_seq_fp, "%s/%s.bin", chr_data_dir, raw_chr_name);
		f_chr = fopen(chr_seq_fp, "rb");

		if(f_chr == NULL)
		{
			fprintf(stderr, "Could not identify the conforming chromosome name from id %s, returning NULL.\n", raw_chr_name);
			return(NULL);
		}
	}

	// Read the binary sequence length.
	int l_bin_seq = 0;
	fread(&l_bin_seq, sizeof(int), 1, f_chr);

	int f_start = start - 1 + sizeof(int);
	//int f_end = end - 1;
	int f_end = f_start + (end-start);

	char* seq_buffer = NULL;

	if(f_start < f_end)
	{
		int length = (end - start + 1);

		seq_buffer = new char[length + 2];
		memset(seq_buffer, 0, sizeof(char) * (length + 1));

		// Go to the starting position.
		fseek(f_chr, f_start, SEEK_SET);

		// Fill the buffer.
		fread(seq_buffer, sizeof(char), length, f_chr);

		seq_buffer[length] = 0;
	} // start, end coparison.
	else
	{
		// Get the file size.
		fseek (f_chr, 0 , SEEK_END);
		int length = (int)(ftell(f_chr));
		
		seq_buffer = new char[length+2]; 
		memset(seq_buffer, 0, sizeof(char) * (length + 1));

		rewind(f_chr);

		fread(seq_buffer, sizeof(char), length, f_chr);

		seq_buffer[length] = 0;
	} // whole chromosome reading check.

	// If the requested strand is on negative strand, do reverse complementing.
	if(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;
	}

	fclose(f_chr);

	if(upper_case)
	{
		t_string::to_upper(seq_buffer);
	}

	return(seq_buffer);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3f8, %rsp            # imm = 0x3F8
movl %r9d, 0x8(%rsp)
movl %r8d, %ebp
movl %ecx, %r15d
movl %edx, %r12d
movq %rsi, %r13
movq %rdi, %rbx
leaq 0x8aff(%rip), %rsi      # 0x2af93
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rdx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2080
leaq 0xba80(%rip), %rsi      # 0x2df30
movq %r14, %rdi
callq 0x21c0
testq %rax, %rax
jne 0x224f1
leaq 0x8acf(%rip), %rsi      # 0x2af93
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rdx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2080
leaq 0xba50(%rip), %rsi      # 0x2df30
movq %r14, %rdi
callq 0x21c0
testq %rax, %rax
je 0x22641
movq %rax, %r14
leaq 0xc(%rsp), %rdi
movl $0x0, (%rdi)
movl $0x4, %esi
movl $0x1, %edx
movq %rax, %rcx
callq 0x2260
leal 0x3(%r12), %r13d
leal 0x3(%r15), %eax
cmpl %eax, %r13d
jge 0x22570
subl %r12d, %r15d
movslq %r15d, %rbx
leaq 0x1(%rbx), %r12
leal 0x3(%rbx), %eax
movslq %eax, %rdi
callq 0x2040
movq %rax, %r15
leal 0x2(%rbx), %eax
movslq %eax, %rdx
movq %r15, %rdi
xorl %esi, %esi
callq 0x20f0
movslq %r13d, %rsi
movq %r14, %rdi
xorl %edx, %edx
callq 0x21a0
movl $0x1, %esi
movq %r15, %rdi
movq %r12, %rdx
movq %r14, %rcx
callq 0x2260
leaq (%r15,%rbx), %rax
incq %rax
jmp 0x225e9
movq %r14, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x21a0
movq %r14, %rdi
callq 0x2030
movq %rax, %rbx
movq %rax, %r12
shlq $0x20, %r12
movabsq $0x200000000, %rdi      # imm = 0x200000000
addq %r12, %rdi
sarq $0x20, %rdi
callq 0x2040
movq %rax, %r15
movabsq $0x100000000, %rdx      # imm = 0x100000000
addq %r12, %rdx
sarq $0x20, %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x20f0
movq %r14, %rdi
callq 0x2060
movslq %ebx, %rbx
movl $0x1, %esi
movq %r15, %rdi
movq %rbx, %rdx
movq %r14, %rcx
callq 0x2260
movq %r15, %rax
addq %rbx, %rax
movb $0x0, (%rax)
cmpb $0x2d, %bpl
jne 0x22615
movq %r15, %rdi
callq 0x26856
leal -0x1(%rax), %edx
movq %r15, %rdi
xorl %esi, %esi
callq 0x22661
movq %rax, %rbx
movq %r15, %rdi
callq 0x2220
movq %rbx, %r15
movq %r14, %rdi
callq 0x2170
cmpb $0x0, 0x8(%rsp)
je 0x2262c
movq %r15, %rdi
callq 0x291da
movq %r15, %rax
addq $0x3f8, %rsp            # imm = 0x3F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x16998(%rip), %rax     # 0x38fe0
movq (%rax), %rdi
leaq 0xbce3(%rip), %rsi      # 0x2e335
xorl %r15d, %r15d
movq %r13, %rdx
xorl %eax, %eax
callq 0x2250
jmp 0x2262c