/*
 * Jakelib2 - General purpose C++ library
 * Copyright (C) 2001 Florian Wolff  (florian@donuz.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: StringTokenizer.h,v 1.5 2002/06/08 10:09:42 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_UTIL_STRINGTOKENIZER_H
# define INCLUDE_JAKELIB2_UTIL_STRINGTOKENIZER_H
#include "Iterator.h"

namespace jakelib {
  namespace util {

    /**
     * @brief This class splits a string into tokens. The caller can set on which 
     * delimiters the string should be split and if the delimiters should be
     * returned.
     *
     * You may change the delimiter set on the fly by calling
     * \c nextToken(String). But the semantic is quite difficult; it even
     * depends on calling \c hasMoreTokens(). You should call
     * \c hasMoreTokens() before, otherwise the old delimiters
     * after the last token are returned.
     *
     * If you want to get the delimiters, you have to use the three argument
     * constructor. The delimiters are returned as token consisting of a
     * single character.  
     *
     * @class StringTokenizer
     * @version $Id: StringTokenizer.h,v 1.5 2002/06/08 10:09:42 florian Exp $
     * @author Jochen Hoenicke
     * @author Warren Levy <warrenl@cygnus.com>
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class StringTokenizer : public jakelib::lang::Object, Iterator
      {
      private:
	/** @brief The position in the str, where we currently are. */
	int pos;

	/** @brief The string that should be split into tokens. */
	jakelib::lang::String* str;

	/** @brief The string containing the delimiter characters. */
	jakelib::lang::String* delim;

	/** @brief Tells, if we should return the delimiters. */
	jboolean retDelims;

      public:

	/**
	 * @brief Creates a new StringTokenizer for the string <code>str</code>,
	 * that should split on the default delimiter set (space, tap,
	 * newline, return and formfeed), and which doesn't return the
	 * delimiters.
	 * @param str The string to split.
	 */
	StringTokenizer(jakelib::lang::String* str);

	/**
	 * @brief Create a new StringTokenizer, that splits the given string on
	 * the given delimiter characters.  If you set
	 * <code>returnDelims</code> to <code>true</code>, the delimiter
	 * characters are returned as tokens of their own.  The delimiter
	 * tokens always consist of a single character.
	 *
	 * @param str The string to split.
	 * @param delim A string containing all delimiter characters.
	 * @param returnDelims Tells, if you want to get the delimiters.
	 */
	StringTokenizer(jakelib::lang::String* str, jakelib::lang::String* delim, jboolean returnDelims = false);

	/**
	 * @brief Tells if there are more tokens.
	 * @return True, if the next call of nextToken() succeeds, false otherwise.
	 */
	virtual jboolean hasMoreTokens();

	/**
	 * @brief Returns the nextToken, changing the delimiter set to the given
	 * <code>delim</code>.  The change of the delimiter set is
	 * permanent, ie. the next call of nextToken(), uses the same
	 * delimiter set.
	 *
	 * @param delim a string containing the new delimiter characters.
	 * @return the next token with respect to the new delimiter characters.
	 * @exception NoSuchElementException if there are no more tokens.
	 */
	virtual jakelib::lang::String* nextToken(jakelib::lang::String* delim);

	/**
	 * @brief Returns the nextToken of the string.
	 *
	 * @return the next token with respect to the new delimiter characters.
	 * @exception NoSuchElementException if there are no more tokens.
	 */
	virtual jakelib::lang::String* nextToken();

	/**
	 * @brief This does the same as \c hasMoreTokens. This is the
	 * <code>Iterator</code interface method.
	 *
	 * @return \c true, if the next call of \c nextElement() succeeds, \c false
	 * otherwise.  
	 */
	jboolean hasNext();

	/**
	 * @brief This does the same as \c nextTokens. This is the
	 * \c Iterator interface method.
	 *
	 * @return the next token with respect to the new delimiter characters.
	 * @exception NoSuchElementException if there are no more tokens.
	 * @see #nextToken
	 */
	jakelib::lang::Object* next();

	/**
	 * @brief This counts the number of remaining tokens in the string, with
	 * respect to the current delimiter set.
	 *
	 * @return the number of times <code>nextTokens()</code> will
	 * succeed.  
	 * @see #nextToken
	 */
	virtual int countTokens();

	/**
	 * @throws UnsupportedOperationException Always
	 */
	void remove();

	JAKELIB_DECLARE_CLASS(StringTokenizer);
      };

  }
}
#endif

