/***************************************************************************
 *   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
 * A report class for document
 *
 * @author Stephane MANKOWSKI
 */
#include "skgreport.h"

#include <grantlee/engine.h>
#include <grantlee/templateloader.h>
#include <grantlee/qtlocalizer.h>
#include <grantlee/metatype.h>

#include <kaboutdata.h>
#include <kcolorscheme.h>

#include <qfile.h>
#include <qdir.h>
#include <qfont.h>
#include <qstandardpaths.h>
#include <qurl.h>
#include <qfontdatabase.h>

#include "skgtraces.h"
#include "skgdocument.h"
#include "skgobjectbase.h"

GRANTLEE_BEGIN_LOOKUP(SKGObjectBase)
Q_UNUSED(object);
Q_UNUSED(property);
GRANTLEE_END_LOOKUP

SKGReport::SKGReport(SKGDocument* iDocument)
    : QObject(), m_document(iDocument)
{
    SKGTRACEINFUNC(1);

    // Grantlee initialization
    Grantlee::registerMetaType<SKGObjectBase>();
}

SKGReport::~SKGReport()
{
    SKGTRACEINFUNC(1);
}

void SKGReport::setPeriod(const QString& iPeriod)
{
    m_cache["period"] = iPeriod;
}

QString SKGReport::getPeriod()
{
    QString month = m_cache["period"].toString();
    if (month.isEmpty()) {
        month = QDate::currentDate().toString("yyyy-MM");
        m_cache["period"] = month;
    }
    return month;
}

QString SKGReport::getPreviousPeriod()
{
    QString previousmonth = m_cache["previousperiod"].toString();
    if (previousmonth.isEmpty()) {
        QString period = getPeriod();
        if (!period.isEmpty()) {
            previousmonth = SKGServices::getNeighboringPeriod(period);
        }
        m_cache["previousperiod"] = previousmonth;
    }
    return previousmonth;
}

void SKGReport::addItemsInMapping(QVariantHash& iMapping)
{
    iMapping.insert("report", QVariant::fromValue<QObject*>(this));
    iMapping.insert("current_date", QDate::currentDate());
    KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
    iMapping.insert("color_negativetext", scheme.foreground(KColorScheme::NegativeText).color().name().right(6));
    iMapping.insert("color_positivetext", scheme.foreground(KColorScheme::PositiveText).color().name().right(6));
    iMapping.insert("color_neutraltext", scheme.foreground(KColorScheme::NeutralText).color().name().right(6));
    iMapping.insert("color_normaltext", scheme.foreground(KColorScheme::NormalText).color().name().right(6));
    iMapping.insert("color_inactivetext", scheme.foreground(KColorScheme::InactiveText).color().name().right(6));
    iMapping.insert("color_activetext", scheme.foreground(KColorScheme::ActiveText).color().name().right(6));
    iMapping.insert("color_linktext", scheme.foreground(KColorScheme::LinkText).color().name().right(6));
    iMapping.insert("color_visitedtext", scheme.foreground(KColorScheme::VisitedText).color().name().right(6));
    iMapping.insert("color_normalbackground", scheme.background(KColorScheme::NormalBackground).color().name().right(6));
    iMapping.insert("color_activebackground", scheme.background(KColorScheme::ActiveBackground).color().name().right(6));

    QFont generalFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
    iMapping.insert("font_family", generalFont.family());
}

SKGError SKGReport::getReportFromTemplate(SKGReport* iReport, const QString& iFile, QString& oHtml)
{
    SKGError err;
    SKGTRACEINFUNCRC(10, err);
    SKGDocument* doc = (iReport ? static_cast<SKGDocument*>(iReport->m_document) : NULL);

    // Prepare grantlee engine
    Grantlee::Engine gEngine;
    gEngine.addDefaultLibrary("grantlee_skgfilters");

    QSharedPointer<Grantlee::FileSystemTemplateLoader> gLoader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(new Grantlee::FileSystemTemplateLoader());
    gLoader->setTemplateDirs(QStringList(QFileInfo(iFile).dir().absolutePath()));
    gEngine.addTemplateLoader(gLoader);

    Grantlee::Template gTemplate = gEngine.loadByName(QFileInfo(iFile).fileName());

    QVariantHash mapping;
    if (iReport) {
        iReport->addItemsInMapping(mapping);
    }
    if (doc) {
        mapping.insert("document", QVariant::fromValue<QObject*>(doc));
    }

    QString dir = "file://" % QFileInfo(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kf5/infopage/kde_infopage.css")).dir().absolutePath() % '/';
    {
        QFile file(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kf5/infopage/kde_infopage.css"));
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            mapping.insert("kde_infopage_css", QString(file.readAll()).replace("url(", "url(" % dir));
        }
    }

    KAboutData about = KAboutData::applicationData();
    mapping.insert("about_welcome", i18nc("Welcome message", "Welcome to %1", about.displayName()));
    mapping.insert("about_programname", about.displayName());
    mapping.insert("about_version", about.version());
    mapping.insert("about_bugaddress", about.bugAddress());
    mapping.insert("about_copyrightstatement", about.copyrightStatement());
    mapping.insert("about_homepage", about.homepage());
    mapping.insert("about_shortdescription", about.shortDescription());
    mapping.insert("about_othertext", about.otherText());
    Grantlee::Context gContext(mapping);

    // Generation
    {
        SKGTRACEINFUNCRC(10, err);
        oHtml = gTemplate->render(&gContext);
        if (gTemplate->error()) {
            err = SKGError(gTemplate->error(), gTemplate->errorString());
        }
    }
    return err;
}


