// File: gersteinlab[P]MUSIC/src/ms_annot_region_tools.cpp
// Function: load_BED(char*)
vector<t_annot_region*>* load_BED(char* bed_fp)
{
	vector<t_annot_region*>* bed_regions = new vector<t_annot_region*>();

	FILE* f_bed = open_f(bed_fp, "r");
	
	while(1)
	{
		char* cur_line = getline(f_bed);
		if(cur_line == NULL)
		{
			break;
		}

		bool skip_line = check_line_skip(cur_line);

		if(!skip_line)
		{
			// Read the mandatory fields.
			int i_cur_char = 0;
			char strand_char = '+';
			char region_name[1000];
			strcpy(region_name, ".");
			int region_score = 0;

			char chrom[100];
			memset(chrom, 0, 100);
			if(!t_string::get_next_token(cur_line, chrom, 100, "\t", i_cur_char))
			{
				fprintf(stderr, "Could not read chromosome in %s\n", cur_line);
				exit(0);
			}
			

			int start = 0;
			char start_str[100];
			memset(start_str, 0, 100);
			if(!t_string::get_next_token(cur_line, start_str, 100, "\t", i_cur_char))
			{
				fprintf(stderr, "Could not read start in %s\n", cur_line);
				exit(0);
			}
			else
			{
				start = atoi(start_str);
			}

			int end = 0;
			char end_str[100];
			memset(end_str, 0, 100);
			if(!t_string::get_next_token(cur_line, end_str, 100, "\t", i_cur_char))
			{
				fprintf(stderr, "Could not read end in %s\n", cur_line);
				exit(0);
			}
			else
			{
				end = atoi(end_str);
			}

			
			// Keep on reading and load until line is finished.
			bool line_finished = false;
			char name_str[1000];
			memset(name_str, 0, 1000);
			if(!t_string::get_next_token(cur_line, name_str, 1000, "\t", i_cur_char))
			{
				// Could not get the next token.
				line_finished = true;
			}
			else
			{
				// Region name is already initialized to '.'.
				strcpy(region_name, name_str);
			}

			if(!line_finished)
			{
				char score_str[1000];
				memset(score_str, 0, 1000);
				if(!t_string::get_next_token(cur_line, score_str, 1000, "\t", i_cur_char))
				{
					line_finished = true;
				}
				else
				{
					//strcpy(region_score, score_str);
					region_score = atoi(score_str);
				}
			}

			if(!line_finished)
			{
				char strand_str[10];
				memset(strand_str, 0, 10);
				if(!t_string::get_next_token(cur_line, strand_str, 10, "\t", i_cur_char))
				{
					line_finished = true;
				}
				else
				{
					strand_char = strand_str[0];
				}
			}

			/*if(sscanf(cur_line, "%s %d %d", chrom, &start, &end) != 3)
			{
				printf("Could not read the mandatory fields from BED file line:\n%s\n", cur_line);
				exit(0);
			}*/

			//char strand = '+'; 
			//if(sscanf(cur_line, "%*s %*s %*s %*s %*s %c", &strand) != 1)
			//{
			//	// Could not read the strand from file, set it to '+' by default.
			//	strand = '+';
			//}

			//int region_score = 0;
			//if(sscanf(cur_line, "%*s %*s %*s %*s %d", &region_score) != 1)
			//{
			//	// Could not read the score from the file.
			//}

			//char region_name[1000];
			//if(sscanf(cur_line, "%*s %*s %*s %s", region_name) != 1)
			//{
			//	// Could not read the strand from file, set it to '+' by default.
			//	strcpy(region_name, ".");
			//}

			t_annot_region* new_region = new t_annot_region();

			// Translate the start and end of the BED coordinates to the codebase coordinates.
			//new_region->start = start - BED_START_BASE + CODEBASE_START_BASE;
			//new_region->end = end - BED_END_BASE + CODEBASE_END_BASE;
			new_region->start = translate_coord(start, BED_COORDS::start_base, CODEBASE_COORDS::start_base);
			new_region->end = translate_coord(end, BED_COORDS::end_base, CODEBASE_COORDS::end_base);
			new_region->chrom = t_string::copy_me_str(chrom);
			normalize_chr_id(new_region->chrom);
			new_region->name = new char[strlen(region_name) + 2];
			strcpy(new_region->name, region_name);
			new_region->strand = strand_char;
			new_region->data = NULL;
			new_region->score = region_score;
			new_region->sort_info = NULL;
		
			bed_regions->push_back(new_region);
		} // line skip check.

		delete [] cur_line;
	} // file reading loop.

	fclose(f_bed);

	//printf("Loaded %d regions from %s\n", bed_regions->size(), bed_fp);

	if(!validate_region_coords(bed_regions))
	{
		fprintf(stderr, "The coordinates are not valid for %s\n", bed_fp);
		exit(0);
	}

	return(bed_regions);
}

// Assembly:
subq $0xd78, %rsp            # imm = 0xD78
movq %rdi, 0xd70(%rsp)
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x10(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0x10(%rsp), %rdi
callq 0xc670
movq 0x10(%rsp), %rax
movq %rax, 0xd68(%rsp)
movq 0xd70(%rsp), %rdi
leaq 0x29b3b(%rip), %rsi     # 0x550ce
callq 0x455f0
movq %rax, 0xd60(%rsp)
movq 0xd60(%rsp), %rdi
callq 0x45400
movq %rax, 0xd58(%rsp)
cmpq $0x0, 0xd58(%rsp)
jne 0x2b5c5
jmp 0x2b9e3
movq 0xd58(%rsp), %rdi
callq 0x2b460
andb $0x1, %al
movb %al, 0xd57(%rsp)
testb $0x1, 0xd57(%rsp)
jne 0x2b9c3
movl $0x0, 0xd50(%rsp)
movb $0x2b, 0xd4f(%rsp)
leaq 0x960(%rsp), %rdi
leaq 0x29959(%rip), %rsi     # 0x54f64
callq 0x2160
movl $0x0, 0x95c(%rsp)
leaq 0x8f0(%rsp), %rdi
xorl %esi, %esi
movl $0x64, %edx
callq 0x2110
movq 0xd58(%rsp), %rdi
leaq 0x8f0(%rsp), %rsi
movl $0x64, %edx
leaq 0x2ab79(%rip), %rcx     # 0x561c4
leaq 0xd50(%rsp), %r8
callq 0x491d0
testb $0x1, %al
jne 0x2b683
movq 0x3997d(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
movq 0xd58(%rsp), %rdx
leaq 0x2a7fa(%rip), %rsi     # 0x55e6f
movb $0x0, %al
callq 0x2250
xorl %edi, %edi
callq 0x21f0
movl $0x0, 0x8ec(%rsp)
leaq 0x880(%rsp), %rdi
xorl %esi, %esi
movl $0x64, %edx
callq 0x2110
movq 0xd58(%rsp), %rdi
leaq 0x880(%rsp), %rsi
movl $0x64, %edx
leaq 0x2ab06(%rip), %rcx     # 0x561c4
leaq 0xd50(%rsp), %r8
callq 0x491d0
testb $0x1, %al
jne 0x2b6f6
movq 0x3990a(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
movq 0xd58(%rsp), %rdx
leaq 0x2a7a8(%rip), %rsi     # 0x55e90
movb $0x0, %al
callq 0x2250
xorl %edi, %edi
callq 0x21f0
leaq 0x880(%rsp), %rdi
callq 0x2290
movl %eax, 0x8ec(%rsp)
movl $0x0, 0x87c(%rsp)
leaq 0x810(%rsp), %rdi
xorl %esi, %esi
movl $0x64, %edx
callq 0x2110
movq 0xd58(%rsp), %rdi
leaq 0x810(%rsp), %rsi
movl $0x64, %edx
leaq 0x2aa7f(%rip), %rcx     # 0x561c4
leaq 0xd50(%rsp), %r8
callq 0x491d0
testb $0x1, %al
jne 0x2b77d
movq 0x39883(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
movq 0xd58(%rsp), %rdx
leaq 0x2a73d(%rip), %rsi     # 0x55eac
movb $0x0, %al
callq 0x2250
xorl %edi, %edi
callq 0x21f0
leaq 0x810(%rsp), %rdi
callq 0x2290
movl %eax, 0x87c(%rsp)
movb $0x0, 0x80f(%rsp)
leaq 0x420(%rsp), %rdi
xorl %esi, %esi
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x2110
movq 0xd58(%rsp), %rdi
leaq 0x420(%rsp), %rsi
movl $0x3e8, %edx            # imm = 0x3E8
leaq 0x2a9fb(%rip), %rcx     # 0x561c4
leaq 0xd50(%rsp), %r8
callq 0x491d0
testb $0x1, %al
jne 0x2b7e4
movb $0x1, 0x80f(%rsp)
jmp 0x2b7f9
leaq 0x960(%rsp), %rdi
leaq 0x420(%rsp), %rsi
callq 0x2160
testb $0x1, 0x80f(%rsp)
jne 0x2b85b
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x2110
movq 0xd58(%rsp), %rdi
leaq 0x30(%rsp), %rsi
movl $0x3e8, %edx            # imm = 0x3E8
leaq 0x2a997(%rip), %rcx     # 0x561c4
leaq 0xd50(%rsp), %r8
callq 0x491d0
testb $0x1, %al
jne 0x2b848
movb $0x1, 0x80f(%rsp)
jmp 0x2b859
leaq 0x30(%rsp), %rdi
callq 0x2290
movl %eax, 0x95c(%rsp)
jmp 0x2b85b
testb $0x1, 0x80f(%rsp)
jne 0x2b8b7
leaq 0x26(%rsp), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x2110
movq 0xd58(%rsp), %rdi
leaq 0x26(%rsp), %rsi
movl $0xa, %edx
leaq 0x2a935(%rip), %rcx     # 0x561c4
leaq 0xd50(%rsp), %r8
callq 0x491d0
testb $0x1, %al
jne 0x2b8aa
movb $0x1, 0x80f(%rsp)
jmp 0x2b8b5
movb 0x26(%rsp), %al
movb %al, 0xd4f(%rsp)
jmp 0x2b8b7
movl $0x50, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x8(%rsp)
xorl %esi, %esi
movl $0x50, %edx
callq 0x2110
movq 0x8(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0x8ec(%rsp), %edi
xorl %esi, %esi
movl $0x1, %edx
callq 0x1fd20
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0xc(%rax)
movl 0x87c(%rsp), %edi
movl $0x1, %edx
movl %edx, %esi
callq 0x1fd20
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x20(%rax)
leaq 0x8f0(%rsp), %rdi
callq 0x47b60
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, (%rax)
movq 0x18(%rsp), %rax
movq (%rax), %rdi
callq 0x22350
leaq 0x960(%rsp), %rdi
callq 0x20e0
movq %rax, %rdi
addq $0x2, %rdi
callq 0x2040
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x18(%rsp), %rax
movq 0x18(%rax), %rdi
leaq 0x960(%rsp), %rsi
callq 0x2160
movb 0xd4f(%rsp), %cl
movq 0x18(%rsp), %rax
movb %cl, 0x8(%rax)
movq 0x18(%rsp), %rax
movq $0x0, 0x48(%rax)
movl 0x95c(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x10(%rax)
movq 0x18(%rsp), %rax
movq $0x0, 0x38(%rax)
movq 0xd68(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0xc8c0
movq 0xd58(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x2b9de
movq (%rsp), %rdi
callq 0x2220
jmp 0x2b5a0
movq 0xd60(%rsp), %rdi
callq 0x2180
movq 0xd68(%rsp), %rdi
callq 0x2ba40
testb $0x1, %al
jne 0x2ba28
movq 0x395d8(%rip), %rax     # 0x64fe0
movq (%rax), %rdi
movq 0xd70(%rsp), %rdx
leaq 0x2a4ac(%rip), %rsi     # 0x55ec6
movb $0x0, %al
callq 0x2250
xorl %edi, %edi
callq 0x21f0
movq 0xd68(%rsp), %rax
addq $0xd78, %rsp            # imm = 0xD78
retq
nopl (%rax,%rax)