/***************************************************************************
                          kgpglibrary.cpp  -  description
                             -------------------
    begin                : Mon Jul 8 2002
    copyright          : (C) 2002 by Jean-Baptiste Mardelle
    email                : bj@altern.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kgpglibrary.h"

#include <QDesktopWidget>
#include <QApplication>
#include <QTextStream>
#include <QFile>

#include <KFileDialog>
#include <KPassivePopup>
#include <kio/renamedialog.h>
#include <KMessageBox>
#include <KLocale>
#include <kio/deletejob.h>
#include <kio/jobuidelegate.h>

#include "images.h"
#include "selectpublickeydialog.h"
#include "kgpgsettings.h"
#include "kgpginterface.h"
#include "kgpgtextinterface.h"
#include "kgpgitemmodel.h"

using namespace KgpgCore;

KgpgLibrary::KgpgLibrary(QWidget *parent)
{
    m_extension = ".gpg";

    m_popisactive = false;
    m_panel = parent;
}

void KgpgLibrary::setFileExtension(const QString &ext)
{
    m_extension = ext;
}

void KgpgLibrary::slotFileEnc(const KUrl::List &urls, const QStringList &opts, KGpgItemModel *model, const KShortcut &goDefaultKey, const QString &defaultKey)
{
    if (!urls.empty())
    {
        m_urlselecteds = urls;
            QString fileNames = urls.first().fileName();
            if (urls.count() > 1)
                fileNames += ", ...";

            KgpgSelectPublicKeyDlg *dialog = new KgpgSelectPublicKeyDlg(0, model, goDefaultKey, fileNames);
            if (dialog->exec() == KDialog::Accepted)
            {
                QStringList options = opts;
                if (dialog->getUntrusted()) options << "--always-trust";
                if (dialog->getArmor())     options << "--armor";
                if (dialog->getHideId())    options << "--throw-keyid";

                if (!dialog->getCustomOptions().isEmpty())
                    if (KGpgSettings::allowCustomEncryptionOptions())
                        options << dialog->getCustomOptions().split(' ');

                QStringList keys = dialog->selectedKeys();
                if (!defaultKey.isEmpty() && !keys.contains(defaultKey))
                    keys << defaultKey;
                startEncode(keys, options, dialog->getSymmetric());
            }

            delete dialog;
    }
}

void KgpgLibrary::startEncode(const QStringList &encryptkeys, const QStringList &encryptoptions, const bool &symetric)
{
    m_popisactive = false;
    //KUrl::List::iterator it;
    //filesToEncode=m_urlselecteds.count();
    m_encryptkeys = encryptkeys;
    m_encryptoptions = encryptoptions;
    m_symetric = symetric;
    fastEncode(m_urlselecteds.first(), encryptkeys, encryptoptions, symetric);
}

void KgpgLibrary::fastEncode(const KUrl &filetocrypt, const QStringList &encryptkeys, const QStringList &encryptoptions, const bool &symetric)
{
    if ((encryptkeys.isEmpty()) && (!symetric))
    {
        KMessageBox::sorry(0, i18n("You have not chosen an encryption key."));
        return;
    }

    m_urlselected = filetocrypt;

    KUrl dest;
    if (encryptoptions.contains("--armor"))
        dest.setPath(m_urlselected.path() + ".asc");
    else
        dest.setPath(m_urlselected.path() + m_extension);

    QFile fgpg(dest.path());
    if (fgpg.exists())
    {
        KIO::RenameDialog over(0, i18n("File Already Exists"), KUrl(), dest, KIO::M_OVERWRITE);
        if (over.exec() == QDialog::Rejected)
        {
            emit systemMessage(QString(), true);
            return;
        }

        dest = over.newDestUrl();
    }

    int filesToEncode = m_urlselecteds.count();
    if (filesToEncode > 1)
        emit systemMessage(i18n("<p><b>%1 Files left.</b><br /><b>Encrypting </b>%2</p>", filesToEncode, m_urlselecteds.first().path()));
    else
        emit systemMessage(i18n("<b>Encrypting </b>%1", m_urlselecteds.first().path()));

    m_pop = new KPassivePopup(m_panel);

    KGpgTextInterface *cryptFileProcess = new KGpgTextInterface();
    connect(cryptFileProcess, SIGNAL(fileEncryptionFinished(KUrl, KGpgTextInterface*)), this, SLOT(processEnc(KUrl, KGpgTextInterface*)));
    connect(cryptFileProcess, SIGNAL(errorMessage(QString, KGpgTextInterface*)), this, SLOT(processEncError(QString, KGpgTextInterface*)));
    cryptFileProcess->encryptFile(encryptkeys, m_urlselected, dest, encryptoptions, symetric);

    if (!m_popisactive)
    {
        //connect(cryptFileProcess,SIGNAL(processstarted(QString)),this,SLOT(processpopup2(QString)));
        m_popisactive = true;
    }

}

void KgpgLibrary::processEnc(const KUrl &, KGpgTextInterface *i)
{
    i->deleteLater();
    emit systemMessage(QString());

    m_urlselecteds.pop_front();

    if (m_urlselecteds.count() > 0)
        fastEncode(m_urlselecteds.first(), m_encryptkeys, m_encryptoptions, m_symetric);
    else
        emit encryptionOver();
}

void KgpgLibrary::processEncError(const QString &mssge, KGpgTextInterface *i)
{
    i->deleteLater();
    m_popisactive = false;
    emit systemMessage(QString(), true);
    KMessageBox::detailedSorry(m_panel, i18n("<p><b>Process halted</b>.<br />Not all files were encrypted.</p>"), mssge);
}

void KgpgLibrary::slotFileDec(const KUrl &src, const KUrl &dest, const QStringList &customDecryptOption)
{
    // decode file from konqueror or menu
    m_pop = new KPassivePopup();
    m_urlselected = src;

    KGpgTextInterface *decryptFileProcess = new KGpgTextInterface();
    decryptFileProcess->decryptFile(src, dest, customDecryptOption);
    connect(decryptFileProcess, SIGNAL(decryptFileStarted(KUrl)), this, SLOT(processEncPopup(KUrl)));
    connect(decryptFileProcess, SIGNAL(decryptFileFinished(int, KGpgTextInterface*)), this, SLOT(processDecOver(int, KGpgTextInterface*)));
}

void KgpgLibrary::processDecOver(int ret, KGpgTextInterface *iface)
{
    emit systemMessage(QString());
    delete m_pop;
    iface->deleteLater();
    if (ret != 0)
	emit decryptionOver(this, m_urlselected);
    else
	emit decryptionOver(this, KUrl());
}

void KgpgLibrary::slotImportOver(KgpgInterface *iface, const QStringList &keys)
{
    iface->deleteLater();
    emit importOver(this, keys);
}

void KgpgLibrary::processEncPopup(const KUrl &url)
{
    emit systemMessage(i18n("Decrypting %1", url.pathOrUrl()));

    m_pop->setTimeout(0);
    m_pop->setView(i18n("Processing decryption"), i18n("Please wait..."), Images::kgpg());
    m_pop->show();

    QRect qRect(QApplication::desktop()->screenGeometry());
    int iXpos = qRect.width() / 2 - m_pop->width() / 2;
    int iYpos = qRect.height() / 2 - m_pop->height() / 2;
    m_pop->move(iXpos, iYpos);
}

void KgpgLibrary::processPopup2(const QString &fileName)
{
    //m_pop->setTimeout(0);
    m_pop->setView(i18n("Processing encryption (%1)", fileName),i18n("Please wait..."), Images::kgpg());
    m_pop->show();
    /*QRect qRect(QApplication::desktop()->screenGeometry());
    int iXpos=qRect.width()/2-m_pop->width()/2;
    int iYpos=qRect.height()/2-m_pop->height()/2;
    m_pop->move(iXpos,iYpos);*/
}

#include "kgpglibrary.moc"
