/***************************************************************************
 *   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 Shares & Indexes Skroogoid
*
* @author Siddharth SHARMA
*/
#include "unitskroogoid.h"

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

#include <QGraphicsLinearLayout>
#include <KMessageBox>
#include <QGraphicsGridLayout>
#include <QGraphicsScene>
#include <Plasma/Frame>
#include <Plasma/ToolButton>

UnitSkroogoid::UnitSkroogoid(QObject* iParent, const QVariantList& args)
    : Plasma::Applet(iParent, args), doc(NULL), widgetLayout(NULL)
{}

void UnitSkroogoid::init()
{
    // This is the widget Layout
    if (widgetLayout == NULL) {
        widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
        setLayout(widgetLayout);

        // Load the dataengine that contains data we need
        Plasma::DataEngine* engine = dataEngine("skgdataengine");
        if (engine->isValid()) {
            engine->connectSource("Units", this);
        }
    }
}

UnitSkroogoid::~UnitSkroogoid()
{}

void UnitSkroogoid::dataUpdated(const QString& sourceName, const Plasma::DataEngine::Data& engineData)
{
    if (sourceName != "Units") {
        return;
    }
    SKGTRACEINFUNC(1);
    // Get the current document
    SKGMainPanel* panel = SKGMainPanel::getMainPanel();
    doc = qobject_cast<SKGDocumentBank*> (panel->getDocument());

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

    QHash<QString, QStringList> listData;
    for (int i = 0 ; i < engineData.keys().count() ; ++i) {
        QString unitId = engineData.keys().at(i);
        QVariant unitValuesVariant = engineData.value(unitId);
        QStringList unitValues = unitValuesVariant.value<QStringList>();

        listData[unitId] = unitValues;
    }

    // Refresh
    // Create a QHash containing pointers to layouts
    // There is one layout for each unit type.
    // This will allow grouping units per unit type

    // 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;
        }
    }
    QHash<QString, QGraphicsGridLayout*> typeLayout;
    nb = listData.count();
    for (int i = 0; i < nb; ++i) {
        // Operation id
        QString id = listData.keys().at(i);
        // FIXME: Since the keys() methods returns keys in
        // an arbitrary order, we lose the order by unit type
        // that allows grouping units by type.
        // Need to do that manually


        QStringList values = listData[id];

        // Name
        QString name = values.at(0);

        // Symbol
        QString symbol = values.at(1);

        // Amount
        double amount = SKGServices::stringToDouble(values.at(2));

        // Type
        QString type = values.at(3);

        // Daily change
        QString dailyChange = values.at(4);


        // If this is a new type, add a header line with the type
        if (!typeLayout.contains(type)) {

            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]);
        }

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

        if (row > 0) {
            thisTypeLayout->setRowStretchFactor(row - 1, 0);
        }

        thisTypeLayout->setRowStretchFactor(row, 1);

        Plasma::ToolButton* button = new Plasma::ToolButton();
        button->setText(name);
        thisTypeLayout->addItem(button, row, 0);
        connect(button, SIGNAL(clicked()), this, SLOT(openUnitTab()));

        Plasma::Label* amountLabel = new Plasma::Label();
        amountLabel->setText(doc->formatMoney(amount, primary));
        thisTypeLayout->addItem(amountLabel, row, 3);
        amountLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

        Plasma::Label* dailyChangeLabel = new Plasma::Label();
        dailyChangeLabel->setText("(" % dailyChange % ")");
        thisTypeLayout->addItem(dailyChangeLabel, row, 4);
        dailyChangeLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

        // Increment row number
        row++;
    }

    // Add a spacer for visual clarity
    widgetLayout->addStretch(2);
}

void UnitSkroogoid::openUnitTab()
{
    // And finally, open a new tab for units
    SKGMainPanel::getMainPanel()->openPage("skg://skrooge_unit_plugin");
}

#include "unitskroogoid.moc"
