/*
 * Copyright (C) 2005 Mike Pultz. All rights reserved.         
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Library General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * Written by: Mike Pultz (mike@mrhost.ca)
 * 
 */
#ifndef __CSTRING_H__
#define __CSTRING_H__

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>

class cstring : public std::string
{
	public:
		cstring() : std::string() { }
		cstring(const std::string &_s, size_type _pos = 0, 
			size_type _n = std::string::npos) : std::string(_s, _pos, _n) { }
		cstring(const value_type *_s) : std::string(_s) { }
		cstring(const value_type *_s, size_type _n) : std::string(_s, _n) { }		
		cstring(size_type _n, value_type _c) : std::string(_n, _c) { }
		template <class InputIterator>
			cstring(InputIterator _first, InputIterator _last) : std::string(_first, _last) { }
		~cstring() { }

		void format(const char *_format, ...)
		{
			va_list ap;
			int size = 1;
			char *buffer = NULL;
		
			while(1)
			{
				if (buffer != NULL)
				{
					delete[] buffer;
				}

				buffer = new char[size+1];
				memset(buffer, '\0', size+1);

				va_start(ap, _format);
				int br = vsnprintf(buffer, size, _format, ap);
				va_end(ap);

				if (br > size)
				{
					size = br + 1;
				} else
				{
					break;
				}
			}

			assign(buffer);
			delete[] buffer;

			return;
		}
		void trim()
		{
			for(reverse_iterator i=rbegin(); i!=rend(); i++)
			{
				if ( (*i == '\n') || (*i == '\r') )
				{
					*i = '\0';
					resize(size() -1);
				} else
				{
					break;
				}
			}
		}
		int scanf(const char *_format, ...) const
		{
			va_list ap;
			va_start(ap, _format);

			int matches = ::vsscanf(c_str(), _format, ap);

			va_end(ap);

			return matches;
		}
		void toupper()
		{
			for (iterator i = begin(); i != end(); i++)
			{
				if (*i >= 'a' && *i <= 'z')
				{
					*i = (*i) - ('a' - 'A');
				}
			}
			
			return;
		}
		void tolower()
		{
			for (iterator i = begin(); i != end(); i++)
			{
				if (*i >= 'A' && *i <= 'Z')
				{
					*i = (*i) + ('a' - 'A');
				}
			}

			return;
		}
		bool is_lower() const
		{
			if (length() == 0)
			{
				return false;
			}
			for (const_iterator i = begin(); i != end(); i++)
			{
				if (*i < 'a' || *i < 'z')
				{
					return false;
				}
			}

			return true;
		}
		bool is_upper() const
		{
			if (length() == 0)
			{
				return false;
			}
			for (const_iterator i = begin(); i != end(); i++)
			{
				if (*i < 'A' || *i > 'Z')
				{
					return false;
				}
			}

			return true;
		}
		int to_int() const
		{
			if (length() == 0)
			{
				return -1;
			}

			int result;
			std::stringstream ss(c_str());
			std::istringstream iss(ss.str());
	
			iss >> result;

			return result;
		}
		int casecompare(const cstring &_s) const
		{
			cstring a(c_str());
			cstring b(_s);

			a.tolower();
			b.tolower();

			return a.compare(b);
		}
		int casecompare(const char *_s) const
		{
			cstring a(c_str());
			cstring b(_s);

			a.tolower();
			b.tolower();

			return a.compare(b);
		}
};

#endif //__CSTRING_H__
