/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef _DECAF_UTIL_STRINGTOKENIZER_H_
#define _DECAF_UTIL_STRINGTOKENIZER_H_

#include <decaf/util/Config.h>
#include <decaf/util/NoSuchElementException.h>
#include <string>
#include <vector>

namespace decaf{
namespace util{

    /**
     * Class that allows for parsing of string based on Tokens.
     *
     * @since 1.0
     */
    class DECAF_API StringTokenizer {
    private:

        // String to tokenize
        std::string str;

        // The delimiter string
        std::string delim;

        // The current pos in the string
        std::string::size_type pos;

        // Are we returning delimiters
        bool returnDelims;

    public:

        /**
         * Constructs a string tokenizer for the specified string. All
         * characters in the delim argument are the delimiters for separating
         * tokens.
         *
         * If the returnDelims flag is true, then the delimiter characters are
         * also returned as tokens. Each delimiter is returned as a string of
         * length one. If the flag is false, the delimiter characters are
         * skipped and only serve as separators between tokens.
         *
         * Note that if delim is "", this constructor does not throw an
         * exception. However, trying to invoke other methods on the resulting
         * StringTokenizer may result in an Exception.
         * @param str - The string to tokenize
         * @param delim - String containing the delimiters
         * @param returnDelims - boolean indicating if the delimiters are returned as tokens
         */
        StringTokenizer(const std::string& str, const std::string& delim = " \t\n\r\f", bool returnDelims = false);

        virtual ~StringTokenizer();

        /**
         * Calculates the number of times that this tokenizer's nextToken
         * method can be called before it generates an exception. The current
         * position is not advanced.
         * @return Count of remaining tokens
         */
        virtual int countTokens() const;

        /**
         * Tests if there are more tokens available from this tokenizer's
         * string.
         * @return true if there are more tokens remaining
         */
        virtual bool hasMoreTokens() const;

        /**
         * Returns the next token from this string tokenizer.
         *
         * @return string value of next token
         *
         * @throws NoSuchElementException if there are no more tokens in this string.
         */
        virtual std::string nextToken();

        /**
         * Returns the next token in this string tokenizer's string. First,
         * the set of characters considered to be delimiters by this
         * StringTokenizer object is changed to be the characters in the
         * string delim. Then the next token in the string after the current
         * position is returned. The current position is advanced beyond the
         * recognized token. The new delimiter set remains the default after
         * this call.
         *
         * @param delim
         *      The string containing the new set of delimiters.
         *
         * @return next string in the token list
         *
         * @throws NoSuchElementException if there are no more tokens in this string.
         */
        virtual std::string nextToken(const std::string& delim);

        /**
         * Grab all remaining tokens in the String and return them
         * in the vector that is passed in by reference.
         * @param array - vector to place token strings in
         * @return number of string placed into the vector
         */
        virtual unsigned int toArray(std::vector<std::string>& array);

        /**
         * Resets the Tokenizer's position in the String to the Beginning
         * calls to countToken and nextToken now start back at the beginning.
         * This allows this object to be reused, the caller need not create
         * a new instance every time a String needs tokenizing.
         *
         *   * If set the string param will reset the string that this Tokenizer
         *     is working on.  If set to "" no change is made.
         *   * If set the delim param will reset the string that this Tokenizer
         *     is using to tokenizer the string.  If set to "", no change is made
         *   * If set the return Delims will set if this Tokenizer will return
         *     delimiters as tokens. Defaults to false.
         *
         * @param str
         *      New String to tokenize or "", defaults to ""
         * @param delim
         *      New Delimiter String to use or "", defaults to ""
         * @param returnDelims
         *      Should the Tokenizer return delimiters as Tokens, default false
         */
        virtual void reset(const std::string& str = "", const std::string& delim = "", bool returnDelims = false);

    };

}}

#endif /*_DECAF_UTIL_STRINGTOKENIZER_H_*/
