/*
   This file is part of MDic Dictionary
   Copyright (C) 2007-2010 Mehrdad Momeny <mehrdad.momeny@gmail.com
   Copyright (C) 2007-2010 Majid Ramezanpour <majid.ramezanpour@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 3 of the License,
   (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/

*/


#include "dictionaryconfig.h"
#include "ui_dictionaryconfigbase.h"
#include "settings.h"
#include "mdicconv.h"
#include "dbproperties.h"
#include <QTableWidget>
#include <QSqlQuery>
#include <QCheckBox>
#include <QFileDialog>
#include "adddictionary.h"
#include <dicts/mdict.h>
#include <dicts/gtranslate.h>
#include <QMessageBox>

class DictionaryConfigWidget::Private
{
public:
    Ui_DictionaryConfigBase ui;
};

DictionaryConfigWidget::DictionaryConfigWidget(QWidget* parent, Qt::WindowFlags f)
        : QWidget(parent, f), d(new Private)
{
    d->ui.setupUi(this);
    connect(d->ui.btnAdd, SIGNAL(clicked(bool)), this, SLOT(addDictionary()));
    connect(d->ui.btnRemove, SIGNAL(clicked(bool)), SLOT(removeCurrentDictionary()));
    connect(d->ui.btnConv, SIGNAL(clicked(bool)), SLOT(showConvertDialog()));
    connect(d->ui.btnProperties, SIGNAL(clicked(bool)), SLOT(showDictionaryProperties()));
    connect(d->ui.btnUp, SIGNAL(clicked(bool)), SLOT(moveRowUp()));
    connect(d->ui.btnDown, SIGNAL(clicked(bool)), SLOT(moveRowDown()));
    load();
}

DictionaryConfigWidget::~DictionaryConfigWidget()
{
    delete d;
}

void DictionaryConfigWidget::load()
{
    foreach(const DictCore::Dictionary &db, Settings::self()->dicts) {
        loadDb(db);
    }
    d->ui.dbTable->resizeColumnsToContents();
}

void DictionaryConfigWidget::save()
{
    Settings::self()->dicts.clear();
    for (int i = 0; i < d->ui.dbTable->rowCount(); ++i) {
        DictCore::Dictionary dic;
        dic.setBackendType( (DictCore::BackendType) d->ui.dbTable->item(i, 2)->data(32).toInt());
        dic.setCode( d->ui.dbTable->item(i, 1)->data(32).toString() );
        dic.setName( d->ui.dbTable->item(i, 1)->text() );
        dic.setEnabled( qobject_cast< QCheckBox* >(d->ui.dbTable->cellWidget(i, 0))->isChecked() );
        Settings::self()->dicts.append(dic);
    }
    DictCore::self()->setLoadedDicts(Settings::self()->dicts);
}

void DictionaryConfigWidget::loadDb(const DictCore::Dictionary& dic)
{
    int rc = d->ui.dbTable->rowCount();
    d->ui.dbTable->setRowCount(rc + 1);

    QTableWidgetItem *dbNameItem = new QTableWidgetItem(dic.name(), 1);
    dbNameItem->setData(32, dic.code());
    d->ui.dbTable->setItem(rc, 1, dbNameItem);

    QCheckBox *chk = new QCheckBox(this);
    chk->setChecked(dic.isEnabled());
    d->ui.dbTable->setCellWidget(rc, 0, chk);  //show checkbox

    QTableWidgetItem *typeItem = new QTableWidgetItem(dic.typeName(), 0);
    typeItem->setData(32, dic.backendType());
    d->ui.dbTable->setItem(rc, 2, typeItem);
}

void DictionaryConfigWidget::addDictionary()
{
    QPointer<AddDictionary> f = new AddDictionary(this);
    f->setAttribute(Qt::WA_DeleteOnClose, false);
    if(f->exec() == QDialog::Accepted){
        loadDb(f->resultDict());
        d->ui.dbTable->resizeColumnsToContents();
    }
}

void DictionaryConfigWidget::removeCurrentDictionary()
{
    int rowToDelete = d->ui.dbTable->currentRow();
    if (rowToDelete >= 0) {
        if(d->ui.dbTable->item(rowToDelete, 2)->data(32).toInt() == DictCore::GoogleTranslate){
            d->ui.dbTable->removeRow(rowToDelete);
        } else {
            QString FileName;
            FileName = d->ui.dbTable->item(rowToDelete, 1)->text();
            if (!FileName.isEmpty()) {
                QFileInfo infoFile(FileName);
                FileName = infoFile.fileName();
            }
            if (QFile::remove(Settings::self()->dbsDir() + FileName)) {
                d->ui.dbTable->removeRow(rowToDelete);
            } else {
                QMessageBox::warning(this, tr("Error on Delete"),
                                    tr("Can not Delete Database file please delete it manually from: %1").arg(Settings::self()->dbsDir()));
            }
        }
        d->ui.dbTable->resizeColumnsToContents();
    } else {
        QMessageBox::warning(this, tr("Select a Database"), tr("Please select a database to remove."));
    }
}

void DictionaryConfigWidget::showConvertDialog()
{
    QPointer<MDicConv> f = new MDicConv(this);
    f->setAttribute(Qt::WA_DeleteOnClose);
    f->show();
}

void DictionaryConfigWidget::showDictionaryProperties()
{
    int row = d->ui.dbTable->currentRow();
    if (row >= 0) {
        QString code = d->ui.dbTable->item(row, 1)->data(32).toString();
        foreach(const DictCore::Dictionary &dic, Settings::self()->dicts) {
            if(dic.code() == code){
                DictInfo info;
                if(dic.backendType() == DictCore::MDic)
                    info = MDict::dictInfo(dic);
                else
                    info = GTranslate::dictInfo(dic);
                QPointer<DBProperties> f = new DBProperties(this);
                f->setAttribute(Qt::WA_DeleteOnClose);
                f->showForm(info);
            }
        }
    } else {
        QMessageBox::warning(this, tr("Select a Database"),
                             tr("Please select a database to view and change its properties!"));
    }
}

void DictionaryConfigWidget::moveRowUp()
{
    move(true);
}

void DictionaryConfigWidget::moveRowDown()
{
    move(false);
}

void DictionaryConfigWidget::move(bool up)
{
    if (d->ui.dbTable->selectedItems().count() <= 0)
        return;

    const int sourceRow = d->ui.dbTable->row(d->ui.dbTable->selectedItems().at(0));
    bool sourceShow = qobject_cast<QCheckBox*>(d->ui.dbTable->cellWidget(sourceRow, 0))->isChecked();
    const int destRow = (up ? sourceRow - 1 : sourceRow + 1);

    if (destRow < 0  || (destRow >= d->ui.dbTable->rowCount()))
        return;

    bool destShow = qobject_cast<QCheckBox*>(d->ui.dbTable->cellWidget(destRow, 0))->isChecked();

    // take whole rows
    QList<QTableWidgetItem*> sourceItems = takeRow(sourceRow);
    QList<QTableWidgetItem*> destItems = takeRow(destRow);

    // set back in reverse order
    setRow(sourceRow, destItems);
    setRow(destRow, sourceItems);

    // taking whole row doesn't work! so changing value of checkBoxes take place here.
    qobject_cast<QCheckBox*>(d->ui.dbTable->cellWidget(sourceRow, 0))->setChecked(destShow);
    qobject_cast<QCheckBox*>(d->ui.dbTable->cellWidget(destRow, 0))->setChecked(sourceShow);

    d->ui.dbTable->setCurrentCell(destRow, 0);
}

// takes and returns the whole row
QList<QTableWidgetItem*> DictionaryConfigWidget::takeRow(int row)
{
    QList<QTableWidgetItem*> rowItems;

    for (int col = 0; col < d->ui.dbTable->columnCount(); ++col) {
        rowItems << d->ui.dbTable->takeItem(row, col);
    }

    return rowItems;
}

// sets the whole row
void DictionaryConfigWidget::setRow(int row, const QList<QTableWidgetItem*>& rowItems)
{
    for (int col = 0; col < d->ui.dbTable->columnCount(); ++col) {
        d->ui.dbTable->setItem(row, col, rowItems.at(col));
    }
}

#include "dictionaryconfig.moc"
