/***************************************************************************
                                kstdebug.cpp
                             -------------------
    begin                : Mar 07 2004
    copyright            : (C) 2004 The University of Toronto
    email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kstdatasource.h"
#include "kstdebug.h"
#include "kstversion.h"

#include <kapplication.h>
#include <klocale.h>

static KStaticDeleter<KstDebug> sd;

KstDebug *KstDebug::_self = 0L;

static QMutex soLock;
KstDebug *KstDebug::self() {
  QMutexLocker ml(&soLock);
  if (!_self) {
    _self = sd.setObject(_self, new KstDebug);
  }

  return _self;
}


KstDebug::KstDebug() {
  _applyLimit = false;
  _limit = 10000;
}


KstDebug::~KstDebug() {
}


QStringList KstDebug::dataSourcePlugins() const {
  return KstDataSource::pluginList();
}


void KstDebug::log(const QString& msg, LogLevel level) {
  QMutexLocker ml(&_lock);
  LogMessage message;
  
  message.date  = QDateTime::currentDateTime();
  message.msg   = msg;
  message.level = level;
      
  _messages.append(message);
  if (_applyLimit) {
    if ((int)_messages.size() > _limit) {
      QValueListIterator<LogMessage> first;
      QValueListIterator<LogMessage> last;

      first = _messages.begin();
      last  = first;
      last += _messages.size() - _limit; 

      _messages.erase(first, last);
    }
  }
  
  emit logAdded();
}


void KstDebug::clear() {
  QMutexLocker ml(&_lock);
  _messages.clear(); 
}


QString KstDebug::label(LogLevel level) const {
  switch (level) {
    case Notice:
      return i18n("Notice");
    case Warning:
      return i18n("Warning");
    case Error:
      return i18n("Error");
    case Debug:
      return i18n("Debug");
    default:
      return i18n("Other");
  }    
}


QString KstDebug::text() {
  QMutexLocker ml(&_lock);
  // FIXME: this must be hard to internationalize
  QString body = i18n("Kst version %1\n\n\nKst log:\n").arg(KSTVERSION);
  
  for (unsigned i = 0; i < _messages.count(); i++ ) {
    body += i18n("%1 %2: %3\n").arg(_messages[i].date.toString()).arg(label(_messages[i].level)).arg(_messages[i].msg);
  }
  
  body += i18n("\n\nData-source plugins:");
  QStringList dsp = dataSourcePlugins();
  for (QStringList::ConstIterator it = dsp.begin(); it != dsp.end(); ++it) {
    body += '\n';
    body += *it;
  }
  body += "\n\n";
  return body;
}


void KstDebug::setLimit(bool applyLimit, int limit) {
  QMutexLocker ml(&_lock);
  _applyLimit = applyLimit;
  _limit = limit;
}


void KstDebug::sendEmail() {
  kapp->invokeMailer(QString::null, QString::null, QString::null, i18n("Kst Debugging Information"), text());
}


#include "kstdebug.moc"
// vim: ts=2 sw=2 et
