/***************************************************************************
 *   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 for bank management.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgbankpluginwidget.h"

#include <KStandardDirs>
#include <KMessageBox>
#include <KFileDialog>

#include <QDomDocument>
#include <QFile>
#include <QDir>
#include <QKeyEvent>

#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgtransactionmng.h"
#include "skgunitobject.h"
#include "skgunitvalueobject.h"
#include "skgbankobject.h"
#include "skgdocumentbank.h"
#include "skgtraces.h"
#include "skginterfaceplugin.h"
#include "skgtablewithgraph.h"
#include "skgboardwidget.h"

SKGBankPluginWidget::SKGBankPluginWidget(SKGDocumentBank* iDocument)
    : SKGTabPage(iDocument)
{
    SKGTRACEIN(10, "SKGBankPluginWidget::SKGBankPluginWidget");
    if (!iDocument) return;

    ui.setupUi(this);

    // Add report
    SKGInterfacePlugin* reportPlugin = SKGMainPanel::getMainPanel()->getPluginByName("Skrooge report plugin");
    if (reportPlugin) {
        m_graph = reportPlugin->getDashboardWidget(0);
        if (m_graph) {
            // To avoid hidden page when no account exist
            QWidget* w = new QWidget(this);
            QVBoxLayout* verticalLayout = new QVBoxLayout(w);
            verticalLayout->addWidget(m_graph);

            m_graph->hideTitle();

            ui.verticalLayout->insertWidget(2, w);
            // Set initial state
            m_graph->hide();

            QDomDocument doc1("SKGML");
            QDomElement root1 = doc1.createElement("parameters");
            doc1.appendChild(root1);

            root1.setAttribute("period", "0");
            root1.setAttribute("columns", "d_DATEMONTH");
            root1.setAttribute("mode", "1");
            root1.setAttribute("currentPage", "-2");

            {
                QDomDocument doc2("SKGML");
                QDomElement root2 = doc2.createElement("parameters");
                doc2.appendChild(root2);
                root2.setAttribute("graphMode", SKGServices::intToString(static_cast<int>(SKGTableWithGraph::LINE)));

                {
                    QDomDocument doc3("SKGML");
                    QDomElement root3 = doc3.createElement("parameters");
                    doc3.appendChild(root3);
                    root3.setAttribute("isToolBarVisible", "N");

                    root2.setAttribute("graphicViewState", doc3.toString());
                }

                root1.setAttribute("tableAndGraphState", doc2.toString());
            }
            m_graph->setState(doc1.toString());


            m_timer2.setSingleShot(true);
            connect(&m_timer2, SIGNAL(timeout()), this, SLOT(onRefreshGraph()), Qt::QueuedConnection);
            m_timer2.start(300);

            connect(ui.kView->getShowWidget(), SIGNAL(stateChanged()), &m_timer2, SIGNAL(timeout()));
        }
    }

    // Set label titles
    ui.kAccountLbl->setText(i18n("%1:", iDocument->getDisplay("t_ACCOUNT")));
    ui.kTypeLbl->setText(i18n("%1:", iDocument->getDisplay("t_type")));
    ui.kBankNumberLbl->setText(i18n("%1:", iDocument->getDisplay("t_bank_number")));
    ui.kAgencyNumberLbl->setText(i18n("%1:", iDocument->getDisplay("t_agency_number")));
    ui.kNumberLbl->setText(i18n("%1:", iDocument->getDisplay("i_number")));
    ui.kAgencyAddressLbl->setText(i18n("%1:", iDocument->getDisplay("t_agency_address")));
    ui.kMaxLimit->setText(i18n("%1:", iDocument->getDisplay("f_maxamount")));
    ui.kMinLimit->setText(i18n("%1:", iDocument->getDisplay("f_minamount")));
    ui.kCommentLabel->setText(i18n("%1:", iDocument->getDisplay("t_comment")));

    ui.kUnitEdit->setDocument(iDocument);

    // Set show widget
    ui.kView->getShowWidget()->addGroupedItem("all", i18n("All"));
    ui.kView->getShowWidget()->addGroupedItem("opened", i18n("Opened"), "", "t_close='N'");
    ui.kView->getShowWidget()->addGroupedItem("closed", i18n("Closed"), "dialog-close", "t_close='Y'");
    ui.kView->getShowWidget()->addGroupedItem("highlighted", i18n("Highlighted only"), "bookmarks", "t_bookmarked='Y'");
    if (m_graph) {
        ui.kView->getShowWidget()->addSeparator();
        ui.kView->getShowWidget()->addItem("graph", i18n("Graph"), "view-investment", "1=0");
    }

    ui.kView->getShowWidget()->setDefaultState("opened");

    m_timer.setSingleShot(true);
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(refreshInfoZone()), Qt::QueuedConnection);

    // Add Standard KDE Icons to buttons to Accounts
    ui.kAccountCreatorUpdate->setIcon(KIcon("dialog-ok-apply"));
    ui.kAccountCreatorAdd->setIcon(KIcon("list-add"));

    SKGWidgetSelector::SKGListQWidget list;
    list.push_back(ui.SKGEditionWidget);
    list.push_back(ui.SKGEditionButtonswidget);
    ui.kWidgetSelector->addButton(KIcon("configure"), i18n("Edit"), i18n("Display the account edit panel"), list);

    // Add NLS values for type of account
    // C=current D=credit card P=passif (for objects) I=Investment O=other
    ui.kAccountCreatorType->addItem(KIcon("view-bank-account-savings"), i18nc("Noun, a type of account", "Current"), SKGAccountObject::CURRENT);
    ui.kAccountCreatorType->addItem(KIcon("view-credit-card-account"), i18nc("Noun, a type of account", "Credit card"), SKGAccountObject::CREDITCARD);
    ui.kAccountCreatorType->addItem(KIcon("view-bank-account-savings"), i18nc("Noun, a type of account", "Saving"), SKGAccountObject::SAVING);
    ui.kAccountCreatorType->addItem(KIcon("view-stock-account"), i18nc("Noun, a type of account", "Investment"), SKGAccountObject::INVESTMENT);
    ui.kAccountCreatorType->addItem(KIcon("view-loan-asset"), i18nc("Noun, a type of account", "Assets"), SKGAccountObject::ASSETS);
    ui.kAccountCreatorType->addItem(KIcon("view-loan-asset"), i18nc("Noun, a type of account", "Loan"), SKGAccountObject::LOAN);
    ui.kAccountCreatorType->addItem(KIcon("view-loan-asset"), i18nc("Noun, a type of account", "Pension"), SKGAccountObject::PENSION);
    ui.kAccountCreatorType->addItem(KIcon("kwalletmanager"), i18nc("Noun, a type of account", "Wallet"), SKGAccountObject::WALLET);
    ui.kAccountCreatorType->addItem(i18nc("Noun, a type of account", "Other"), SKGAccountObject::OTHER);

    // Bind account creation view
    ui.kView->setModel(new SKGObjectModel(static_cast<SKGDocumentBank*>(getDocument()), "v_account_display", "1=0", this, "", false));

    // Add registered global action in contextual menu
    if (SKGMainPanel::getMainPanel()) {
        ui.kView->getView()->insertGlobalAction();
        ui.kView->getView()->insertGlobalAction("open");
        ui.kView->getView()->insertGlobalAction("open_report");
        ui.kView->getView()->insertGlobalAction("edit_find");
        ui.kView->getView()->insertGlobalAction();
        ui.kView->getView()->insertGlobalAction("edit_delete");
        ui.kView->getView()->insertGlobalAction();
        ui.kView->getView()->insertGlobalAction("edit_switch_highlight");
        ui.kView->getView()->insertGlobalAction("edit_reconciliate");
    }
    connect(ui.kView->getView(), SIGNAL(clickEmptyArea()), this, SLOT(cleanEditor()));
    connect(ui.kView->getView(), SIGNAL(doubleClicked(QModelIndex)), SKGMainPanel::getMainPanel()->getGlobalAction("open"), SLOT(trigger()));
    connect(ui.kView->getView(), SIGNAL(selectionChangedDelayed()), this, SLOT(onSelectionChanged()));

    // Search file list
    QString listIconFile = KStandardDirs::locate("data", "skrooge/images/logo/l10n/" % KGlobal::locale()->country() % "/list_bank.txt");
    if (listIconFile.isEmpty()) listIconFile = KStandardDirs::locate("data", "skrooge/images/logo/list_bank.txt");

    // Logo for banks
    ui.kAccountCreatorIcon->addItem("");
    QFile file(listIconFile);
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QDir dirLogo(KStandardDirs::locate("data", QString::fromLatin1("skrooge/images/logo/")));

        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line = in.readLine().trimmed();
            if (!line.isEmpty()) {
                QString bankName = line;
                bankName.remove(".png");
                bankName.replace('_', ' ');

                QRegExp rx("(.+) {2,}(.+)");
                if (rx.indexIn(bankName) != -1) {
                    // Icon is something like <bank name>__<banknumber>.png
                    ui.kAccountCreatorIcon->addItem(QIcon(dirLogo.absoluteFilePath(line)), rx.cap(1), rx.cap(2));
                } else {
                    ui.kAccountCreatorIcon->addItem(QIcon(dirLogo.absoluteFilePath(line)), bankName, "");
                }
            }
        }
        ui.kAccountCreatorIcon->addItem(KIcon("document-open-folder"), i18nc("Other type of bank account", "Other..."));

        file.close();
    }

    // Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
    this->installEventFilter(this);

    // Activate the edit panel per default
    ui.kWidgetSelector->setSelectedMode(0);

    // Refresh
    connect(getDocument(), SIGNAL(tableModified(QString,int)), this, SLOT(dataModified(QString,int)), Qt::QueuedConnection);
    dataModified("", 0);
}

SKGBankPluginWidget::~SKGBankPluginWidget()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::~SKGBankPluginWidget");
}

bool SKGBankPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
    if (iEvent && iEvent->type() == QEvent::KeyPress) {
        QKeyEvent* keyEvent = static_cast<QKeyEvent*>(iEvent);
        if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
            if (QApplication::keyboardModifiers() &Qt::ControlModifier && ui.kAccountCreatorAdd->isEnabled()) {
                ui.kAccountCreatorAdd->click();
            } else if (QApplication::keyboardModifiers() &Qt::ShiftModifier && ui.kAccountCreatorUpdate->isEnabled()) {
                ui.kAccountCreatorUpdate->click();
            }
        }
    }

    return false;
}

void SKGBankPluginWidget::onSelectionChanged()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::onSelectionChanged");
    // Mapping
    int nbSelect = ui.kView->getView()->getNbSelectedObjects();
    if (nbSelect == 1) {
        // set the icon
        SKGAccountObject account(ui.kView->getView()->getFirstSelectedObject());
        SKGBankObject bank;
        account.getBank(bank);
        QString fileName = bank.getIcon();
        QString iconName = fileName;
        if (!iconName.isEmpty()) {
            iconName.remove(".png");
            iconName.replace('_', ' ');

            QRegExp rx("(.+) {2,}(.+)");
            if (rx.indexIn(iconName) != -1) {
                iconName = rx.cap(1);
            }
            if (ui.kAccountCreatorIcon->contains(iconName)) ui.kAccountCreatorIcon->setText(iconName);
            else if (ui.kAccountCreatorIcon->contains(fileName)) {
                ui.kAccountCreatorIcon->setText(fileName);
            } else {
                int c = ui.kAccountCreatorIcon->count() - 1;
                bool b = ui.kAccountCreatorIcon->blockSignals(true);
                ui.kAccountCreatorIcon->insertItem(c, QIcon(fileName), fileName);
                ui.kAccountCreatorIcon->setCurrentIndex(c);
                ui.kAccountCreatorIcon->blockSignals(b);
            }
        } else {
            ui.kAccountCreatorIcon->setText("");
        }

        ui.kAccountCreatorBank->setText(account.getAttribute("t_BANK"));
        ui.kAccountCreatorAccount->setText(account.getAttribute("t_name"));
        ui.kAccountCreatorBankNumber->setText(account.getAttribute("t_BANK_NUMBER"));
        ui.kAccountCreatorAgencyNumber->setText(account.getAttribute("t_agency_number"));
        ui.kAccountCreatorNumber->setText(account.getAttribute("t_number"));
        ui.kAccountCreatorType->setText(account.getAttribute("t_TYPENLS"));
        ui.kAccountCreatorAddress->setText(account.getAttribute("t_agency_address"));
        ui.kAccountCreatorComment->setText(account.getAttribute("t_comment"));
        ui.kMinLimitAmout->setText(account.getAttribute("f_minamount"));
        ui.kMaxLimitAmout->setText(account.getAttribute("f_maxamount"));
        ui.kMaxLimit->setTristate(false);
        ui.kMaxLimit->setCheckState(account.isMaxLimitAmountEnabled() ? Qt::Checked : Qt::Unchecked);
        ui.kMinLimit->setTristate(false);
        ui.kMinLimit->setCheckState(account.isMinLimitAmountEnabled() ? Qt::Checked : Qt::Unchecked);

        double oBalance = 0;
        SKGUnitObject oUnit;
        account.getInitialBalance(oBalance, oUnit);

        int nbDec = oUnit.getNumberDecimal();
        if (nbDec == 0) nbDec = 2;

        ui.kAmountEdit->setText(KGlobal::locale()->formatMoney(oBalance, "", nbDec));
        if (oUnit.exist()) {
            ui.kUnitEdit->setUnit(oUnit);
        } else {
            SKGDocumentBank* doc = static_cast<SKGDocumentBank*>(getDocument());
            if (doc) {
                SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
                ui.kUnitEdit->setText(primary.Symbol);
            }
        }
    } else if (nbSelect > 1) {
        ui.kAccountCreatorIcon->setText(NOUPDATE);
        ui.kAccountCreatorBank->setText(NOUPDATE);
        ui.kAccountCreatorAccount->setText(NOUPDATE);
        ui.kAccountCreatorBankNumber->setText(NOUPDATE);
        ui.kAccountCreatorAgencyNumber->setText(NOUPDATE);
        ui.kAccountCreatorNumber->setText(NOUPDATE);
        ui.kAccountCreatorType->setText(NOUPDATE);
        ui.kAccountCreatorAddress->setText(NOUPDATE);
        ui.kAccountCreatorComment->setText(NOUPDATE);
        ui.kAmountEdit->setText(NOUPDATE);
        ui.kUnitEdit->setText(NOUPDATE);
        ui.kMinLimitAmout->setText(NOUPDATE);
        ui.kMaxLimitAmout->setText(NOUPDATE);
        ui.kMaxLimit->setTristate(true);
        ui.kMaxLimit->setCheckState(Qt::PartiallyChecked);
        ui.kMinLimit->setTristate(true);
        ui.kMinLimit->setCheckState(Qt::PartiallyChecked);
    }

    // Refresh graph
    m_timer2.start(300);

    onAccountCreatorModified();
    Q_EMIT selectionChanged();
}

void SKGBankPluginWidget::onRefreshGraph()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::onRefreshGraph");
    if (m_graph) {
        bool visible = ui.kView->getShowWidget()->getState().contains("graph");

        QDomDocument doc("SKGML");
        if (doc.setContent(m_graph->getState())) {
            QDomElement root = doc.documentElement();

            QString graphS = root.attribute("graph");

            QDomDocument doc2("SKGML");
            if (doc2.setContent(graphS)) {
                QDomElement root2 = doc2.documentElement();
                QString wc;
                QString title;
                int nbSelect = 0;
                if (visible) {
                    SKGObjectBase::SKGListSKGObjectBase objs = ui.kView->getView()->getSelectedObjects();
                    nbSelect = objs.count();
                    if (nbSelect) {
                        wc = "t_ACCOUNT IN (";
                        title = i18nc("Noun, a list of items", "Operations of account ");
                        for (int i = 0; i < nbSelect; ++i) {
                            if (i) {
                                wc += ',';
                                title += ',';
                            }
                            SKGAccountObject act(objs.at(i));
                            wc += '\'' % SKGServices::stringToSqlString(act.getName()) % '\'';
                            title += i18n("'%1'", act.getName());
                        }
                        wc += ')';
                    }
                } else {
                    wc = "1=0";
                }
                root2.setAttribute("operationWhereClause", wc);
                root2.setAttribute("title", title);
                root2.setAttribute("lines", nbSelect ? "t_ACCOUNT" : "#NOTHING#");
            }
            root.setAttribute("graph", doc2.toString());
        }

        m_graph->setState(doc.toString());

        m_graph->setVisible(visible);
    }
}

void SKGBankPluginWidget::onIconChanged()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::onIconChanged");

    int c = ui.kAccountCreatorIcon->currentIndex();
    if (c && c == ui.kAccountCreatorIcon->count() - 1) {
        QString fileName = KFileDialog::getOpenFileName(KUrl(KStandardDirs::locate("data", "skrooge/images/logo/")), "image/png image/jpeg image/gif image/tiff" , this);
        if (!fileName.isEmpty()) {
            if (ui.kAccountCreatorIcon->contains(fileName)) ui.kAccountCreatorIcon->setText(fileName);
            else {
                bool b = ui.kAccountCreatorIcon->blockSignals(true);
                ui.kAccountCreatorIcon->insertItem(c, QIcon(fileName), fileName);
                ui.kAccountCreatorIcon->setCurrentIndex(c);
                ui.kAccountCreatorIcon->blockSignals(b);
            }
        } else {
            ui.kAccountCreatorIcon->setCurrentIndex(c - 1);
        }
    }

    if (ui.kAccountCreatorIcon->currentIndex() != 0) {
        // Set the bank name
        QString name = ui.kAccountCreatorIcon->currentText();
        QFileInfo f(name);
        if (f.exists()) {
            name = f.baseName();
            name = name.replace('_', ' ');
        }
        ui.kAccountCreatorBank->setText(name);
    } else {
        ui.kAccountCreatorBank->setText("");
    }
}

void SKGBankPluginWidget::onAccountCreatorModified()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::onAccountCreatorModified");

    bool activatedForWallet = ui.kWidgetSelector->getSelectedMode() != -1 &&
                              ui.kAccountCreatorAccount->text().length() > 0 &&
                              ui.kUnitEdit->currentText().length() > 0 &&
                              (ui.kAmountEdit->valid() || ui.kAmountEdit->text().isEmpty() || ui.kAmountEdit->text() == NOUPDATE);
    bool activated = activatedForWallet &&
                     ui.kAccountCreatorBank->text().length() > 0;
    bool wallet = (static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt()) == SKGAccountObject::WALLET);

    int nbSelect = getNbSelectedObjects();
    ui.kAccountCreatorAdd->setEnabled(activated || (wallet && activatedForWallet));
    ui.kAccountCreatorUpdate->setEnabled((activated || (wallet && activatedForWallet)) && nbSelect > 0);

    // Wallet specific mode
    ui.kNumeroFrm->setVisible(!wallet);
    ui.kBankFrm->setVisible(!wallet);
    ui.kBankLbl->setVisible(!wallet);
    ui.kAccountCreatorAddress->setVisible(!wallet);
    ui.kAgencyAddressLbl->setVisible(!wallet);

    // Facilitate bank number
    if (ui.kAccountCreatorBankNumber->text().isEmpty()) {
        QString code = ui.kAccountCreatorIcon->itemData(ui.kAccountCreatorIcon->currentIndex()).toString();
        ui.kAccountCreatorBankNumber->setText(code);
    }
}

SKGError SKGBankPluginWidget::setInitialBalanceFromEditor(SKGAccountObject& iAccount)
{
    return (ui.kAmountEdit->text() != NOUPDATE &&  ui.kUnitEdit->text() != NOUPDATE ? iAccount.setInitialBalance(ui.kAmountEdit->value(), ui.kUnitEdit->getUnit()) : SKGError());
}

void SKGBankPluginWidget::onAddAccountClicked()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGBankPluginWidget::onAddAccountClicked", err);
    {
        SKGAccountObject accountObj;

        QString bankName = ui.kAccountCreatorBank->text();
        QString accountName = ui.kAccountCreatorAccount->text();
        QString name = bankName % '-' % accountName;
        SKGAccountObject::AccountType accountType = static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt());
        if (accountType == SKGAccountObject::WALLET) bankName = "";
        {
            SKGBEGINTRANSACTION(*getDocument(), i18nc("Creating an account", "Account creation '%1'", name), err);

            // Create bank object in case of missing
            SKGBankObject bankObj(getDocument());
            IFOKDO(err, bankObj.setName(ui.kAccountCreatorBank->text()))
            IFOK(err) {
                // Build icon name
                QString icon = ui.kAccountCreatorIcon->currentText();
                if (!QFile(icon).exists() && !icon.isEmpty()) {
                    QString code = ui.kAccountCreatorIcon->itemData(ui.kAccountCreatorIcon->currentIndex()).toString();
                    if (!code.isEmpty()) icon += "  " % code;

                    icon.replace(' ', '_');
                    icon += ".png";
                }
                err = bankObj.setIcon(icon);
            }
            IFOKDO(err, bankObj.setNumber(ui.kAccountCreatorBankNumber->text()))

            IFOKDO(err, bankObj.save())
            IFOKDO(err, bankObj.load())

            // Create account object in case of missing
            IFOKDO(err, bankObj.addAccount(accountObj))
            IFOKDO(err, accountObj.setName(accountName))
            IFOKDO(err, accountObj.setAgencyNumber(ui.kAccountCreatorAgencyNumber->text()))
            IFOKDO(err, accountObj.setAgencyAddress(ui.kAccountCreatorAddress->text()))
            IFOKDO(err, accountObj.setComment(ui.kAccountCreatorComment->text()))
            IFOKDO(err, accountObj.setNumber(ui.kAccountCreatorNumber->text()))
            IFOKDO(err, accountObj.setType(accountType))

            IFOKDO(err, accountObj.maxLimitAmountEnabled(ui.kMaxLimit->isChecked()))
            IFOKDO(err, accountObj.setMaxLimitAmount(ui.kMaxLimitAmout->value()))

            IFOKDO(err, accountObj.minLimitAmountEnabled(ui.kMinLimit->isChecked()))
            IFOKDO(err, accountObj.setMinLimitAmount(ui.kMinLimitAmout->value()))

            IFOKDO(err, accountObj.save(false))
            IFOKDO(err, setInitialBalanceFromEditor(accountObj))
            IFOKDO(err, accountObj.save())
        }

        // status bar
        IFOK(err) {
            err = SKGError(0, i18nc("Successfully created an account", "Account '%1' created", name));
            ui.kView->getView()->selectObject(accountObj.getUniqueID());
        } else {
            err.addError(ERR_FAIL, i18nc("Error message : Could not create an account",  "Account creation failed"));
        }
    }

    // Display error
    SKGMainPanel::displayErrorMessage(err);
}

void SKGBankPluginWidget::onModifyAccountClicked()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGBankPluginWidget::onModifyAccountClicked", err);
    {
        // Get Selection
        SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();

        int nb = selection.count();

        // Is it a massive modification of accounts to merge them ?
        SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Updating an account", "Account update"), err, nb);
        if (nb > 1 && ui.kAccountCreatorAccount->text() != NOUPDATE && !ui.kAccountCreatorAccount->text().startsWith(QLatin1String(" = "))) {
            getDocument()->sendMessage(i18nc("Information message", "You tried to modify all names of selected accounts. Accounts have been merged."));

            // Do the merge
            SKGAccountObject accountObj1(selection[0]);
            for (int i = 1; !err && i < nb; ++i) {
                SKGAccountObject accountObj(selection[i]);
                err = accountObj1.merge(accountObj);
            }

            // Change selection for the rest of the operation
            selection.clear();
            selection.push_back(accountObj1);
            nb = 1;
        }

        QString bankName = ui.kAccountCreatorBank->text();
        SKGAccountObject::AccountType accountType = static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt());
        if (accountType == SKGAccountObject::WALLET) bankName = "";

        for (int i = 0; !err && i < nb; ++i) {
            SKGAccountObject accountObj(selection[i]);
            err = accountObj.setName(ui.kAccountCreatorAccount->text());
            IFOKDO(err, accountObj.setNumber(ui.kAccountCreatorNumber->text()))
            IFOKDO(err, setInitialBalanceFromEditor(accountObj))
            if (!err && ui.kAccountCreatorType->text() != NOUPDATE) err = accountObj.setType(static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt()));
            IFOKDO(err, accountObj.setAgencyNumber(ui.kAccountCreatorAgencyNumber->text()))
            IFOKDO(err, accountObj.setAgencyAddress(ui.kAccountCreatorAddress->text()))
            IFOKDO(err, accountObj.setComment(ui.kAccountCreatorComment->text()))

            if (!err && ui.kMaxLimit->checkState() != Qt::PartiallyChecked) err = accountObj.maxLimitAmountEnabled(ui.kMaxLimit->isChecked());
            if (!err && ui.kMaxLimitAmout->text() != NOUPDATE) err = accountObj.setMaxLimitAmount(ui.kMaxLimitAmout->value());

            if (!err && ui.kMinLimit->checkState() != Qt::PartiallyChecked) err = accountObj.minLimitAmountEnabled(ui.kMinLimit->isChecked());
            if (!err && ui.kMaxLimitAmout->text() != NOUPDATE) err = accountObj.setMinLimitAmount(ui.kMinLimitAmout->value());

            IFOKDO(err, accountObj.save())

            // Update bank
            SKGBankObject bankObj;
            if (bankName == NOUPDATE) {
                accountObj.getBank(bankObj);
            } else {
                if (SKGNamedObject::getObjectByName(getDocument(), "bank", bankName, bankObj).isSucceeded()) {
                    // The created bank already exist ==> update parent bank
                    IFOKDO(err, accountObj.setBank(bankObj))
                    IFOKDO(err, accountObj.save())
                } else {
                    // The bank does not exist
                    int code = KMessageBox::Yes;
                    SKGBankObject currentBank;
                    err = accountObj.getBank(currentBank);
                    IFOK(err) {
                        SKGObjectBase::SKGListSKGObjectBase accounts;
                        err = currentBank.getAccounts(accounts);
                        if (!err && accounts.count() > 1) {
                            QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
                            code = KMessageBox::questionYesNo(this, i18nc("Question", "You are trying to modify bank name of account named '%1'.\nDo you want to do this modification for all accounts of this bank ? ",  accountObj.getName()));
                            QApplication::restoreOverrideCursor();
                        }
                    }

                    IFOKDO(err, accountObj.getBank(bankObj))
                    if (code == KMessageBox::Yes) {
                        // The bank does not exist ==> update this one
                        IFOKDO(err, bankObj.setName(bankName))
                    } else {
                        // The bank does not exist ==> create a new one
                        IFOKDO(err, bankObj.resetID())
                        IFOKDO(err, bankObj.setName(bankName))
                        IFOKDO(err, bankObj.save())
                        IFOKDO(err, accountObj.setBank(bankObj))
                        IFOKDO(err, accountObj.save())
                    }
                }
            }
            if (ui.kAccountCreatorIcon->text() != NOUPDATE) {
                IFOK(err) {
                    // Build icon name
                    QString icon = ui.kAccountCreatorIcon->currentText();
                    if (!QFile(icon).exists() && !icon.isEmpty()) {
                        QString code = ui.kAccountCreatorIcon->itemData(ui.kAccountCreatorIcon->currentIndex()).toString();
                        if (!code.isEmpty()) icon += "  " % code;
                        icon.replace(' ', '_');
                        icon += ".png";
                    }
                    err = bankObj.setIcon(icon);
                }
            }
            IFOKDO(err, bankObj.setNumber(ui.kAccountCreatorBankNumber->text()))
            IFOKDO(err, bankObj.save())

            IFOKDO(err, getDocument()->stepForward(i + 1))
        }

        // Remove bank without account
        IFOK(err) {
            err = getDocument()->executeSqliteOrder("DELETE FROM bank WHERE NOT EXISTS(SELECT 1 FROM account WHERE account.rd_bank_id = bank.id)");
        }
    }

    // status bar
    IFOKDO(err, SKGError(0, i18nc("Successfully updated an account", "Account updated.")))
    else {
        err.addError(ERR_FAIL, i18nc("Error message : Could not update an account",  "Update failed"));
    }
    // Display error
    SKGMainPanel::displayErrorMessage(err);
}

void SKGBankPluginWidget::onComputeRIB()
{
    QString sb = ui.kAccountCreatorBankNumber->text().rightJustified(5, '0', true);
    QString sg = ui.kAccountCreatorAgencyNumber->text().rightJustified(5, '0', true);
    QString sc = ui.kAccountCreatorNumber->text().rightJustified(11, '0', true);

    QString l1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    QString l2 = "12345678912345678923456789";

    for (int i = 0; i < 26; ++i) {
        sc = sc.replace(l1[i], l2[i]);
    }

    //         int b=SKGServices::stringToInt ( sb );
    //         int g=SKGServices::stringToInt ( sg );
    //         int d=SKGServices::stringToInt ( sc.left ( 6 ) );
    //         int c=SKGServices::stringToInt ( sc.right ( 5 ) );

    //         ui.kRib->setText ( SKGServices::intToString ( 97 - ( ( 89 * b + 15 * g + 76 * d + 3 * c ) % 97 ) ) );
}

void SKGBankPluginWidget::cleanEditor()
{
    if (getNbSelectedObjects() == 0) {
        ui.kAccountCreatorIcon->setText("");
        ui.kAccountCreatorBank->setText("");
        ui.kAccountCreatorAccount->setText("");
        ui.kAccountCreatorBankNumber->setText("");
        ui.kAccountCreatorAgencyNumber->setText("");
        ui.kAccountCreatorNumber->setText("");
        ui.kAccountCreatorType->setText(i18nc("Noun, a type of account", "Current"));
        ui.kAccountCreatorAddress->setText("");
        ui.kAccountCreatorComment->setText("");
        ui.kAmountEdit->setText("0");
        ui.kUnitEdit->refershList();
    }
}

QString SKGBankPluginWidget::getState()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::getState");
    QDomDocument doc("SKGML");
    QDomElement root = doc.createElement("parameters");
    doc.appendChild(root);
    root.setAttribute("currentPage", SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
    root.setAttribute("view", ui.kView->getState());
    root.setAttribute("graph", m_graph->getState());
    return doc.toString();
}

void SKGBankPluginWidget::setState(const QString& iState)
{
    SKGTRACEIN(10, "SKGBankPluginWidget::setState");

    QDomDocument doc("SKGML");
    doc.setContent(iState);
    QDomElement root = doc.documentElement();

    QString currentPage = root.attribute("currentPage");
    if (currentPage.isEmpty()) currentPage = '0';
    ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));

    ui.kView->setState(root.attribute("view"));
    m_graph->setState(root.attribute("graph"));
}

QString SKGBankPluginWidget::getDefaultStateAttribute()
{
    return "SKGBANK_DEFAULT_PARAMETERS";
}

void SKGBankPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
    SKGTRACEIN(10, "SKGBankPluginWidget::dataModified");
    Q_UNUSED(iIdTransaction);

    // Refresh widgets
    if (iTableName == "v_account_display" || iTableName.isEmpty()) {
        // Refresh info area
        m_timer.start(300);
    }

    if (iTableName == "bank" || iTableName.isEmpty()) {
        // Set completions
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorBank, getDocument(), "bank", "t_name", "", true);
    }

    if (iTableName == "account" || iTableName.isEmpty()) {
        // Set completions
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorAccount, getDocument(), "account", "t_name", "", true);
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorBankNumber, getDocument(), "bank", "t_bank_number", "", true);
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorAgencyNumber, getDocument(), "account", "t_agency_number", "", true);
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorNumber, getDocument(), "account", "t_number", "", true);
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorAddress, getDocument(), "account", "t_agency_address", "", true);
        SKGMainPanel::fillWithDistinctValue(ui.kAccountCreatorComment, getDocument(), "account", "t_comment", "", true);
    }
}

void SKGBankPluginWidget::refreshInfoZone()
{
    SKGTRACEIN(10, "SKGBankPluginWidget::refreshInfoZone");

    // Refresh info area
    SKGStringListList listTmp;
    getDocument()->executeSelectSqliteOrder(
        "SELECT TOTAL(f_TODAYAMOUNT), TOTAL(f_CURRENTAMOUNT), TOTAL(f_CHECKED), TOTAL(f_COMING_SOON) from v_account_display",
        listTmp);
    if (listTmp.count() == 2) {
        SKGDocumentBank* doc = static_cast<SKGDocumentBank*>(getDocument());
        if (doc) {
            SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
            double v1 = SKGServices::stringToDouble(listTmp.at(1).at(0));
            double v2 = SKGServices::stringToDouble(listTmp.at(1).at(1));
            double v3 = SKGServices::stringToDouble(listTmp.at(1).at(2));
            double v4 = SKGServices::stringToDouble(listTmp.at(1).at(3));
            QString s1 = doc->formatMoney(v1, primary);
            QString s2 = doc->formatMoney(v2, primary);
            QString s3 = doc->formatMoney(v3, primary);
            QString s4 = doc->formatMoney(v4, primary);
            ui.kInfo->setText(i18nc("Information on an account's status : Balance is the current amount of money on the account, Checked is the amount of money on your last bank's statement, To be Checked is the differences between these two values", "Today balance : %1     Balance : %2     Checked : %3     To be Checked : %4", s1, s2, s3, s4));

            SKGServices::SKGUnitInfo secondaryUnit = doc->getSecondaryUnit();
            if (!secondaryUnit.Symbol.isEmpty() && secondaryUnit.Value) {
                s1 = doc->formatMoney(v1, secondaryUnit);
                s2 = doc->formatMoney(v2, secondaryUnit);
                s3 = doc->formatMoney(v3, secondaryUnit);
                s4 = doc->formatMoney(v4, secondaryUnit);
            }
            ui.kInfo->setToolTip(i18nc("Information on an account's status : Balance is the current amount of money on the account, Checked is the amount of money on your last bank's statement, To be Checked is the differences between these two values", "<p>Today balance : %1 < / p > <p>Balance : %2 < / p > <p>Checked : %3 < / p > <p>To be Checked : %4 < / p > ", s1, s2, s3, s4));
        }
    }
}

QWidget* SKGBankPluginWidget::mainWidget()
{
    return ui.kView->getView();
}

QList< QWidget* > SKGBankPluginWidget::printableWidgets()
{
    QList< QWidget* > output;
    output.push_back(mainWidget());
    output.push_back(m_graph);
    return output;
}


void SKGBankPluginWidget::activateEditor()
{
    if (ui.kWidgetSelector->getSelectedMode() == -1) ui.kWidgetSelector->setSelectedMode(0);
    ui.kAccountCreatorBank->setFocus();
}

bool SKGBankPluginWidget::isEditor()
{
    return true;
}

#include "skgbankpluginwidget.moc"
