/* This file is part of cardwords
   (c) 1998 1999 Tobias Peters
   see file COPYING for the copyright terms.
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
// cardwords_string.hh

#ifndef CARDWORDS_STRING_HH
#define CARDWORDS_STRING_HH

#include "cardwords_char.hh"
#include "cardwords_machinestring.hh"
#include <vector>
#include <string.h>
#include <algo.h>

class CardWords_String {
public:
  CardWords_String () {};

  CardWords_String (const Machine_Char*);

  // this is again ok
  // CardWords_String (const CardWords_String&);

  // the default destructor is not virtual enough for the compiler
  // It would be ok to leave that warning in, but warnings are ugly...
  virtual ~CardWords_String() {};

  // the default assignment operator is ok
  // CardWords_String&
  // operator= (const CardWords_String &);

  // assignment from a non-string vector<CardWords_Char>:
  virtual
  CardWords_String&
  operator= (const vector<CardWords_Char> &);

  // copy a part from a non-string vector(CardWords_Char):
  CardWords_String (vector<CardWords_Char>::const_iterator,
                    vector<CardWords_Char>::const_iterator);
  virtual
  CardWords_String&
  operator+= (const CardWords_String &);

  virtual
  CardWords_String&
  operator+= (const CardWords_Char &);

  int
  compare (const CardWords_String &) const;

  bool
  operator== (const CardWords_String &) const;
  bool
  operator!= (const CardWords_String &) const;
  bool
  operator< (const CardWords_String &) const;
  bool
  operator> (const CardWords_String &) const;

  CardWords_Char &
  operator[] (int);

  const CardWords_Char &
  operator[] (int) const;

  size_t
  length (void) const {return representation.size();};

protected:
  friend ostream& operator<< (ostream &, const CardWords_String &);
  vector<CardWords_Char> representation;
public:
  void sort (void) {::sort(representation.begin(), representation.end());}
};

inline
CardWords_String::CardWords_String (const Machine_Char* str)
{
  assert (str);
  while (*str) {
    representation.push_back (*str++);
  }
}

inline
CardWords_String&
CardWords_String::operator+= (const CardWords_String &other)
{
  back_insert_iterator<vector<CardWords_Char> > dest (representation);

  copy (other.representation.begin(), other.representation.end(), dest);
  return *this;
}

inline
CardWords_String&
CardWords_String::operator+= (const CardWords_Char & c)
{
  representation.push_back (c);
  return *this;
}

inline
bool
CardWords_String::operator== (const CardWords_String & other) const
{
  return (compare(other) == 0);
}

inline
bool
CardWords_String::operator!= (const CardWords_String & other) const
{
  return (compare(other) != 0);
}

inline
bool
CardWords_String::operator< (const CardWords_String & other) const
{
  return (compare(other) < 0);
}

inline
bool
CardWords_String::operator> (const CardWords_String & other) const
{
  return (compare(other) > 0);
}

inline
CardWords_Char &
CardWords_String::operator[] (int n)
{
  return representation[n];
}

inline
const CardWords_Char &
CardWords_String::operator[] (int n) const
{
  return representation[n];
}

inline
istream& operator>> (istream &is, CardWords_String &ks)
{
  Machine_String b;
  is >> b;
  ks = (const Machine_Char *)b;
  return is;
}

inline
ostream& operator<< (ostream & os, const CardWords_String &ks)
{
  copy (ks.representation.begin(),
        ks.representation.end(),
        ostream_iterator<CardWords_Char> (os));
  return os;
}

// assignment from a non-string vector<CardWords_Char>:
inline CardWords_String&
CardWords_String::operator= (const vector<CardWords_Char> &vec)
{
  representation = vec;
  return *this;
}
// copy a part from a non-string vector(CardWords_Char):
inline
CardWords_String::CardWords_String (vector<CardWords_Char>::const_iterator i1,
                                    vector<CardWords_Char>::const_iterator i2)
  : representation(i1,i2)
{}
#endif

