/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CStrings.h  -  description
                             -------------------
    begin                : Thu August 11 2005
    copyright            : (C) 2005 by Alexey Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library 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 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 Library
   General Public License for more details.

   You should have received a copy of the GNU Library 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.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifndef __CSTRINGS_H__
#define __CSTRINGS_H__

#include <sptk3/sptk.h>
#include <sptk3/string_ext.h>
#include <sptk3/CException.h>
#include <string>
#include <vector>
#include <algorithm>

/// @addtogroup utility Utility Classes
/// @{

/// A workaround for VC++ bug
typedef std::string std_string;

/// @brief String with ID
/// Extended version of std::string that supports an integer string ID
class SP_EXPORT idstring : public std_string {
public:
   long       m_id;	///< String ID
public:
   /// Default constructor
   idstring() { m_id = 0; }

   /// Copy constructor
   /// @param str const idstring&, source string
   idstring(const idstring& str) : std_string(str), m_id(str.m_id) {}

   /// Constructor
   /// @param str const string&, source string
   /// @param id in, optional string id
   idstring(const std::string& str,long id=0) : std_string(str), m_id(id) {}

   /// Constructor
   /// @param str const char *, source string
   /// @param id in, optional string id
   idstring(const char *str,long id=0) : std_string(str), m_id(id) {}

   /// Assignment operator
   idstring& operator = (const idstring& si)  { assign(si); m_id = si.m_id; return *this; }

   /// Assignment operator
   /// @param str const char *, source string
   idstring& operator = (const char * str) { assign(str); m_id = 0; return *this; }

   /// Returns string ID
   long ident() const { return m_id; }

   /// Sets string ID
   void ident(long id) { m_id = id; }

   /// Convertor
   //operator std::string () const { return c_str(); }
};

/// @brief List of strings with ids
///
/// General string list. Based on vector<idstring>. Stores strings with (optional) integer Ids.
/// Includes several extra methods to construct it from string or load/save from/to file.
class CStrings : public std::vector<idstring> {

   long m_userData;	///< User-specified data

   /// Parses a string to elements separated by a delimiter string
   /// @param src const char *, a source string
   /// @param separator const char *, a separator string
   void parseString(const char *src,const char *delimitter);
public:	
   /// Default constructor
   CStrings() { m_userData = 0; }

   /// Copy constructor
   CStrings(const CStrings& src) {
      resize(src.size());
      std::copy(src.begin(),src.end(),begin()); 
   }

   /// Constructor from a string with elements separated by a delimiter string
   /// @param src const std::string&, a source string
   /// @param separator const char *, a separator string
   CStrings(const std::string& src,const char *separator) {
      parseString(src.c_str(),separator);
   }

   /// Constructor from a string with elements separated by a delimiter string
   /// @param src const char *, a source string
   /// @param separator const char *, a separator string
   CStrings(const char *src,const char *separator) {
      clear();
      parseString(src,separator);
   }

   /// Assigns strings from a string with elements separated by a delimiter string
   /// @param src const std::string&, a source string
   /// @param separator const char *, a separator string
   void fromString(const std::string& src,const char *separator) {
      clear();
      parseString(src.c_str(),separator);
   }

   /// Makes string from own strings separated by a delimiter string
   /// @param separator const char *, a separator string
   std::string asString(const char *separator) const;

   /// Returns an index of the string in strings, or -1 if not found
   /// @param s std::string, a string to find
   /// @returns a string index, or -1
   int indexOf(std::string s) const;

   /// Saves strings to file. String ids are discarded.
   /// @param fileName std::string, the name of the file
   void saveToFile(std::string fileName) const throw(CException);

   /// Loads strings from file. String ids are not loaded.
   /// @param fileName std::string, the name of the file
   void loadFromFile(std::string fileName) throw(CException);

   /// Returns user data as integer
   long argument() const   { return (int)m_userData; }

   /// Sets user data as integer
   /// @param d int, new value for user data
   void argument(long d)   { m_userData = d; }

   /// Removes a string from vector
   /// @param i unsigned, string index in the vector
   void remove(unsigned i) { erase(begin()+i); }
};

/// @}

#endif
