// ---------------------------------------------------------------------------
// - 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-2019 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 {
  private:
    /// the exception id
    String  d_eid;
    /// the exception reason
    String  d_reason;
    /// the exception client object
    Object* p_obj;
    /// the file name
    String  d_name;
    /// the line number
    long    d_lnum;
    /// the newline flag
    bool    d_nlf;
    /// the abort flag
    bool    d_abf;

  public:
    /// 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);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  private:
    // make the assignment operator private
    Exception& operator = (const Exception&);

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

    /// evaluate an object member by quark
    /// @param robj  the current runnable
    /// @param nset  the current nameset    
    /// @param quark the quark to evaluate
    Object* eval (Runnable* robj, Nameset* nset, const long quark);    
  };
}

#endif
