////////////////////////////////////////////////////////////////////////////////
//DRS_Error.h
//DRS errors and error reporters.
////////////////////////////////////////////////////////////////////////////////

#ifndef DRS_ERROR_H
#define DRS_ERROR_H

#include <vector>
#include "drs/na_types.h"

#include "base/at_defs.h"
#include "xdart/x_at_index.h"
#include "base/at_error.h"
#include "retrieve/at_parse.h"
#include "base/at_reporterr.h"

#include "drs/drs_type.h"
#include "drs/drs_error.h"

#ifndef NDEBUG
  #define DRS_DEBUG
#endif

#ifdef DRS_DEBUG
  #define DRS_AssertBounds( s, x, y) \
          AT_Assert( *this, (x <= y), s);
#else
  #define DRS_AssertBounds( s, x, y)
#endif


class DRS_Error : public AT_Error
{
public :

  class Reporter;  // defined below

  virtual void report
    (Reporter &reporter)
    const = 0;

protected :
  DRS_Error
    (const char *module = 0,
     uint lineNum = 0,
     AT_String objectType = 0,
     AT_String objectName = 0,
     const AT_Error *const prev = 0) :
    AT_Error(module, lineNum, objectType, objectName, prev)
  {};

  DRS_Error
    (const DRS_Error &err) :
    AT_Error(err)
  {};
};

class DRS_ErrorMissingConfig : public DRS_Error
{
public :
  DRS_ErrorMissingConfig
    (const char* module,
     uint lineNum,
     AT_String objectType = 0,
     AT_String sFile = 0,
     AT_String sSection = 0,
     AT_String sKey = 0)
         : DRS_Error(module, lineNum, objectType, sSection),
           sSourceFile( (AT_String) sFile),
           sSourceKey( (AT_String) sKey)
     {};

  #define DRSERR_MissingConfig(T, f, s, k)  \
    DRS_ErrorMissingConfig(__FILE__, __LINE__, (AT_String) typeid(T).name(), (AT_String) f, (AT_String) s, (AT_String) k)

  DRS_ErrorMissingConfig *clone
    ()
    const;

  class Reporter;
  void report
    (DRS_Error::Reporter &r)
    const;

  AT_String File() const { return sSourceFile;};
  AT_String Section() const { return getObjectName();};
  AT_String Key() const { return sSourceKey;};

private :
  const AT_String sSourceFile;
  const AT_String sSourceKey;
};

class DRS_ErrorFormat : public collStrings
{
public:
  void GetStrings( std::vector<std::string> &v) { collStrings::GetStrings(v); }

protected:
  byte num_buf[35];

  void PushErr
    (const AT_Error *const err);

  void PushErr
    (const AT_System_Error *const err);

  void PushErr
    (const AT_General_Error *const err);

  //Base info formatting funcs
  na_string Param( const AT_Error *const err, char const * prefix = 0);
  na_string ObjectStamp( const AT_Error *const err);
  na_string FileStamp( const AT_Error *const err);
  na_string ErrorNum( const AT_System_Error *const err);
};

class DRS_ConfigFormat : public DRS_ErrorFormat
{
protected:
  void PushErr
    (const DRS_ErrorMissingConfig  *const err);
};

class DRS_GenFormat : public DRS_ErrorFormat
{
protected:
  void PushErr
    (const AT_Logic_Error *const err);

  void PushErr
    (const AT_Bounds_Error *const err);

  void PushErr
    (const AT_Corrupt_Error *const err);

  void PushErr
    (const AT_File_Open_Error *const err);

  void PushErr
    (const AT_File_Type_Error *const err);

  void PushErr
    (const AT_File_Read_Error *const err);

  void PushErr
    (const AT_File_Write_Error *const err);

  void PushErr
    (const AT_Constructor_Error *const err);

  void PushErr
    (const AT_Function_Error *const err);

  void PushErr
    (const AT_Unexpected_Error *const err);
};

class DRS_IdxFormat : public DRS_ErrorFormat
{
protected:
  void PushErr
    (const AT_Index_List::noIndex *const err);

  void PushErr
    (const AT_Index_List::openError *const err);
    
  void PushErr
    (const AT_Parse::Error *const err);
};

class DRS_Error::Reporter : public AT_Error::Reporter, public DRS_ConfigFormat
{
public:
  //default
  virtual void report
    (const AT_Error *const err);

  virtual void report
    (const AT_System_Error *const err);

  virtual void report
    (const DRS_ErrorMissingConfig  *const err);
};

class AT_GenErrorReporter : public AT_General_Error::Reporter, public DRS_GenFormat
{
public:

  virtual void report
    (const AT_Error *const err);

  // PS added
  virtual void report
    (const AT_General_Error *const err);

  virtual void report
    (const AT_Logic_Error *const err);

  virtual void report
    (const AT_Bounds_Error *const err);

  virtual void report
    (const AT_Corrupt_Error *const err);

  virtual void report
    (const AT_System_Error *const err);

  virtual void report
    (const AT_File_Open_Error *const err);

  virtual void report
    (const AT_File_Type_Error *const err);

  virtual void report
    (const AT_File_Read_Error *const err);

  virtual void report
    (const AT_File_Write_Error *const err);

  virtual void report
    (const AT_Constructor_Error *const err);

  virtual void report
    (const AT_Function_Error *const err);

  virtual void report
    (const AT_Unexpected_Error *const err);
};

class AT_IdxErrorReporter : public AT_Index_List::Error::Reporter, public DRS_IdxFormat
{
public:

  virtual void report
    (const AT_Index_List::noIndex *const err);

  virtual void report
    (const AT_Index_List::openError *const err);

  void report
    (const AT_Parse::Error *const err);

  virtual void report
    (const AT_System_Error *const err);

  virtual void report
    (const AT_Error *const err);
};


#endif