#ifndef INCLUDED_BOBCAT_STRING_
#define INCLUDED_BOBCAT_STRING_

#include <cstring>
#include <string>
#include <vector>
#include <cctype>

namespace FBB
{

class String
{
    public:
        enum Type
        {
            DQUOTE_UNTERMINATED,    // unterminated d-quoted element
            SQUOTE_UNTERMINATED,    // unterminated s-quoted element
            ESCAPED_END,            // word with plain \ at the end
            SEPARATOR, // separator encountered
            NORMAL, // normal string-element in the original string
            DQUOTE, // string-element originally surrounded by " chars
            SQUOTE, // string-element originally surrounded by ' chars
        };
        typedef std::pair<std::string, Type> SplitPair;
        typedef std::string::const_iterator const_iterator;

        static char const **argv(std::vector<std::string> const &lines);

        static int casecmp(std::string const &lhs, std::string const &rhs);
        static std::string lc(std::string const &str);
        static size_t split(std::vector<std::string> *words,
                        std::string const &str,
                        char const *separators = " \t",
                        bool addEmpty = false);
        static size_t split(std::vector<SplitPair> *words,
                        std::string const &str,
                        char const *separators = " \t",
                        bool addEmpty = false);
        static std::string trim(std::string const &str);
        static std::string uc(std::string const &str);
        static std::string unescape(std::string const &str);
        static std::string escape(std::string const &str, 
                            char const *series = "'\"\\");

    private:
        static Type nextField(std::string const &str,
                        const_iterator *until, const_iterator from,
                        std::string const &separators);
        static const_iterator separator(std::string const &str,
                                const_iterator from, 
                                std::string const &separators);
        static const_iterator quoted(std::string const &str,
                                const_iterator from, int quote);
        static Type word(std::string const &str,
                            const_iterator *until, const_iterator from, 
                            std::string const &separators);

        static void tolower(char &chr);
        static void toupper(char &chr);
};

inline int String::casecmp(std::string const &lhs, std::string const &rhs)
{
    return strcasecmp(lhs.c_str(), rhs.c_str());
}

} // FBB


#endif
