#ifndef MESSAGE_H
#define MESSAGE_H

#include <cstdarg>
#include <cstdio>
#include <iostream>
#include <ostream>
#include <string>

#include "Header.hh"

#ifdef DEBUG
/* GCC extention ##__VA_ARGS__ */
#define DebugMessage(name, member, fmt, ... ) debugMessage(className, member, fmt, ##__VA_ARGS__); std::cerr.flush()
#else
#define DebugMessage(name, member, fmt, ... )
#endif


/**
 *  output error and waring messages in the prescribed form to stderr
 *
 */
class AdvMessage {

    private:
        static const std::string ERROR_LEADER;
        static const std::string WARNING_LEADER;
        static const std::string INFO_LEADER;
        static const std::string DEBUG_LEADER;

        static const std::string SCOPE;
        static const std::string SEPARATOR;

        /** output a leader std::string to the stndard output */
        void outputLeader(const std::string &className, const std::string &memberName);

        /** output a leader std::string to the stndard error output */
        void outputLeader(const std::string &leader, const std::string &className, const std::string &memberName);
        /** output a leader std::string to the stndard error output */
        void outputLeader(const std::string &leader, const std::string &className, const std::string &memberName, const Char *file, const Int4 line);

        /** output a message std::string to the stndard error message */
        void outputMessage(const std::string &description) ;

        void end(void) ;

    public:

        /** output a message with a leader to the stndard output */
        //void message(const std::string &className, const std::string &memberName, const std::string &description) ;
        /** output a message with a leader in the given format to the standard output */
        //void message(const std::string &className, const std::string &memberName, const char *format, ...) ;
        /** output a message without a leader in the given format to the standard output */
        void message(const char *format, ...);

        //----------------------------------------------------------------------------------------------
        /** output a error message with a leader to the standard error output */
        //void errorMessage(const std::string &className, const std::string &methodName, const Char *file, const Int4 line, const std::string &description) ;
        /** output a error message with a leader in the given format to the standard error output */
        void errorMessage(const std::string &className, const std::string &methodName, const Char *file, const Int4 line, const char *format, ...)  ;

        /** output a error message with a leader to the standard error output */
        //void errorMessage(const std::string &className, const std::string &methodName, const std::string &description) ;
        /** output a error message with a leader in the given format to the standard error output */
        void errorMessage(const std::string &className, const std::string &methodName, const char *format, ...)  ;
        /** output a error message without a leader in the given format to the standard error output */
        void errorMessage(const char *format, ...)  ;


        /** output a warning message with a leader to the standard error output */
        //void warningMessage(const std::string &className, const std::string &methodName, const Char *file, const Int4 line, const std::string &description) ;
        /** output a warning message with a leader in the given format to the standard error output */
        void warningMessage(const std::string &className, const std::string &methodName, const Char *file, const Int4 line, const char *format, ...)  ;


        /** output a warning message with a leader to the standard error output */
        //void warningMessage(const std::string &className, const std::string &methodName, const std::string &description) ;
        /** output a warning message with a leader in the given format to the standard error output */
        void warningMessage(const std::string &className, const std::string &methodName, const char *format, ...)  ;
        /** output a warning message without a leader in the given format to the standard error output */
        void warningMessage(const char *format, ...)  ;

        /** output a information message with a leader to the standard error output */
        void infoMessage(const std::string &className, const std::string &methodName, const std::string &description) ;
        /** output a infomation message with a leader in the given format to the standard error output */
        void infoMessage(const std::string &className, const std::string &methodName, const char *format, ...)  ; 
        /** output a infomation message without a leader in the given format to the standard error output */
        void infoMessage(const char *format, ...)  ; 


        /** output a debug message with a leader to the standard error output */
        void debugMessage(const std::string &className, const std::string &methodName, const Char *file, const Int4 line, const std::string &description) ;
        /** output a debug message with a leader in the given format to the standard error output */
        void debugMessage(const std::string &className, const std::string &methodName, const Char *file, const Int4 line, const char *format, ...)  ; 

        /** output a debug message with a leader to the standard error output */
        void debugMessage(const std::string &className, const std::string &methodName, const std::string &description) ;
        /** output a debug message with a leader in the given format to the standard error output */
        void debugMessage(const std::string &className, const std::string &methodName, const char *format, ...)  ; 
        /** output a debug message without a leader in the given format to the standard error output */
        //void debugMessage(const char *firmat, ...)  ; 
};

#endif
