#ifndef LOGGER
#define LOGGER

#include <deque>
#include <iostream>
#include <ostream>
#include <fstream>

#include <pthread.h>

#include "Header.hh"

#include "AdvMessage.hh"

/** simple logger for classs that support thread (pthread)
 *  print message to the standard error
 *
 *  @author TANIMORI Souichirou, AdvanceSoft Corp.
 *  @verion 0.0
 *  @since  0.8
 */
class AdvLogger {

    public:
        enum Level {
            ERROR,   /** the highest level */
            WARNING,
            INFO,
            CONFIG,
            FINE,
            FINER,
            FINEST    /** the lowest level */
        };
        static const Level DEFAULT_LEVEL; //
        static const std::string LevelStr[];

    private:
        pthread_mutex_t mutex;
        ptheead_cond_t  guard;

        Int4 level;

    protected:
        AdvLogger();
        ~AdvLogger();

    public:
        AdvLogger *getLogger();

        void setLevel(LogLevel level) { this->level=level } ;
        Int4 getLevel() { return this->level; } ;

        void error(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const std::string &description);
        void error(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const Char *fmt, ...);
        void error(const std::string &className, const std::string &memberName, const std::string *description);
        void error(const std::string &className, const std::string &memberName, const Char *fmt, ...);

        void warning(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const std::string &description);
        void warning(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const Char *fmt, ...);
        void warning(const std::string &className, const std::string &memberName, const std::string *description);
        void warning(const std::string &className, const std::string &memberName, const Char *fmt, ...);

        void info(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const std::string &description);
        void info(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const Char *fmt, ...);
        void info(const std::string &className, const std::string &memberName, const std::string *description);
        void info(const std::string &className, const std::string &memberName, const Char *fmt, ...);

        void debug(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const std::string &description);
        void debug(const std::string &className, const std::string &memberName, const std::string &fileName, const Int4 lineNo, const Char *fmt, ...);
        void debug(const std::string &className, const std::string &memberName, const std::string *description);
        void debug(const std::string &className, const std::string &memberName, const Char *fmt, ...);
}

#endif // LOGGER
