/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   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.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
* This file implements classes SKGError.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgerror.h"

QDBusArgument& operator<<(QDBusArgument& iArgument, const SKGError& iError)
{
    iArgument.beginStructure();
    iArgument << iError.getReturnCode() << iError.getMessage();
    iArgument.endStructure();
    return iArgument;
}
const QDBusArgument& operator>>(const QDBusArgument& iArgument, SKGError& iError)
{
    iArgument.beginStructure();
    int rc = 0;
    iArgument >> rc;
    iError.setReturnCode(rc);
    QString message;
    iArgument >> message;
    iError.setMessage(message);
    iArgument.endStructure();
    return iArgument;
}

QScriptValue SKGErrorToScriptValue(QScriptEngine* engine, SKGError* const& in)
{
    return engine->newQObject(in);
}

void SKGErrorFromScriptValue(const QScriptValue& object, SKGError* &out)
{
    out = qobject_cast<SKGError*>(object.toQObject());
}

SKGError::SKGError()
    : QObject(), m_rc(0), m_message(""), m_previousError(NULL)
{}

SKGError::SKGError(int iRc, const QString& iMessage)
    : QObject(), m_rc(iRc), m_message(iMessage), m_previousError(NULL)
{}

SKGError::SKGError(const SKGError& iError)
    : QObject()
{
    m_rc = iError.m_rc;
    m_message = iError.m_message;
    if (iError.m_previousError != NULL) m_previousError = new SKGError(*iError.m_previousError);
    else m_previousError = NULL;
}

SKGError::~SKGError()
{
    delete m_previousError;
    m_previousError = NULL;
}

const SKGError& SKGError::operator= (const SKGError& iError)
{
    if (&iError != this) {
        delete m_previousError;
        m_previousError = NULL;

        m_rc = iError.m_rc;
        m_message = iError.m_message;
        if (iError.m_previousError != NULL) m_previousError = new SKGError(*iError.m_previousError);
    }
    return *this;
}

bool SKGError::operator!() const
{
    return isSucceeded();
}

SKGError::operator bool() const
{
    return isFailed();
}

bool SKGError::isFailed() const
{
    return (m_rc > 0);
}

bool SKGError::isSucceeded() const
{
    return (m_rc <= 0);
}

bool SKGError::isWarning() const
{
    return (m_rc < 0);
}

int SKGError::getReturnCode() const
{
    return m_rc;
}

void SKGError::setReturnCode(int iReturnCode)
{
    m_rc = iReturnCode;
}

void SKGError::setMessage(const QString& iMessage)
{
    m_message = iMessage;
}

QString SKGError::getMessage() const
{
    return m_message;
}

QString SKGError::getFullMessage() const
{
    QString output('[');
    output += (m_rc == 0 ? "SUC" : (m_rc > 0 ? "ERR" : "WAR"));
    output += '-';

    QString tmp;
    tmp.setNum(m_rc);
    output += tmp;
    output += ']';
    if (!m_message.isEmpty()) output += ": " % m_message;
    return output;
}

QString SKGError::getFullMessageWithHistorical() const
{
    QString output = getFullMessage();
    if (m_previousError) output += '\n' % m_previousError->getFullMessageWithHistorical();
    return output;
}

int SKGError::getHistoricalSize() const
{
    int output = 0;
    if (m_previousError) output += 1 + m_previousError->getHistoricalSize();
    return output;
}

void SKGError::addError(int iRc, const QString& iMessage)
{
    SKGError* pe = new SKGError(*this);
    setReturnCode(iRc);
    setMessage(iMessage);
    delete m_previousError;
    m_previousError = pe;
}

void SKGError::addError(const SKGError& iError)
{
    addError(iError.getReturnCode(), iError.getMessage());
}

SKGError* SKGError::getPreviousError() const
{
    return m_previousError;
}

#include "skgerror.moc"
