/*
 * Pspell interface header file
 * Copyright 2000 by Kevin Atkinson under the terms of the LGPL
 *
 */

#ifndef PSPELL_ERROR__H
#define PSPELL_ERROR__H

#define PERROR_NOT                     0000

#define PERROR_OTHER                   0500

#define PERROR_OPERATION_NOT_SUPPORTED 1000
#define PERROR_CANT_COPY               1100

#define PERROR_FILE                    2000
#define PERROR_CANT_READ_FILE          2100
#define PERROR_CANT_WRITE_FILE         2200
#define PERROR_BAD_FILE_FORMAT         2300

#define PERROR_CONIG                   3000
#define PERROR_UNKNOWN_KEY             3100
#define PERROR_CANT_CHANGE_VALUE       3200
#define PERROR_BAD_ITEM                3300
#define PERROR_BAD_KEY                 3310
#define PERROR_BAD_VALUE               3320
#define PERROR_LIST_SET                3330
#define PERROR_DUPLICATE               3400

#define PERROR_LANGUAGE_RELATED         4000

#define PERROR_LANGUAGE                 4100
#define PERROR_UNKNOWN_LANGUAGE         4110
#define PERROR_LANGUAGE_NOT_SUPPORTED   4120
#define PERROR_NO_WORDLIST_FOR_LANG     4121

#define PERROR_REGION                   4200
#define PERROR_UNKNOWN_REGION           4210
#define PERROR_REGION_NOT_SUPPORTED     4220

#define PERROR_ENCODING                 4300
#define PERROR_UNKNOWN_ENCODING         4310
#define PERROR_ENCODING_NOT_SUPPORTED   4320
#define PERROR_CONVERSION_NOT_SUPPORTED 4330

#define PERROR_PIPE                     5000
#define PERROR_CANT_CREATE_PIPE         5100
#define PERROR_PROCESS_DIED             5200

#define PERROR_BAD_INPUT                6000
#define PERROR_INVALID_WORD             6100

#ifdef __cplusplus

inline bool perror_check(int check_for, int error) {
  return 
    check_for % 1000 == 0 ? check_for <= error && error < check_for + 1000 
  : check_for % 100  == 0 ? check_for <= error && error < check_for + 100  
  : check_for % 10   == 0 ? check_for <= error && error < check_for + 10   
  : check_for == error;
}

class PspellErrorExtraInfo;

class PspellCanHaveError {
 public:
  virtual int error_number() const = 0;
  // return the error number

  virtual const char * error_message() const = 0;
  // returns an *informative* error message.  This message included
  // more information than an english desciption of the error number
  // such as the key or value that was the culprit.

  virtual const PspellErrorExtraInfo * error_extra_info() const = 0;
  // returns any extra info associated with the current error.
  // Null if there is none. (NOTE: currently always returns null).

  virtual ~PspellCanHaveError() {}
};

class PspellErrorExtraInfo {
public:
  virtual PspellErrorExtraInfo * clone() const = 0;
  virtual void assign(const PspellErrorExtraInfo *) = 0;
  virtual ~PspellErrorExtraInfo() {}
};
 
#else 

#define perror_check(check_for, error) \
      check_for % 1000 == 0 ? check_for <= error && error < check_for + 1000 \
    : check_for % 100  == 0 ? check_for <= error && error < check_for + 100  \
    : check_for % 10   == 0 ? check_for <= error && error < check_for + 10   \
    : check_for == error;

typedef struct PspellCanHaveError   PspellCanHaveError;

typedef struct PspellErrorExtraInfo PspellErrorExtraInfo;

#endif

#ifdef __cplusplus
extern "C" {
#endif

  int pspell_error_number(const PspellCanHaveError *);
  
  const char * pspell_error_message(const PspellCanHaveError *);

  const PspellErrorExtraInfo * pspell_error_extra_info(const PspellCanHaveError *);

  void delete_pspell_can_have_error(PspellCanHaveError *);

#ifdef __cplusplus
}
#endif

#endif
