/*
 * PEAK-SEQ -- PREPROCESSING
 * Paper by Joel Rozowsky, et. al.
 * Coded in C by Theodore Gibson.
 * This module deals with input/output concerns.
*/


#include <stdio.h>
#include <string.h>
#include "io.h"
#include "util.h"


//-------------------------------------------------
// PRIVATE FUNCTION PROTOTYPE
//-------------------------------------------------
String toString( const int num );


//-------------------------------------------------
// PUBLIC FUNCTIONS
//-------------------------------------------------
/*
 * This function converts the string from chr1 to chrM to an
 * integer that represents which chromosome it is on.
 * The X chromosome is stored as chromosome 23, Y as 24, and M as 25.
 * If there is a letter other than X, Y, or M, -1 is outputted, denoting failure.
 * cname: the string representation of the chromosome in the format chr#.
 * Outputs the chromosome number.
*/
int getCnum( const String cname )
{
	// These local varaibles are used for temporary storage.
	char chr[3];
	int cnum = 0;

	// Remove the "chr" prefix from the string.
	int ret = sscanf( cname, "chr%2[^.]", chr );

	// If this function fails, return -1, indicating failure.
	if( ret != 1 ) return -1;

	// If the value in the chr string is a decimal number,
	// return the number.
	ret = sscanf(chr, "%d", &cnum);
	if( ret == 1 ) return cnum;

	// Otherwise get the character and return its numerical representation.
	char ch = '\0';
	sscanf(chr, "%c", &ch);
	switch( ch )
	{
		case 'X':
			return 23;
		case 'Y':
			return 24;
		case 'M':
			return 25;
		default:
			return -1;
	}
}

/*
 * This function converts a chromosome number to the string chr1 to chrM.
 * If the number is greater than 25, this function returns a NULL pointer,
 * denoting failure.
 * cnum: the number of this chromosome.
 * Outputs the string corresponding to this chromosome.
*/
String getCname( const int cnum )
{
	// Initialize the String.
	String cname = safe_malloc( 6 * sizeof(char) );
	strcpy( cname, "chr" );

	// If this chromosome is represented by a number,
	// conver the number to its String representation
	// and add it to the end of the chr string.
	if( cnum <= 22 )
	{
		String str = toString( cnum );
		strcat( cname, str );
		free( str );
		return cname;
	}

	// Otherwise this is a "character" chromosome.
	switch( cnum )
	{
		case 23:
			strcat( cname, "X" );
			return cname;
		case 24:
			strcat( cname, "Y" );
			return cname;
		case 25:
			strcat( cname, "M" );
			return cname;
		default:
			free( cname );
			return NULL;
	}
}

/*
 * This function moves to the end of the current line before moving to
 * the next line in the file.
 * in: the file being read.
*/
void getNewline( FILE* in )
{
	char buf[40];

	// Get the rest of the line and its terminating '\n' character.
	while( fscanf( in, "%39[^\n]", buf) == 1);
	char ch = fgetc( in );

	// If the end of the file has been reached, put the EOF character
	// back so that it can be read by the loop comparison.
	// Otherwise, a segmentation fault might occur.
	if( ch == EOF) ungetc( ch, in );
}


//-------------------------------------------------
// PRIVATE FUNCTION
//-------------------------------------------------
/*
 * This function converts an integer between 1 and 22
 * (the chromosome numbers) to a string containing these digits.
*/
String toString( const int num )
{
	// Check that the number is in the correct range.
	if( (num < 1) || (num > 22) ) return NULL;

	// Allocate memory for and initialize the string.
	String str = safe_malloc( 3 * sizeof(char) );
	for(int i = 0; i < 3; i++)
		str[i] = '\0';

	// If this is a single digit number, it is only
	// necessary to store one character in the string.
	if( num < 10 )
		str[0] = num + '0';

	// Otherwise, store the tens and ones digit in
	// separate fields.
	else
	{
		// The tens digit.
		str[0] = (num/10) + '0';
		// The ones digit.
		str[1] = (num % ((num/10) * 10)) + '0';
	}

	// Return the string
	return str;
}
