/***************************************************************************
 *   Copyright (C) 2010 by SIDDHARTH SHARMA siddharth.kde@gmail.com        *
 *                                                                         *
 *   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 Plasma Applet for Account Skroogoid
*
* @author Siddharth SHARMA
* @author Guillaume DE BURE
*/

#include "accountskroogoid.h"

#include "skgtraces.h"
#include "skgdocumentbank.h"
#include "skgservices.h"
#include "skgmainpanel.h"

#include <QGraphicsLinearLayout>
#include <QGraphicsGridLayout>

#include <KPushButton>
#include <Plasma/ToolButton>
#include <Plasma/Frame>
#include <KMessageBox>
#include <QGraphicsScene>

AccountSkroogoid::AccountSkroogoid(QObject* iParent, const QVariantList& args)
    : Plasma::Applet(iParent, args)
{
    // This signalMapper will be used to open the account tab when clicking on the
    // corresponding button
    signalMapper = new QSignalMapper(this);
    connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(openAccountTab(QString)));
}

void AccountSkroogoid::init()
{
    // This is the layout for the whole widget
    widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
    setLayout(widgetLayout);

    Plasma::DataEngine* engine = dataEngine("skgdataengine");
    if (engine->isValid())  engine->connectSource("Accounts", this);
}


AccountSkroogoid::~AccountSkroogoid()
{}

void AccountSkroogoid::dataUpdated(const QString& sourceName, const Plasma::DataEngine::Data& engineData)
{
    if (sourceName != "Accounts") return;
    SKGTRACEIN(1, "AccountSkroogoid::dataUpdated");
    QHash<QString, QVariantHash> listData;
    for (int i = 0 ; i < engineData.keys().count() ; ++i) {
        const QString accountName = engineData.keys().at(i);
        QVariant accountValuesVariant = engineData.value(accountName);
        QVariantHash accountValues = accountValuesVariant.toHash();

        listData[accountName] = accountValues;
    }

    // Get the current document
    SKGMainPanel* panel = SKGMainPanel::getMainPanel();
    doc = qobject_cast<SKGDocumentBank*> (panel->getDocument());

    // Get the primary unit
    SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();

    // Initialisation
    int nb = widgetLayout->count();
    for (int i = 0; widgetLayout && i < nb; ++i) {
        QGraphicsLayoutItem* item = widgetLayout->itemAt(0);
        if (item) {
            widgetLayout->removeItem(item);
            delete item;
        }
    }

    // Create a QHash containing pointers to layouts
    // There is one layout for each unit type.
    // This will allow grouping units per unit type
    QHash<QString, QGraphicsGridLayout*> typeLayout;

    // Create a QHash for storing sums per account type
    QHash<QString, double> valuePerType;

    nb = listData.count();
    for (int i = 0; i < nb; ++i) {
        // Account name
        QString account = listData.keys().at(i);

        QVariantHash values = listData[account];

        // Account type
        QString type = values["type"].toString();

        // Amount of money
        double v1 = values["amount"].toDouble();

        // Account closed
        bool closed = (values["closed"] == "Y");


        // Display different sections depending on account types
        if (!typeLayout.contains(type) && !closed) {

            Plasma::Frame* typeFrame = new Plasma::Frame();
            widgetLayout->addItem(typeFrame);
            typeFrame->setFrameShadow(Plasma::Frame::Raised);

            QGraphicsLinearLayout* frameLayout = new QGraphicsLinearLayout(Qt::Vertical);
            typeFrame->setLayout(frameLayout);

            Plasma::Label* typeLabel = new Plasma::Label();
            typeLabel->setText(type);
            QFont headerFont = typeLabel->font();
            headerFont.setBold(true);
            typeLabel->setFont(headerFont);
            frameLayout->addItem(typeLabel);

            // Create a Grid Layout, and store it in the hash
            typeLayout[type] = new QGraphicsGridLayout();
            frameLayout->addItem(typeLayout[type]);

            // Initiate the sum for this account type
            valuePerType[type] = 0;
        }

        if (!closed) {

            QGraphicsGridLayout* thisTypeLayout = typeLayout[type];
            int row = thisTypeLayout->rowCount();

            // Create a button for the account.
            Plasma::ToolButton* button = new Plasma::ToolButton();
            button->setText(account);
            thisTypeLayout->addItem(button, row, 0);

            // Open the account in a new tab when clicking on the account
            connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
            signalMapper->setMapping(button, account);

            // Create a label for the amount
            Plasma::Label* amountLabel = new Plasma::Label();
            amountLabel->setText(doc->formatMoney(v1, primary));
            amountLabel->setAlignment(Qt::AlignRight);
            thisTypeLayout->addItem(amountLabel, row, 1);

            // Add the account value to the sum per type
            valuePerType[type] = valuePerType[type] + v1;
        }
    }

    for (int i = 0 ; i < valuePerType.count() ; ++i) {
        QString type = valuePerType.keys().at(i);
        QGraphicsGridLayout* thisTypeLayout = typeLayout[type];
        int row = thisTypeLayout->rowCount();

        // The label for the string "Total"
        Plasma::Label* totalLabel = new Plasma::Label();
        totalLabel->setText(i18nc("Noun, the total is a sum of numerical values", "Total"));
        QFont totalLabelFont = totalLabel->font();
        totalLabelFont.setBold(true);
        totalLabel->setFont(totalLabelFont);
        thisTypeLayout->addItem(totalLabel, row, 0);

        // The total value for the account type
        Plasma::Label* valueLabel = new Plasma::Label();
        valueLabel->setText(doc->formatMoney(valuePerType[type], primary));
        valueLabel->setAlignment(Qt::AlignRight);
        thisTypeLayout->addItem(valueLabel, row, 1);
    }

    widgetLayout->addStretch(20);
}

void AccountSkroogoid::openAccountTab(QString accountName)
{
    // And finally, open a new tab for this account
    SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/?account=" % SKGServices::encodeForUrl(accountName));
}

#include "accountskroogoid.moc"
