#ifndef __STRING_TOKENIZER__HPP
#define __STRING_TOKENIZER__HPP

/******************************************************************************
 *
 * Author      : Mario Konrad, Mario.Konrad@gmx.net
 *
 * Copyright (C) Mario Konrad
 *
 ******************************************************************************
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 ******************************************************************************/

#include <string>

namespace utils {

/**
 * This class reads tokens from a string. The separation
 * of the tokens is customizable. Default is whitespace
 * (space, newline, tab).
 */
class string_tokenizer
{
	private:
		/**
		 * The string to parse.
		 */
		std::string str;

		/**
		 * The delemitters.
		 */
		std::string delm;

		/**
		 * The current position within the string.
		 */
		size_t pos;

		/**
		 * The length of the string to parse.
		 */
		size_t len;

		/**
		 * The current token.
		 */
		std::string tok;

		/**
		 * Automatic advancing.
		 */
		bool automatic;
	public:

		/**
		 * This constructor initializes the object with
		 * the string to parse and the delemitter of the tokens.
		 *
		 * @param STR The string to parse.
		 * @param DELM The delemitters. Each of them works as
		 *  delemitter. It is <b>not</b> possible to define
		 *  delemitters more than one character.
		 */
		string_tokenizer::string_tokenizer(const std::string & str, bool automatic, const std::string & delm)
			: str(str)
			  , delm(delm)
			  , pos(0)
			  , tok("")
			  , automatic(automatic)
		{
			len = str.length();
			next();
		}

		/**
		 * Destructor.
		 */
		string_tokenizer::~string_tokenizer()
		{}

		/**
		 * This method checks if there are tokens left.
		 *
		 * @return <tt>true</tt> if there are tokens left, <tt>false</tt>
		 *  if there aren't.
		 */
		bool string_tokenizer::hasMoreTokens()
		{
			return (pos <= len && pos >= 0);
		}

		/**
		 * Advances to the next token.
		 */
		void string_tokenizer::next()
		{
			if (pos == (size_t)-1 || pos >= len) {
				tok = "";
				pos = (size_t)-1;
				return;
			}
			size_t i = str.find_first_of(delm, pos);
			if (i == (size_t)-1) {
				tok = str.substr(pos);
				pos = len;
			} else {
				tok = str.substr(pos, i-pos);
				pos = str.find_first_not_of(delm, i);
			}
		}

		/**
		 * Returns the current token.
		 * \return The current token.
		 */
		std::string string_tokenizer::token() const
		{
			std::string t = tok;
			if (automatic) next();
			return t;
		}

		/**
		 * This method resets the tokenizer. Use this method if you
		 * like to restart parsing the tokens.
		 */
		void string_tokenizer::reset()
		{
			pos = 0;
		}
};

}

#endif
