/* 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_exceptions.hh

#ifndef CARDWORDS_EXCEPTIONS_HH
#define CARDWORDS_EXCEPTIONS_HH
#include <errno.h>
#include "cardwords_iostream.hh"
#include "cardwords_gettext.hh"
#include <string.h>

// Defining some types here that indicate exceptional states

// Thrown when the resources of the computer are exploited:
// Low memory, too many filedescriptors etc.
class CardWords_XLowResources
{
public:
  // the libc errno that caused this exception
  int error_number;

  // a string describing the situation that caused this exception
  const char *description;

  CardWords_XLowResources (int en, const char *desc);
  CardWords_XLowResources (const char *desc);

};

inline
CardWords_XLowResources::CardWords_XLowResources (int en, const char *desc)
{
  this->error_number = en; description = desc;
}

inline
CardWords_XLowResources::CardWords_XLowResources (const char *desc)
{
  this->error_number = errno;
  description = desc;
}
inline ostream & operator << (ostream & o,
                              const CardWords_XLowResources & xlr)
{
  o << gettext("Low Resources: ");
  if (xlr.description != 0) {
    o << xlr.description << ": ";
  }
  return o << strerror (xlr.error_number);
}
// Thrown when a bug in cardwords shows up:
class CardWords_XInternal_Error
{
public:
  // the libc errno that caused this exception
  int error_number;

  // a string describing the situation that caused this exception
  const char *description;

  CardWords_XInternal_Error (const char *desc);
};

inline
CardWords_XInternal_Error::CardWords_XInternal_Error (const char *desc)
{
  this->error_number = errno;
  description = desc;
}
inline ostream & operator << (ostream & o,
                              const CardWords_XInternal_Error & xie)
{
  o << gettext("Internal Error: ");
  if (xie.description != 0) {
    o << xie.description;
  }
  return o << gettext(". (May not apply here: ")
           << strerror (xie.error_number)
           << ')';
}
  
// Thrown when a member of array/vector/map was requested with illegal
// argument:
class CardWords_XOutOfRange
{
public:
  // a string describing the situation that caused this exception
  const char *description;

  CardWords_XOutOfRange (const char *desc) {
    description = desc;
  }
};
inline ostream & operator << (ostream & o, const CardWords_XOutOfRange & xoor)
{
  o << gettext("Out Of Range Error: ");
  if (xoor.description != 0) {
    o << xoor.description;
  }
  return o;
}
  
// Thrown when a file does not exist or permissions deny the usage of it:
class CardWords_XAccessingFile
{
public:
  // the libc errno that caused this exception
  int error_number;

  // a string describing the situation that caused this exception
  const char *description;

  // the filename that caused this exception
  const char *filename;

  CardWords_XAccessingFile (int en, const char *desc, const char *fn);
  CardWords_XAccessingFile (const char *desc, const char *fn);
  CardWords_XAccessingFile (const char *desc, const unsigned char *fn);
};

inline
CardWords_XAccessingFile::CardWords_XAccessingFile (int en,
                                                    const char *desc,
                                                    const char *fn)
{
  error_number = en;
  description = desc;
  filename = fn;
}

inline
CardWords_XAccessingFile::CardWords_XAccessingFile (const char *desc,
                                                    const char *fn)
{
  error_number = errno; description=desc; filename=fn;
}
inline
CardWords_XAccessingFile::CardWords_XAccessingFile (const char *desc,
                                                    const unsigned char *fn)
{
  error_number = errno; description=desc; filename=(const char *)fn;
}

inline
ostream & operator << (ostream & os, const CardWords_XAccessingFile& x)
{
  os << gettext ("Unable to access file ") 
     << x.filename << ": " << x.description << ": "
     << strerror(x.error_number);
  return os;
}

// thrown when the input does not match the expected format:
class CardWords_XBadInput {
public:
  const char * description;
  const char * expected;

  CardWords_XBadInput (const char *desc, const char *exp);
};

inline
CardWords_XBadInput::CardWords_XBadInput (const char *desc, const char *exp)
{
  description = desc; expected = exp;
}

inline
ostream & operator <<(ostream &os, const CardWords_XBadInput & x)
{
  return os << gettext ("Bad Input Reading ") << x.description
            << gettext (", expected ") << x.expected;
}

// Thrown when a request for a member of a union is scheduled and that member
// is currently not existing and the type of the return value has no way to
// tell that the request was invalid (like a NULL pointer).
class CardWords_XInvalidRequest {
public:
  // a string describing the situation that caused this exception
  const char *description;

  CardWords_XInvalidRequest (const char *desc) {
    description = desc;
  }
};

#define CardWords_XBadNetworkMessage CardWords_XBadInput

#endif
