// ---------------------------------------------------------------------------
// - Logger.hpp                                                              -
// - standard object library - message logger 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-2012 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  AFNIX_LOGGER_HPP
#define  AFNIX_LOGGER_HPP

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

namespace afnix {

  /// The Looger class is a message logger that stores messages in a
  /// buffer with a level. The default level is the level 0. A negative level 
  /// generally indicates a warning or an error message but this is just
  /// a convention which is not enforced by the class. A high level generally
  /// indicates a less important message. The messages are stored in a circular
  /// buffer. When the logger is full, a new message replace the oldest one. 
  /// By default, the logger is initialized with a 256 messages capacity 
  /// that can be resized.
  /// @author amaury darsch

  class Logger : public virtual Object {
  private:
    /// the logger size
    long d_size;
    /// the logger length
    long d_mcnt;
    /// the logger position
    long d_mpos;
    /// the logger base
    long d_base;
    /// the default level
    long d_dlvl;
    /// the output stream
    OutputStream* p_os;
    /// the message log array
    struct s_mlog* p_mlog;

  protected:
    /// the logger info
    String d_info;
    /// the report level
    long d_rlvl;
    
  public:
    /// create a default logger
    Logger (void);
  
    /// create a logger by size
    /// @param size the logger size
    Logger (const long size);

    /// create a logger by info
    /// @param info the logger size
    Logger (const String& info);

    /// create a logger by size and info
    /// @param size the logger size
    /// @param info the logger size
    Logger (const long size, const String& info);

    /// destroy this logger
    ~Logger (void);

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

    /// reset this logger
    virtual void reset (void);

    /// set the logger info
    /// @param the logger info to set
    virtual void setinfo(const String& info);

    /// @return the logger info
    virtual String getinfo (void) const;

    /// @return the logger length
    virtual long length (void) const;

    /// add a message with a default level
    /// @param mesg the message to add
    virtual void add (const String& mesg);
    
    /// add a message by log level
    /// @param mesg the message to add
    /// @param mlvl the message level
    virtual void add (const String& mesg, const long mlvl);

    /// set the default level
    /// @param dlvl the default level to set
    virtual void setdlvl (const long dlvl);

    /// @return the default level
    virtual long getdlvl (void) const;

    /// set the report level
    /// @param rlvl the report level to set
    virtual void setrlvl (const long drvl);

    /// @return the report level
    virtual long getrlvl (void) const;

    /// @return true if the message level is valid
    virtual bool ismlvl (const long index) const;

    /// @return a message level by index
    virtual long getmlvl (const long index) const;

    /// @eturn a message time by index
    virtual t_long gettime (const long index) const;

    /// @return a message by index
    virtual String getmesg (const long index) const;

    /// @return a full message by index
    virtual String getfull (const long index) const;

    /// set the logger output stream
    /// @param os the output stream to bind
    virtual void setos (OutputStream* os);

    /// set the logger output file name
    /// @param name the output file name
    virtual void setos (const String& name);

    /// resize this message log
    /// @param size the new logger size
    void resize (const long size);

  private:
    // make the copy constructor private
    Logger (const Logger&);
    // make the assignment operator private
    Logger& operator = (const Logger&);    

  public:
    /// create a new object in a generic way
    /// @param argv the argument vector
    static Object* mknew (Vector* argv);

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

    /// apply this object with a set of arguments and a quark
    /// @param robj  the current runnable
    /// @param nset  the current nameset    
    /// @param quark the quark to apply these arguments
    /// @param argv  the arguments  to apply
    Object* apply (Runnable* robj, Nameset* nset, const long quark,
		   Vector* argv);
  };
}

#endif
