/* This file is part of cardwords
   (c) 1998 1999 2000 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_char.hh

#ifndef CARDWORDS_CHAR_HH
#define CARDWORDS_CHAR_HH

#include <string>
class istream;
class ostream;

#ifndef CHAR_SET_LENGTH
#define CHAR_SET_LENGTH 256
#endif
namespace CardWords {

class Char {
public:
  // the default copy constructor is ok
  // Char (const Char &);

  Char (unsigned char = 0);
  Char (char);
  
  // the default copy-assignment-operator is ok
  // Char & operator= (const Char &);

  Char &
  operator= (unsigned char);

  Char &
  operator= (char c);

  operator char() const;

  // defining a Char means: give a set(string!) of Machine_Chars
  // that are represented by the same Char (e.g. "Hh")
  static
  Char
  define ( const string & );

  // read these definition strings from a file:
  static
  void
  define_from_file (const string & filename);

  static
  void
  define_from_stream (istream &);

  static
  void
  write_definitions_to_stream (ostream &);
  
  // How many different Chars have been defined now?
  // (After calling this method, no new Char can be defined)
  static
  size_t
  noOfChars (void);

  // Discard all defined Chars:
  static
  void
  reset(void);
  
  bool
  operator < (const Char&) const;
  bool
  operator > (const Char&) const;
  bool
  operator == (const Char&) const;
  bool
  operator != (const Char&) const;
  int
  compare (const Char&) const;

  // Inkrement und dekrement-Operatoren:
  Char &
  operator ++ ();
  Char &
  operator -- ();
  Char
  operator ++ (int);
  Char
  operator -- (int);
  
private:
  typedef unsigned char CharNumber;

  CharNumber cardwordsCharNumber;

  // cardwordsCharNumbers[some_unsigned_char_from_user_charset]
  //  == internal number that specifies the Char that has the
  //  same meaning as the char in the index.
  static CharNumber cardwordsCharNumbers[CHAR_SET_LENGTH];

  // machineChars[internal_number]
  //   == *one* of the machinechars that are mapped to this internal_number
  //   by cardwordsCharNumbers[]
  static unsigned char        machineChars [CHAR_SET_LENGTH];

  static CharNumber nextFreeNumber;
  static bool                 definitionPossible;
public:
  static Char        blanko;

  size_t internal_no(void) const;

  // return the Char with this internal no:
  static
  Char
  get_cardwords_char_with_internal_no(unsigned char no);
};
}
ostream &
operator << (ostream &os, const CardWords::Char &kc);

istream &
operator >> (istream &is, CardWords::Char &kc);

#endif

