// This file is part of The New Aspell
// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
// version 2.0 or 2.1.  You should have received a copy of the LGPL
// license along with this library if you did not you can find
// it at http://www.gnu.org/.

#ifndef ASPELL_STRING__HPP
#define ASPELL_STRING__HPP

#include <string.h>
#include <string>

#include "hash_fun.hpp"
#include "parm_string.hpp"
#include "istream.hpp"
#include "ostream.hpp"
#ifdef WIN32PORT
#include "aspellroot.h"
using namespace std; // FB
#endif

namespace acommon {

  template <typename Ret> class PosibErr;
  
  class String : public std::string, public OStream
  {
  public:
#ifdef WIN32PORT
    ASPELL_API String() : string() {}
    ASPELL_API String(const char * s) : string(s) {}
    ASPELL_API String(const char * s, unsigned int size) : string(s, size) {}
    ASPELL_API String(ParmString s) : string(s) {}
    ASPELL_API String(const std::string & s) : string(s) {}
    ASPELL_API String(const String & other) : string(other) {}
    ASPELL_API String & operator= (const char * s) {
      string::operator= (s);
#else
    String() : std::string() {}
    String(const char * s) : std::string(s) {}
    String(const char * s, unsigned int size) : std::string(s, size) {}
    String(ParmString s) : std::string(s) {}
    String(const std::string & s) : std::string(s) {}
    String(const String & other) : std::string(other) {}
    inline String(const PosibErr<String> & other);
    String & operator= (const char * s) {
      std::string::operator= (s);
#endif
      return *this;
    }
    inline String & operator= (const PosibErr<const char *> & s);
    ASPELL_API String & operator= (ParmString s) {
#ifdef WIN32PORT
      string::operator= (s);
#else
      std::string::operator= (s);
#endif
      return *this;
    }
    ASPELL_API String & operator= (const std::string & s) {
#ifdef WIN32PORT
      string::operator= (s);
#else
      std::string::operator= (s);
#endif
      return *this;
    }
    ASPELL_API String & operator= (const String & other) {
#ifdef WIN32PORT
      string::operator= (other);
#else
      std::string::operator= (other);
#endif
      return *this;
    }
    ASPELL_API /*inline*/ String & operator= (const PosibErr<String> & s);

    ~String() {}

    void ASPELL_API clear() {*this = "";}

    void ASPELL_API write (char c);
    void ASPELL_API write (ParmString);
    void ASPELL_API write (const char *, unsigned int);
  };

  inline String operator+ (ParmString rhs, ParmString lhs)
  {
    String tmp;
    tmp.reserve(rhs.size() + lhs.size());
    tmp += rhs;
    tmp += lhs;
    return tmp;
  }

  inline ParmString::ParmString(const String & s) : str_(s.c_str()), size_(s.size()) {}


  class StringIStream : public IStream {
    const char * in_str;
    char         delem;
  public:
    StringIStream(ParmString s, char d = ';')
      : IStream(d), in_str(s) {}
    bool getline(String & str, char c);
    bool read(void * data, unsigned int size);
  };

  template <> struct hash<String> : public HashString<String> {};


}
#endif
