/***************************************************************************
 *   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/>  *
 ***************************************************************************/
#ifndef SKGERROR_H
#define SKGERROR_H
/** @file
 * This file defines classes SKGError and macros.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgbasemodeler_export.h"
#include "skgdefine.h"

#include <QString>
#include <QObject>
#include <QDBusArgument>
#include <qscriptvalue.h>
#include <qscriptengine.h>
/**
* This class manages errors
*/
class SKGBASEMODELER_EXPORT SKGError : public QObject
{
    Q_OBJECT;
    Q_CLASSINFO("D-Bus Interface", "org.skrooge.SKGError");
    /**
     * Return code of the error
     */
    Q_PROPERTY(int returnCode READ getReturnCode WRITE setReturnCode);
    /**
     * Message of the error
     */
    Q_PROPERTY(QString message READ getMessage WRITE setMessage);
    /**
     * Full message of the error
     */
    Q_PROPERTY(QString message READ getFullMessageWithHistorical);
    /**
     * To know if it is a success of the error
     */
    Q_PROPERTY(bool succeeded READ isSucceeded);
    /**
     * To know if it is a failure of the error
     */
    Q_PROPERTY(bool failed READ isFailed);
public:
    /**
    * Constructor
    */
    SKGError();

    /**
    * Copy constructor
    * @param iError the error to copy
    */
    SKGError(const SKGError& iError);

    /**
    * Constructor
    * @param iRc the error code
    * @param iMessage the error message
    */
    SKGError(int iRc, const QString& iMessage);

    /**
    * Destructor
    */
    virtual ~SKGError();

    /**
    * Operator affectation
    * @param iError the error to copy
    */
    const SKGError& operator= (const SKGError& iError);

    /**
    * To know if this is an error or not. Equivalent to @see isSucceeded
    * @return true or false
    */
    virtual bool operator!() const;

    /**
    * To know if this is an error or not. Equivalent to @see isFailed
    * @return true or false
    */
    virtual operator bool() const;

public slots:
    /**
    * To know if it's an error or not
    * @return true: It's an error
    *         false: It's not an error (it could be a warning)
    */
    virtual bool isFailed() const;

    /**
    * To know if it's an error or not
    * @return true: It's not an error (it could be a warning)
    *         false: It's an error
    */
    virtual bool isSucceeded() const;

    /**
    * To know if it's a warning or not
    * @return true: It's a warning
    *         false: It's not a warning
    */
    virtual bool isWarning() const;

    /**
    * Return the return code associated to this error
    * @return 0 : It's not an error (SUCCEEDED)
    *         <0: It's just a warning (SUCCEEDED)
    *         >0: It's not error (FAILED)
    */
    virtual int getReturnCode() const;

    /**
    * Set the return code associated to this error
    * @param iReturnCode the return code
    *         0 : It's not an error (SUCCEEDED)
    *         <0: It's just a warning (SUCCEEDED)
    *         >0: It's not error (FAILED)
    */
    virtual void setReturnCode(int iReturnCode);

    /**
    * Set the message associated to this error
    * @param iMessage the message
    */
    virtual void setMessage(const QString&   iMessage);

    /**
    * Return the message associated to this error
    * @return the message
    */
    virtual QString getMessage() const;

    /**
    * Return the full message associated to this error
    * @return the full message
    */
    virtual QString getFullMessage() const;

    /**
    * Return the full message with historical associated to this error
    * @return the full message
    */
    virtual QString getFullMessageWithHistorical() const;

    /**
     * Return the size of the historical associated to this error
     * @return the size
     */
    virtual int getHistoricalSize() const;

    /**
    * Add a new historical message to the current error.
    * @param iRc the error code
    * @param iMessage the error message
    */
    virtual void addError(int iRc, const QString& iMessage);

    /**
    * Add a new historical message to the current error.
    * @param iError the error
    */
    virtual void addError(const SKGError& iError);

    /**
    * Return previous error associated to this SKGError in the historical
    * @return previous error (null if not exist)
    * WARNING: this pointer mustn't be deleted
    */
    virtual SKGError* getPreviousError() const;

private:
    /**
    * the return code of the error
    *         0 : It's not an error (SUCCEEDED)
    *         <0: It's just a warning (SUCCEEDED)
    *         >0: It's not error (FAILED)
    */
    int m_rc;

    /**
     * the message of the error
     */
    QString m_message;

    /**
     * the previous error on this branch
     */
    SKGError* m_previousError;
};
/**
 * Declare the class
 */
Q_DECLARE_TYPEINFO(SKGError, Q_MOVABLE_TYPE);

/**
 * Declare the meta type
 */
Q_DECLARE_METATYPE(SKGError);

/**
 * Declare the meta type
 */
Q_DECLARE_METATYPE(SKGError*);

/**
* Function for scription
* @param engine the engine
* @param in the object
* @return the value
*/
SKGBASEMODELER_EXPORT QScriptValue SKGErrorToScriptValue(QScriptEngine* engine, SKGError* const& in);

/**
* Function for scription
* @param object the object
* @param out the object
*/
SKGBASEMODELER_EXPORT void SKGErrorFromScriptValue(const QScriptValue& object, SKGError* &out);

/**
* Operator <<
* @param iArgument the DBus argument
* @param iError the error
*/
SKGBASEMODELER_EXPORT QDBusArgument& operator<<(QDBusArgument& iArgument, const SKGError& iError);

/**
* Operator >>
* @param iArgument the DBus argument
* @param iError the error
*/
SKGBASEMODELER_EXPORT const QDBusArgument& operator>>(const QDBusArgument& iArgument, SKGError& iError);

#endif //SKGERROR_H
