#ifndef FMP_LOGGERSTREAM_H
#define FMP_LOGGERSTREAM_H

#include <QDebug>
#include <QDateTime>

class FMPLogStream : public QDebug
{
public:
    enum {
        ERROR = 1, WARNING, INFO, DEBUG
    };
    explicit    FMPLogStream(short level, const char* file, const char* func, int line, QIODevice* d = 0)
        : QDebug(d),
          _level(level),
          _file(file),
          _func(func),
          _line(line),
          _device(d)
    {
        _lvmap[ERROR]       = "[ERROR]";
        _lvmap[WARNING]     = "[WARNING]";
        _lvmap[INFO]        = "[INFO]";
        _lvmap[DEBUG]       = "[DEBUG]";
    }

    ~FMPLogStream()
    {
        if (this->_device) {
            QDebug::operator <<(endl);
        }
    }

    template <typename T>
    QDebug &   operator<<(const T& t)
    {
        QDebug & stream = *(this);
        if (!_device) {
            stream = qDebug();
        }
        QString extra;
        if (_level != INFO) {
            QString filename(_file);
            filename = filename.section("\\", -1);
            filename = filename.section("/", -1);
            extra += QString("%1(%2)").arg(filename).arg(QString::number(_line));
            extra += QString("%1:").arg(_func);
        }

        QString s = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
        s.append(_lvmap[_level]);
        stream.noquote() << s << extra << t;

        return stream;
    }

protected:
    int                 _level;
    QMap<int, QString>  _lvmap;
    const char *        _file;
    const char *        _func;
    int                 _line;
    QIODevice*          _device;
};


class FMPNullLogStream : public FMPLogStream
{
public:
    explicit    FMPNullLogStream(short level, const char* file, const char* func, int line)
        : FMPLogStream(level, file, func, line)
    {}
};

#endif // FMP_LOGSTREAM_H
