// File: /workspace/github_cpp_makefile_star2_O2/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 0x7de6(%rip), %rsi      # 0x24f93
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rdx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2080
leaq 0xad67(%rip), %rsi      # 0x27f30
movq %r14, %rdi
callq 0x21b0
testq %rax, %rax
jne 0x1d20a
leaq 0x7db6(%rip), %rsi      # 0x24f93
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rdx
movq %r13, %rcx
xorl %eax, %eax
callq 0x2080
leaq 0xad37(%rip), %rsi      # 0x27f30
movq %r14, %rdi
callq 0x21b0
testq %rax, %rax
je 0x1d34d
movq %rax, %r14
leaq 0xc(%rsp), %rdi
andl $0x0, (%rdi)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %rax, %rcx
callq 0x2250
leal 0x3(%r12), %r13d
leal 0x3(%r15), %eax
cmpl %eax, %r13d
jge 0x1d280
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 0x2190
pushq $0x1
popq %rsi
movq %r15, %rdi
movq %r12, %rdx
movq %r14, %rcx
callq 0x2250
leaq (%r15,%rbx), %rax
incq %rax
jmp 0x1d2f5
pushq $0x2
popq %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x2190
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
pushq $0x1
popq %rsi
movq %r15, %rdi
movq %rbx, %rdx
movq %r14, %rcx
callq 0x2250
movq %r15, %rax
addq %rbx, %rax
movb $0x0, (%rax)
cmpb $0x2d, %bpl
jne 0x1d321
movq %r15, %rdi
callq 0x20d90
leal -0x1(%rax), %edx
movq %r15, %rdi
xorl %esi, %esi
callq 0x1d36d
movq %rax, %rbx
movq %r15, %rdi
callq 0x2210
movq %rbx, %r15
movq %r14, %rdi
callq 0x2160
cmpb $0x0, 0x8(%rsp)
je 0x1d338
movq %r15, %rdi
callq 0x22b94
movq %r15, %rax
addq $0x3f8, %rsp            # imm = 0x3F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x17c8c(%rip), %rax     # 0x34fe0
movq (%rax), %rdi
leaq 0xafd7(%rip), %rsi      # 0x28335
xorl %r15d, %r15d
movq %r13, %rdx
xorl %eax, %eax
callq 0x2240
jmp 0x1d338