/***************************************************************************
 *   Copyright (C) 2004-2009 by Pere Constans
 *   constans@molspaces.com
 *   cb2Bib version 1.3.2. Licensed under the GNU GPL version 3.
 *   See the LICENSE file that comes with this distribution.
 ***************************************************************************/
#include "c2bSettings.h"
#include "c2bUtils.h"

#include <QApplication>
#include <QClipboard>
#include <QIcon>
#include <QMessageBox>
#include <QProgressBar>
#include <QTimer>


/**
    Global settings for the cb2Bib
*/
c2bSettings::c2bSettings(const QString& organization, const QString& application, QObject* parento)
        : settings(organization, application, parento)
{}

c2bSettings::c2bSettings(const QString& fn, QObject* parento) : settings(fn, parento)
{}

c2bSettings::~c2bSettings()
{
    delete progBar;
}


c2bSettings* c2bSettings::initSettings()
{
    c2bSettings* s;
    if (c2bSettings::isConfiguredMode())
        s = new c2bSettings(c2bSettings::configuredFilename());
    else
        s = new c2bSettings(qApp->organizationName(), qApp->applicationName());
    s->init();
    return s;
}

void c2bSettings::init()
{
    settings::init();
    progBar = 0;
    if (cl_console_mode)
        return;
    setDefaults();
    if (cl_import)
        // Process cl_import_filename and update cl_cb2bib_import_mode
        processReferenceFile();
    if (cl_cb2bib_mode && !cl_cb2bib_import_mode)
    {
        setValue("cb2Bib/isRunning", true);
        sync();
        connect(qApp, SIGNAL(lastWindowClosed()), this, SLOT(guiExits()));
    }
}

void c2bSettings::notify()
{
    update();
    emit newSettings();
}

void c2bSettings::update()
{
    // Values for very general GUI settings
    c2bMonoFont = value("cb2Bib/MonoFont").value<QFont>();
    colors.loadColors(this);
}

void c2bSettings::setDefaults()
{
    QHash<QString, QVariant> defaults;
    defaults["cb2Bib/MonoFont"] = QFont("Courier");
    // Construct current settings
    const QStringList keys(defaults.keys());
    for (int i = 0; i < keys.count(); ++i)
        setValue(keys.at(i), value(keys.at(i), defaults.value(keys.at(i))));
    update();
}

#ifdef Q_WS_WIN
#include <QFileDialog>
QString c2bSettings::decodeFilename(const QString& fn) const
{
    // This function is meant for fn given by the command shell and that will end up being visible
    const QString dfn(settings::decodeFilename(fn));
    QFileDialog fd(0, QString(), dfn);
    const QStringList fns(fd.selectedFiles());
    if (fns.count() == 0)
        return dfn;
    const QString wdfn(fns.first());
    if (QFileInfo(wdfn).exists())
        return QDir::toNativeSeparators(wdfn);
    else
        return dfn;
}
#endif

/***************************************************************************
 *  Downloaded reference extraction
 ***************************************************************************/

void c2bSettings::processReferenceFile()
{
    // The "Download reference to reference manager" functionality to cb2Bib is implemented as follows:
    // - Put downloaded reference into the clipboard
    // - If no cb2Bib instance is running, launch cb2Bib GUI, otherwise exit
    // This is simple, enough, and consistent with a 'clipboard to BibTeX' program.
    // The 'single instance' implementation is naive, but it is sufficient for cb2Bib, and does not prevent
    // from having multiple cb2Bib instances in its usual deployment, if so desired.
    // Aware of QClipboard X11 note: "You should not store or retrieve the clipboard contents in response
    // to timer or non-user-input events". Functions processReferenceFile() and processprocessReferenceFileEvent()
    // do not follow it. It seems to work smooth, for all platforms, and, overall, it is a feasible solution
    // in this particular case.

    QFile file(cl_import_filename);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        cl_cb2bib_import_mode = true;
        QMessageBox::warning(0, tr("Warning - cb2Bib"), tr("Unable to open the reference file %1 for reading.\nError: '%2'.").
                             arg(cl_import_filename).arg(file.errorString()), QMessageBox::Ok);
        QTimer::singleShot(500, qApp, SLOT(quit()));
    }
    else
    {
        if (value("cb2Bib/isRunning", false).toBool())
        {
            cl_cb2bib_import_mode = true;
            if (!progBar)
                progBar = new QProgressBar;
            progBar->setRange(0, 100);
            progBar->setWindowTitle(QObject::tr("Importing..."));
            progBar->setWindowIcon(QIcon(QString::fromUtf8(":/icons/icons/cb2bib.png")));
            progBar->show();
            progBar->setValue(50);
        }
        QTimer::singleShot(500, this, SLOT(processReferenceFileEvent()));
    }
}

void c2bSettings::processReferenceFileEvent()
{
    const QString reference(c2bUtils::fileToString(cl_import_filename).trimmed());
    QClipboard* cb = qApp->clipboard();
    cb->setText(reference, QClipboard::Clipboard);
    if (cl_cb2bib_import_mode)
    {
        if (progBar)
            progBar->setValue(100);
        QTimer::singleShot(500, qApp, SLOT(quit()));
    }
}

void c2bSettings::guiExits()
{
    setValue("cb2Bib/isRunning", false);
    sync();
}
