/***************************************************************************
 *   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 Bank Skroogoid
*
* @author Siddharth SHARMA
* @author Guillaume DE BURE
*/

#include "bankskroogoid.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>

BankSkroogoid::BankSkroogoid(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 BankSkroogoid::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);
    }
}


BankSkroogoid::~BankSkroogoid()
{}

void BankSkroogoid::dataUpdated(const QString& sourceName, const Plasma::DataEngine::Data& engineData)
{
    if (sourceName != "Accounts") {
        return;
    }
    SKGTRACEINFUNC(1);
    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 bank
    QHash<QString, QGraphicsGridLayout*> bankLayout;

    // Create a QHash for storing sums per Bank
    QHash<QString, double> valuePerBank;

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

        QVariantHash values = listData[account];

        // Bank
        QString bank = values["bank"].toString();

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

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


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

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

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

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

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

            // Initiate the sum for this bank
            valuePerBank[bank] = 0;
        }

        if (!closed) {

            QGraphicsGridLayout* thisBankLayout = bankLayout[bank];
            int row = thisBankLayout->rowCount();

            // Create a button for the account.
            Plasma::ToolButton* button = new Plasma::ToolButton();
            button->setText(account);
            thisBankLayout->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);
            thisBankLayout->addItem(amountLabel, row, 1);

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

    for (int i = 0 ; i < valuePerBank.count() ; ++i) {
        QString bank = valuePerBank.keys().at(i);
        QGraphicsGridLayout* thisBankLayout = bankLayout[bank];
        int row = thisBankLayout->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);
        thisBankLayout->addItem(totalLabel, row, 0);

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

    widgetLayout->addStretch(20);
}

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

#include "bankskroogoid.moc"

