/***************************************************************************
 *   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 is Skrooge plugin to generate report.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgreportplugin.h"
#include "skgreportpluginwidget.h"
#include "skgtraces.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgaccountobject.h"
#include "skgcategoryobject.h"
#include "skgtrackerobject.h"
#include "skgunitobject.h"
#include "skgruleobject.h"
#include "skgpayeeobject.h"
#include "skgnodeobject.h"
#include "skgreportboardwidget.h"
#include "skgdocumentbank.h"
#include "skgreport_settings.h"

#include <kaction.h>
#include <kactioncollection.h>
#include <kaboutdata.h>
#include <kgenericfactory.h>

#include <QDomDocument>

/**
 * This plugin factory.
 */
K_PLUGIN_FACTORY(SKGReportPluginFactory, registerPlugin<SKGReportPlugin>();)
/**
 * This plugin export.
 */
K_EXPORT_PLUGIN(SKGReportPluginFactory("skrooge_report", "skrooge_report"))

SKGReportPlugin::SKGReportPlugin(QWidget* /*iWidget*/, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent)
{
    SKGTRACEIN(10, "SKGReportPlugin::SKGReportPlugin");
}

SKGReportPlugin::~SKGReportPlugin()
{
    SKGTRACEIN(10, "SKGReportPlugin::~SKGReportPlugin");
    m_currentBankDocument = NULL;
    m_openReportAction = NULL;
}

bool SKGReportPlugin::setupActions(SKGDocument* iDocument, const QStringList& iArgument)
{
    SKGTRACEIN(10, "SKGReportPlugin::setupActions");
    Q_UNUSED(iArgument);
    m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
    if (m_currentBankDocument == NULL) return false;

    setComponentData(KGlobal::mainComponent());
    setXMLFile("../skrooge_report/skrooge_report.rc");

    //Menu
    QStringList overlayopen;
    overlayopen.push_back("skg_open");
    m_openReportAction = new KAction(KIcon("view-investment", NULL, overlayopen), i18nc("Verb", "Open report..."), this);
    connect(m_openReportAction, SIGNAL(triggered(bool)), this, SLOT(onOpenReport()));
    m_openReportAction->setShortcut(Qt::META + Qt::Key_R);
    registerGlobalAction("open_report", m_openReportAction);

    //---------------
    KAction* act = new KAction(KIcon("security-low", NULL, overlayopen), i18nc("Verb", "Open very old operations..."), this);
    act->setData(QString("skg://skrooge_operation_plugin/?title_icon=security-low&title=" %
                         SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Very old operations")) %
                         "&operationWhereClause=" % SKGServices::encodeForUrl("d_date<=(SELECT date('now', '-50 year')) AND d_date<>'0000-00-00'")));
    connect(act, SIGNAL(triggered(bool)), SKGMainPanel::getMainPanel(), SLOT(openPage()));
    registerGlobalAction("view_open_very_old_operations", act);
    return true;
}

void SKGReportPlugin::refresh()
{
    SKGTRACEIN(10, "SKGReportPlugin::refresh");
    if (SKGMainPanel::getMainPanel()) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();

        if (selection.count() > 0) {
            QString table = selection.at(0).getRealTable();
            bool onOperation = (table == "operation" || table == "account" || table == "unit" || table == "category" || table == "refund" || table == "payee" || table == "rule");
            if (m_openReportAction) m_openReportAction->setEnabled(onOperation);
        } else {
            if (m_openReportAction) m_openReportAction->setEnabled(false);
        }
    }
}

int SKGReportPlugin::getNbDashboardWidgets()
{
    return 1;
}

QString SKGReportPlugin::getDashboardWidgetTitle(int iIndex)
{
    if (iIndex == 0) return i18nc("Noun, the title of a section", "Report");
    return "";
}

SKGBoardWidget* SKGReportPlugin::getDashboardWidget(int iIndex)
{
    if (iIndex == 0) return new SKGReportBoardWidget(m_currentBankDocument);
    return NULL;
}

SKGTabPage* SKGReportPlugin::getWidget()
{
    SKGTRACEIN(10, "SKGReportPlugin::getWidget");
    return new SKGReportPluginWidget(m_currentBankDocument);
}

QWidget* SKGReportPlugin::getPreferenceWidget()
{
    SKGTRACEIN(10, "SKGReportPlugin::getPreferenceWidget");
    QWidget* widget = new QWidget();
    ui.setupUi(widget);
    return widget;
}

KConfigSkeleton* SKGReportPlugin::getPreferenceSkeleton()
{
    return skgreport_settings::self();
}

QString SKGReportPlugin::title() const
{
    return i18nc("Noun", "Report");
}

QString SKGReportPlugin::icon() const
{
    return "view-investment";
}

QString SKGReportPlugin::toolTip() const
{
    return i18nc("Noun", "Generate report");
}

int SKGReportPlugin::getOrder() const
{
    return 40;
}

QStringList SKGReportPlugin::tips() const
{
    QStringList output;
    output.push_back(i18nc("Description of a tips", "<p>... you can double click on a value in '%1' to show corresponding operations.</p>", title()));
    output.push_back(i18nc("Description of a tips", "<p>... you can open reports for selections made in other pages.</p>"));
    output.push_back(i18nc("Description of a tips", "<p>... you can export reports in many formats.</p>"));
    return output;
}

bool SKGReportPlugin::isInPagesChooser() const
{
    return true;
}

void SKGReportPlugin::onOpenReport()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGReportPlugin::onOpenReport", err);
    if (SKGMainPanel::getMainPanel()) {
        SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();

        int nb = selection.count();
        if (nb > 0) {
            QString wc;
            QString title;
            QString table = selection.at(0).getRealTable();
            if (table == "account") {
                wc = "rd_account_id in (";
                title = i18nc("Noun, a list of items", "Operations of account ");

                for (int i = 0; i < nb; ++i) {
                    SKGAccountObject tmp(selection.at(i));
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += SKGServices::intToString(tmp.getID());
                    title += i18n("'%1'", tmp.getName());
                }
                wc += ')';
            } else if (table == "unit") {
                wc = "rc_unit_id in (";
                title = i18nc("Noun, a list of items", "Operations with Unit equal to ");

                for (int i = 0; i < nb; ++i) {
                    SKGUnitObject tmp(selection.at(i));
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += SKGServices::intToString(tmp.getID());
                    title += i18n("'%1'", tmp.getName());
                }
                wc += ')';
            } else if (table == "category") {
                wc = "t_REALCATEGORY in (";
                QString wc2;
                title = i18nc("Noun, a list of items", "Operations with Category equal to ");

                for (int i = 0; i < nb; ++i) {
                    SKGCategoryObject tmp(selection.at(i));
                    if (i) {
                        wc += ',';
                        wc2 += " OR ";
                        title += ',';
                    }
                    wc += '\'' % SKGServices::stringToSqlString(tmp.getFullName()) % '\'';
                    wc2 += "t_REALCATEGORY like '" % SKGServices::stringToSqlString(tmp.getFullName()) % "%'";
                    title += i18n("'%1'", tmp.getFullName());
                }
                wc += ") OR " % wc2;
            } else if (table == "refund") {
                wc = "r_refund_id in (";
                title = i18nc("Noun, a list of items", "Operations followed by ");

                for (int i = 0; i < nb; ++i) {
                    SKGTrackerObject tmp(selection.at(i));
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += SKGServices::intToString(tmp.getID());
                    title += i18n("'%1'", tmp.getName());
                }
                wc += ')';
            } else if (table == "payee") {
                wc = "r_payee_id in (";
                title = i18nc("Noun, a list of items", "Operations assigned to ");

                for (int i = 0; i < nb; ++i) {
                    SKGPayeeObject tmp(selection.at(i));
                    if (i) {
                        wc += ',';
                        title += ',';
                    }
                    wc += SKGServices::intToString(tmp.getID());
                    title += i18n("'%1'", tmp.getName());
                }
                wc += ')';
            } else if (table == "operation") {
                wc = "id in (";
                title = i18nc("Noun, a list of items", "Selected operations");

                for (int i = 0; i < nb; ++i) {
                    if (i) {
                        wc += ',';
                    }
                    wc += SKGServices::intToString(selection.at(i).getID());
                }
                wc += ')';
            } else if (table == "rule") {
                title = i18nc("Noun, a list of items", "Operations corresponding to rule ");

                for (int i = 0; i < nb; ++i) {
                    SKGRuleObject tmp(selection.at(i));
                    QString ruleWc = tmp.getSelectSqlOrder();
                    if (!ruleWc.isEmpty()) {
                        if (!wc.isEmpty()) {
                            wc += " OR ";
                            title += ',';
                        }
                        wc += '(' % ruleWc % ')';
                        title += i18n("'%1'", tmp.getSearchDescription());
                    }
                }
            }

            //Call report plugin
            SKGMainPanel::getMainPanel()->openPage("skg://skrooge_report_plugin/?period=0&title_icon=" % icon() % "&title=" % SKGServices::encodeForUrl(title) % "&operationWhereClause=" % SKGServices::encodeForUrl(wc));
        }
    }
}

SKGAdviceList SKGReportPlugin::advice(const QStringList& iIgnoredAdvice)
{
    SKGTRACEIN(10, "SKGReportPlugin::advice");
    SKGAdviceList output;

    //Very old operation
    if (!iIgnoredAdvice.contains("skgreportplugin_veryold")) {
        bool exist = false;
        m_currentBankDocument->existObjects("operation", "d_date<=(SELECT date('now', '-50 year')) AND d_date<>'0000-00-00'", exist);
        if (exist) {
            SKGAdvice ad;
            ad.setUUID("skgreportplugin_veryold");
            ad.setPriority(3);
            ad.setShortMessage(i18nc("Advice on making the best (short)", "Some operations are very old"));
            ad.setLongMessage(i18nc("Advice on making the best (long)", "For performances reasons, very old operations are not taken into account in graph report. Check if these operations are normal."));
            QStringList autoCorrections;
            autoCorrections.push_back("skg://view_open_very_old_operations");
            ad.setAutoCorrections(autoCorrections);
            output.push_back(ad);
        }
    }
    return output;
}

#include "skgreportplugin.moc"
