#ifndef __STRINGUTIL_H
#define __STRINGUTIL_H

// Includes
#include <string>
#include <sstream>
#include <iostream>
// heh
#define LOWER( c )		( (c) >= 'A' && (c) <= 'Z' ? (c)+'a'-'A' : (c) )
#define UPPER( c )		( (c) >= 'a' && (c) <= 'z' ? (c)+'A'-'a' : (c) )

//////////////////////////////////
// Conversion for unknown types //
//////////////////////////////////
template <typename T>
inline std::string to_str (T a_T) {
  std::ostringstream buffer;
  buffer << a_T;
  return buffer.str();
}

/////////////////////////
// Insertion operators //
/////////////////////////
inline std::string &operator<< (std::string &dest, const char c) {
  dest += c;
  return dest;
}

inline std::string &operator<< (std::string &dest, const char *src) {
  dest.append(src);
  return dest;
}

inline std::string &operator<< (std::string &dest, const std::string &src) {
  dest.append(src);
  return dest;
}

inline std::string &operator<< (std::string &dest, int insertion) {
  dest.append(to_str(insertion));
  return dest;
}

inline std::string &operator<< (std::string &dest, unsigned int insertion) {
  dest.append(to_str(insertion));
  return dest;
}

////////////////////////////
// Uniform Tab Evaluation //
////////////////////////////
inline std::string string_eval_tabs (const int maxlength, const int length) {
  std::string tabs(1, '\t');
  return tabs;
}

// Case insensitive string comparison
int	strcasecmp	(const char *str1, const char *str2);
int	strncasecmp	(const char *str1, const char *str2, unsigned int len);
 
inline int strcasecmp (const std::string &str1, const std::string &str2) {
    return strcasecmp(str1.c_str(), str2.c_str());
}

inline int strncasecmp (const std::string &str1, const std::string &str2, unsigned int len) {
	return strncasecmp(str1.c_str(), str2.c_str(), len);
}

// Case Insensitive string compares, false on unequal, true on if they equal
// g++ was spitting an error about the first one being a reference, so I just made it a plain std::string instead of a reference; g++ (gcc) 3.3.2 20030812 (Debian prerelease)
bool str_cmp( std::string string1, std::string string2 );
bool str_cmp( std::string &string1, char * string2 );
bool str_cmp( char * string1, std::string &string2 );
bool str_cmp( char * string1, char * string2 );

// case insensitive string prefix compares, true if it's prefixed in there. ;)
bool str_prefix( std::string &string1, std::string &string2 );
bool str_prefix( std::string &string1, char * string2 );
bool str_prefix( char * string1, std::string &string2 );
bool str_prefix( char * string1, char * string2 );

bool str_str( char * string1, char * string2 );
bool str_str( std::string string1, std::string string2 );

// normal string dealing functions
char * str_dup( const char *str );

#endif // UFX_STRINGUTIL_H