// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1993 
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        error.h
// 
// Purpose:     generic hyperg error
// 
// Created:     29 Nov 93   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// 
// </file> 
#ifndef hg_hyperg_error_h
#define hg_hyperg_error_h

#include <hyperg/hyperg/language.h>

#include <Dispatch/enter-scope.h>

class rpcstream ;



// <class> 
//  
// Name:             ErrorBase
// 
// Purpose:          
// 
// Public Interface: 
// 
// Description:      
// 
// </class> 
class ErrorBase {
public:
   enum ErrorClass {
      // cannot be continuous for compatibility reasons (gpani's errorcode)
      HG = 0,
      FuT = 2,
      DC = 4,
      NCLASSES
   } ;

   // extracts the class id out of a code 
   static ErrorClass classId (int code) ;
   // extracts the specific error code of the class
   static int realCode (int code) ;

   virtual ErrorClass getClassId() const = 0 ;
   virtual const char* getClassName (int language) const = 0 ;
   virtual const char* getDescription (int code, int language=HgLanguage::Default) const = 0 ;
   virtual boolean getOk (int code) const = 0 ;

   // to assert that every used error class has ok == 0
   virtual int okDigit() const = 0 ;
} ;

// <class> 
//  
// Name:             Error
// 
// Purpose:          
// 
// Public Interface: 
// 
// Description:      
//
// </class> 
class Error {
public:
   Error() ;
   Error (int code) ; // just for testing purps.; in real life this is done by op.>>
   Error (const Error& e) ;

   // these go into the use-array; 
   // derived classes may overload them to do it directly 
   // (and to not have to use() anything)
   ErrorBase::ErrorClass classId() const ;
   const char* className (int language) const ;
   const char* description (int language=HgLanguage::Default) const ;
   boolean ok() const ;
   operator void*() const { return (void*)(!ok()); }
   boolean operator !() const { return ok(); }

   int code() const { return code_; }

   static void use (const ErrorBase*) ;

protected:
   int code_ ;

private:
   static const ErrorBase* errcl_[ErrorBase::NCLASSES] ;
   static const char* notusedstr_ ;
   static const char* notvalidstr_ ;

   static const int ok_digit_ ;

   friend rpcstream& operator << (rpcstream&, Error) ;
   friend rpcstream& operator >> (rpcstream&, Error&) ;
} ;
rpcstream& operator << (rpcstream&, Error) ;
rpcstream& operator >> (rpcstream&, Error&) ;



#endif
