#include "stringutil.h"
#include <iostream>
#include <string>

/////////////////////////
//I NEED TO MAKE SURE THESE WORK ALL CORRECTLY
//MULTI-LENGTHED STRINGS ON ALL OF THEM

char			str_empty	[1];

///////////////////////////////////////
 // String Compare (case insensitive) //
 ///////////////////////////////////////
 int strcasecmp (const char *str1, const char *str2) {
 	for (; ((tolower(*str1) - tolower(*str2)) == 0); ++str1, ++str2) {
		if (*str1 == '\0' || *str2 == '\0')
		return 0;
	}

 	return (tolower(*str1) - tolower(*str2));
 }
 
 int strncasecmp (const char *str1, const char *str2, unsigned int len) {
 	for (; ((tolower(*str1) - tolower(*str2)) == 0); ++str1, ++str2) {
 		if (*str1 == '\0' || *str2 == '\0')
			return 0;
 
 		if (--len == 0) break;
 	}
 
 	return (tolower(*str1) - tolower(*str2));
}

///// These functions handle string comparing. They're all case
///// insensitive. 
///////////////////////////////////////////////////////////////
bool str_cmp( std::string string1, std::string string2 ) {
	std::string::iterator cChar, cChar2;	

    if ( string1.empty() )
	    return false;

    if ( string2.empty() )
		return false;

	for ( cChar = string1.begin(), cChar2 = string2.begin(); cChar != string1.end() || cChar2 != string2.end(); cChar++, cChar2++ ) {
		if ( LOWER( (*cChar) ) != LOWER( (*cChar2) ) )
			return false;
	}

	return true;
}

bool str_cmp( std::string &string1, char * string2 ) {
	std::string::iterator cChar;

	if ( string1.empty() )
		return false;

	if ( string2 == NULL )
		return false;

	for ( cChar = string1.begin(); cChar != string1.end() || *string2; ++cChar, string2++ ) {
		if ( LOWER( (*cChar) ) != LOWER( *string2 ) )
			return false;
	}

	return true;
}

bool str_cmp( char * string1, std::string &string2 ) {
	std::string::iterator cChar;

	if ( string1 == NULL )
		return false;

	if ( string2.empty() )
		return false;

	for ( cChar = string2.begin(); cChar != string2.end() || *string1; ++cChar, string1++ ) {
		if ( LOWER( (*string1) ) != LOWER( *cChar ) )
			return false;
	}

	return true;
}

bool str_cmp( char * string1, char * string2 ) {
	if ( string1 == NULL )
	   return false;

    if ( string2 == NULL )
	   return false;

    for ( ; *string1 || *string2; string1++, string2++ ) {
	   if ( LOWER(*string1) != LOWER(*string2) )
	      return false;
    }

    return true;
}

/// end str_cmp

///// These functions handle comparing the beginning of strings
///// (Prefix Matching) They're all case insensitive. 
///////////////////////////////////////////////////////////////
bool str_prefix( std::string &string1, std::string &string2 ) {
	std::string::iterator cChar, cChar2;

    if ( string1.empty() )
	   return false;

    if ( string2.empty() )
	   return false;

    for ( cChar = string1.begin(), cChar2 = string2.begin(); cChar != string1.end(); cChar++, cChar2++ ) {
		if ( LOWER( (*cChar) ) != LOWER( (*cChar2) ) )
			return false;
	}

    return true;
}

bool str_prefix( std::string &string1, char * string2 ) {
	std::string::iterator cChar;

	if ( string1.empty() )
		return false;

	if ( string2 == NULL )
		return false;

	for ( cChar = string1.begin(); cChar != string1.end(); ++cChar, string2++ ) {
		if ( LOWER( (*cChar) ) != LOWER( *string2 ) )
			return false;
	}

	return true;
}

bool str_prefix( char * string1, std::string &string2 ) {
	std::string::iterator cChar;

	if ( string1 == NULL ) 
		return false;

	if ( string2.empty() ) 
		return false;
	for ( cChar = string2.begin(); *string1; ++cChar, string1++ ) {
		if ( LOWER( (*string1) ) != LOWER( *cChar ) )
			return false;
	}

	return true;
}

bool str_prefix( char * string1, char * string2 ) {
	if ( string1 == NULL )
	   return false;

    if ( string2 == NULL )
	   return false;
 

    for ( ; *string1; string1++, string2++ ) {
	   if ( LOWER(*string1) != LOWER(*string2) )
	      return false;
    }

    return true;
}


//// lowerString :: This is a function to convert a string to lowerCase without altering the original
////////////////////////////////////////////
char * lowerString( const char * string1 ) {
    char * str_new;

	str_new = new char[ strlen( string1 ) + 1];	

	for ( unsigned int i = 0; i < ( strlen( string1 ) + 1 ); i++ ) {
	   str_new[i] = LOWER( string1[i] );
    } 
	
	return str_new;
}

//// upperString :: This is a function to convert a string to upperCase without altering the original
////////////////////////////////////////////
char * upperString( const char * string1 ) {
    char * str_new;

	str_new = new char[ strlen( string1 ) + 1];	

	for ( unsigned int i = 0; i < ( strlen( string1 ) + 1 ); i++ ) {
	   str_new[i] = UPPER( string1[i] );
    } 
	
	return str_new;
}

///// Similar to strstr, yet is case insensitive 
///////////////////////////////////////////////////////////////
bool str_str( char * string1, char * string2 ) {
    if ( string1 == NULL ) 
	   return false;

    if ( string2 == NULL )
	   return false;


    if ( strstr( lowerString( string1 ), lowerString( string2 ) ) == NULL )
		return false;
   

    return true;
}

bool str_str( std::string string1, std::string string2 ) {
    if ( string1.empty() ) 
	   return false;

    if ( string2.empty() )
	   return false;


    if ( strstr( lowerString( string1.c_str() ), lowerString( string2.c_str() ) ) == NULL )
		return false;
   

    return true;
}



//// str_dup :: Allocates memory for a pointer and puts a string in it
////////////////////////////////////////////
char * str_dup( const char *str ) {
    char * str_new;

    if ( str[0] == '\0' )
	return &str_empty[0];

    str_new = new char[ strlen(str) + 1 ];
    strcpy( str_new, str );
    return str_new;
}

//// free_string :: Frees the memory in a pointer. ( usually goes along with str_dup )
////////////////////////////////////////////
void free_string( char *pstring ) {
    if ( pstring == NULL || pstring == &str_empty[0] )
	return;

    delete pstring;
    return;
}