// ---------------------------------------------------------------------------
// - Exception.hpp                                                           -
// - standard object library - exception class definition                    -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - 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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2023 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef AFNIX_EXCEPTION_HPP
#define AFNIX_EXCEPTION_HPP

#ifndef  AFNIX_STRING_HPP
#include "String.hpp"
#endif

namespace afnix {

  /// The Exception class is the base class for any exception generated by 
  /// the standard object library. The Exception holds a short string as a 
  /// descriptor and eventually a message. An object can be attached to the 
  /// exception for further reference.
  /// @author amaury darsch

  class Exception : public virtual Object {
  protected:
    /// the exception id
    String  d_eid;
    /// the exception reason
    String  d_reason;
    /// the file name
    String  d_name;
    /// the line number
    long    d_lnum;
    /// the newline flag
    bool    d_nlf;
    /// the abort flag
    bool    d_abf;
    /// the client object
    Object* p_obj;

  public:
    /// create a default exception
    Exception (void);
    
    /// create a exception with an id
    /// @param eid the exception id
    Exception (const String& eid);

    /// create a exception with an id and a reason
    /// @param eid    the exception id
    /// @param reason the reason for this exception
    Exception (const String& eid, const String& reason);

    /// create an exception with an id, a reason and a name
    /// @param eid    the exception eid
    /// @param reason the reason for this exception
    /// @param name   the name for the reason
    Exception (const String& eid, const String& reason, const String& name);

    /// create an exception with an eid an object
    /// @param eid    the exception id
    /// @param object the exception client object
    Exception (const String& eid, Object* object);

    /// create an exception with an id, a reason and an object
    /// @param eid    the exception id
    /// @param reason the reason for this exception
    /// @param object the exception client object
    Exception (const String& eid, const String& reason, Object* object);

    /// copy constructor for this exception class.
    /// @param that the exception to copy
    Exception (const Exception& that);

    /// destroy this exception class
    ~Exception (void);

    /// assign an exception to this one
    /// @param that the exception to assign
    Exception& operator = (const Exception& that);

    /// @return the class name
    String repr (void) const override;

    /// @return a clone of this object
    Object* clone (void) const override;

    /// @return the exception id
    virtual String geteid (void) const;

    /// @return the exception reason
    virtual String getval (void) const;

    /// @return the exception object
    virtual Object* getobj (void) const;

    /// set the new line flag
    virtual void setnlf (const bool flag);

    /// @return the new line flag
    virtual bool getnlf (void) const;

    /// set the abort flag
    virtual void setabf (const bool flag);

    /// @return the abort flag
    virtual bool getabf (void) const;

    /// update the exception file name (aka do not touch if set)
    /// @param name the file name to set
    virtual void updname (const String& name);

    /// set the exception file name
    /// @param name the file name to set
    virtual void setname (const String& name);

    /// @return the exception file name
    virtual String getname (void) const;

    /// update the exception line number (aka do not touch if set)
    /// @param lnum the line number to set
    virtual void updlnum (const long lnum);

    /// set the exception line number
    /// @param lnum the line number to set
    virtual void setlnum (const long lnum);

    /// @return the exception line number
    virtual long getlnum (void) const;

    /// @return an extended exception reason
    virtual String geteer (void) const;

  public:
    /// @return true if the given quark is defined
    bool isquark (const long quark, const bool hflg) const override;

    /// evaluate an object member by quark
    /// @param zobj  the current evaluable
    /// @param nset  the current nameset    
    /// @param quark the quark to evaluate
    Object* eval (Evaluable* zobj, Nameset* nset, const long quark) override;    
  };
}

#endif
