/* ============================================================
 *
 * This file is a part of kipi-plugins project
 * http://www.digikam.org
 *
 * Date        : 2005-12-19
 * Description : a plugin to export image collections using SimpleViewer.
 *
 * Copyright (C) 2005-2006 by Joern Ahrens <joern dot ahrens at kdemail dot net>
 * Copyright (C) 2008-2015 by Gilles Caulier <caulier dot gilles at gmail dot com>
 * Copyright (C) 2011-2013 by Veaceslav Munteanu <slavuttici at gmail dot 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, 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.
 *
 * ============================================================ */

#include "simpleviewer.h"

// Qt includes

#include <QByteArray>
#include <QDataStream>
#include <QDir>
#include <QPointer>
#include <QDomText>
#include <QFile>
#include <QPointer>
#include <QTemporaryDir>
#include <QApplication>
#include <QMessageBox>
#include <QDesktopServices>

// KDE includes

#include <kio/copyjob.h>
#include <kio/job.h>
#include <kjobwidgets.h>
#include <klocalizedstring.h>

// Libkipi includes

#include <KIPI/PluginLoader>

// Local includes

#include "kpversion.h"
#include "kpimageinfo.h"
#include "kipiplugins_debug.h"
#include "kputil.h"

namespace KIPIFlashExportPlugin
{

static QDir makeWritableDir(const QString& subpath)
{
    QString path = QDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).filePath(subpath);
    QDir().mkpath(path);

    return QDir(path);
}

class SimpleViewer::Private
{
public:

    Private() :
        maxThumbSize(45),
        viewer(QStringLiteral("simpleviewer.swf"))
    {
        totalActions = 0;
        action       = 0;
        canceled     = true;
        tempDir      = 0;
        interface    = 0;
        progressWdg  = 0;
        settings     = 0;
        width        = 0;
        height       = 0;
        
        if (interface)
        {
            meta = interface->createMetadataProcessor();
        }
    }

    bool                              canceled;

    int                               totalActions;
    int                               action;

    //size of every image
    int                               width;
    int                               height;


    const int                         maxThumbSize;
    const QString                     viewer;

    QString                           dataDir;
    QString                           dataLocal;
    QString                           hostName;
    QString                           hostUrl;
    QStringList                       simpleViewerFiles;

    QTemporaryDir*                    tempDir;

    Interface*                        interface;
    QPointer<MetadataProcessor>       meta;

    KPBatchProgressWidget*            progressWdg;

    SimpleViewerSettingsContainer*    settings;
};

SimpleViewer::SimpleViewer(Interface* const interface, QObject* const parent)
    : QObject(parent),
      d(new Private)
{
    d->interface = interface;
    d->hostName  = QStringLiteral("Kipi-plugins");
    d->hostUrl   = QStringLiteral("https://projects.kde.org/projects/extragear/graphics/kipi-plugins");
}

SimpleViewer::~SimpleViewer()
{
    delete d->tempDir;
    delete d;
}

void SimpleViewer::appendPluginFiles(int pluginType)
{
    qCDebug(KIPIPLUGINS_LOG) << "Value of plugin type in append files" << pluginType;

    switch (pluginType)
    {
        case 0:
            d->simpleViewerFiles.clear();
            d->simpleViewerFiles.append(QStringLiteral("web/svcore/swf/simpleviewer.swf"));
            d->simpleViewerFiles.append(QStringLiteral("web/svcore/js/swfobject.js"));
            d->dataLocal = makeWritableDir(QStringLiteral("kipiplugin_flashexport/simpleviewer/")).absolutePath() + QStringLiteral("/");
            d->dataDir   = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                  QStringLiteral("kipiplugin_flashexport/simpleviewer/"));
            qCDebug(KIPIPLUGINS_LOG) << "Data dir when set is " << d->dataDir;
            break;
        case 1:
            d->simpleViewerFiles.clear();
            d->simpleViewerFiles.append(QStringLiteral("autoviewer.swf"));
            d->simpleViewerFiles.append(QStringLiteral("swfobject.js"));
            d->dataLocal = makeWritableDir(QStringLiteral("kipiplugin_flashexport/autoviewer/")).absolutePath() + QStringLiteral("/");
            d->dataDir   = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                  QStringLiteral("kipiplugin_flashexport/autoviewer/"));
            break;
        case 2:
            d->simpleViewerFiles.clear();
            d->simpleViewerFiles.append(QStringLiteral("TiltViewer.swf"));
            d->simpleViewerFiles.append(QStringLiteral("swfobject.js"));
            d->dataLocal = makeWritableDir(QStringLiteral("kipiplugin_flashexport/tiltviewer/")).absolutePath() + QStringLiteral("/");
            d->dataDir   = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                  QStringLiteral("kipiplugin_flashexport/tiltviewer/"));
            break;
        case 3:
            d->simpleViewerFiles.clear();
            d->simpleViewerFiles.append(QStringLiteral("viewer.swf"));
            d->simpleViewerFiles.append(QStringLiteral("swfobject.js"));
            d->dataLocal = makeWritableDir(QStringLiteral("kipiplugin_flashexport/postcardviewer/")).absolutePath() + QStringLiteral("/");
            d->dataDir   = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                  QStringLiteral("kipiplugin_flashexport/postcardviewer/"));
            break;
        default:
            break;
    }
}

void SimpleViewer::initProgressWdg() const
{
    d->progressWdg = new KPBatchProgressWidget(QApplication::activeWindow());
    qCDebug(KIPIPLUGINS_LOG) << "progress dialog initialized";
}

void SimpleViewer::startExport()
{
    if (d->canceled)
        return;

     qCDebug(KIPIPLUGINS_LOG) << "SimpleViewer started...";
    // Estimate the number of actions for the KIPIPlugins progress dialog.
    d->progressWdg->addedAction(i18n("Initialising..."), StartingMessage);
    d->totalActions    = 0;
    d->action          = 0;
    d->progressWdg->reset();

    if (d->settings->imgGetOption == 0)
    {
        for( QList<ImageCollection>::ConstIterator it = d->settings->collections.constBegin() ;
            !d->canceled && (it != d->settings->collections.constEnd()) ; ++it )
        {
            d->totalActions += (*it).images().count();
        }
    }
    else
    {
        d->totalActions += d->settings->imageDialogList.count();
    }

    // +copying SimpleViewer, +creating index.html
    d->totalActions += 2;

    d->progressWdg->setProgress(0, d->totalActions);

    slotProcess();
}

void SimpleViewer::slotCancel()
{
    d->progressWdg->addedAction(i18n("Export canceled"), ErrorMessage);
    d->canceled = true;
}

void SimpleViewer::slotProcess()
{
    if (d->canceled)
        return;

    if (!d->canceled && !createExportDirectories())
    {
            d->progressWdg->addedAction(i18n("Failed to create export directories"),
                                       ErrorMessage);
        return;
    }

    if (!d->canceled && !exportImages())
    {
        d->progressWdg->addedAction(i18n("Failed to export the images"),
                                   ErrorMessage);
        return;
    }

    if (!d->canceled && !createIndex())
    {
        d->progressWdg->addedAction(i18n("Failed to create index.html"),
                                   ErrorMessage);
        return;
    }

    if (!d->canceled && !copySimpleViewer())
    {
        d->progressWdg->addedAction(i18n("Failed to copy SimpleViewer files"),
                                   ErrorMessage);
        return;
    }

    if (!d->canceled && !upload())
    {
        d->progressWdg->addedAction(i18n("Failed to upload the gallery"),
                                   ErrorMessage);
        return;
    }

    if (d->canceled)
    {

        int ret = QMessageBox::warning(QApplication::activeWindow(),
                                       i18n("Export was canceled"),
                                       i18n("Do you want to delete files in %1 that have already been created?",
                                            d->settings->exportUrl.path()),
                                       QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No));
        if (ret == QMessageBox::Yes)
        {
            auto deleteJob = KIO::file_delete(d->settings->exportUrl);
            KJobWidgets::setWindow(deleteJob, QApplication::activeWindow());
            deleteJob->exec();
        }
    }

    if (!d->canceled)
    {
        d->progressWdg->addedAction(i18nc("Flash export has finished", "Finished..."),
                                    SuccessMessage);
        emit signalProcessingDone();

        if (d->settings->openInKonqueror)
            QDesktopServices::openUrl(d->settings->exportUrl);
    }
}

bool SimpleViewer::createExportDirectories() const
{
    delete d->tempDir;
    d->tempDir = new QTemporaryDir(makeTemporaryDir("kipi-flashexport").absolutePath());
    d->tempDir->setAutoRemove(true);

    d->progressWdg->addedAction(i18n("Creating directories..."), StartingMessage);

    QUrl root = d->settings->exportUrl;
    qCDebug(KIPIPLUGINS_LOG) << "export url is" << root.url();

    auto mkdirJob = KIO::mkdir(root);
    KJobWidgets::setWindow(mkdirJob, QApplication::activeWindow());

    if (!mkdirJob->exec())
    {
        d->progressWdg->addedAction(i18n("Could not create folder '%1'", root.url()),
                                    ErrorMessage);
        return false;
    }

    if (d->settings->plugType == 0)
    {
        QUrl thumbsDir = QUrl(d->tempDir->path());
        thumbsDir.setPath(thumbsDir.path() + QStringLiteral("/thumbs"));

        auto mkdirJob2 = KIO::mkdir(thumbsDir);
        KJobWidgets::setWindow(mkdirJob2, QApplication::activeWindow());

        if (!mkdirJob2->exec())
        {
            d->progressWdg->addedAction(i18n("Could not create folder '%1'", thumbsDir.url()),
                                   ErrorMessage);
            return false;
        }
    }

    QUrl imagesDir = QUrl(d->tempDir->path());

    qCDebug(KIPIPLUGINS_LOG) << "image folder url is" << imagesDir.url();

    auto mkdirJob3 = KIO::mkdir(imagesDir);
    KJobWidgets::setWindow(mkdirJob3, QApplication::activeWindow());

    if (!mkdirJob3->exec())
    {
        d->progressWdg->addedAction(i18n("Could not create folder '%1'", imagesDir.url()),
                                    ErrorMessage);
        return false;
    }

    d->progressWdg->addedAction(i18n("Finished Creating directories..."), StartingMessage);
    d->progressWdg->setProgress(++d->action, d->totalActions);

    return true;
}

bool SimpleViewer::cmpUrl(const QUrl& url1, const QUrl& url2)
{
    QPointer<MetadataProcessor> meta = 0;
    PluginLoader* const pl           = PluginLoader::instance();
    
    if (pl)
    {
        Interface* const iface = pl->interface();
        
        if (iface)
            meta = iface->createMetadataProcessor();
    }
    
    if (!meta)
        return cmpUrlByName(url1, url2);
    
    if (!meta->load(url1))
        return cmpUrlByName(url1, url2);
    
    QDateTime clock1 = meta->getImageDateTime();

    if (!meta->load(url2))
        return cmpUrlByName(url1, url2);

    QDateTime clock2 = meta->getImageDateTime();

    if (clock1.isValid() || clock2.isValid())
    {
        return (clock1 < clock2);
    }

    return cmpUrlByName(url1, url2);
}

bool SimpleViewer::cmpUrlByName(const QUrl& url1, const QUrl& url2)
{
    QString name1 = url1.fileName();
    QString name2 = url2.fileName();

    return (name1 < name2);
}

bool SimpleViewer::exportImages()
{
    if (d->canceled)
        return false;

    d->progressWdg->addedAction(i18n("Creating images and thumbnails..."), StartingMessage);

    QUrl xmlFile(d->tempDir->path());

    QFile file(xmlFile.path());
    file.open(QIODevice::WriteOnly);

    // header of gallery.xml
    QDomElement  galleryElem;
    QDomElement  photosElem;
    QDomDocument xmlDoc;
    xmlDoc.appendChild(xmlDoc.createProcessingInstruction( QStringLiteral("xml"),
                       QStringLiteral("version=\"1.0\" encoding=\"UTF-8\"") ) );

    switch (d->settings->plugType)
    {
        case 0:
        {
            galleryElem = xmlDoc.createElement(QStringLiteral("simpleviewerGallery"));
            xmlDoc.appendChild( galleryElem );
            galleryElem.setAttribute(QStringLiteral("enableRightClickOpen"),
                                     d->settings->enableRightClickToOpen());
            galleryElem.setAttribute(QStringLiteral("maxImageWidth"),
                                     d->settings->maxImageDimension);
            galleryElem.setAttribute(QStringLiteral("maxImageHeight"),
                                     d->settings->maxImageDimension);
            galleryElem.setAttribute(QStringLiteral("textColor"),
                                     d->settings->textColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            galleryElem.setAttribute(QStringLiteral("frameColor"),
                                     d->settings->frameColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            galleryElem.setAttribute(QStringLiteral("bgColor"),
                                     d->settings->backgroundColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            galleryElem.setAttribute(QStringLiteral("frameWidth"),
                                     d->settings->frameWidth);
            galleryElem.setAttribute(QStringLiteral("stagePadding"),
                                     d->settings->stagePadding);
            galleryElem.setAttribute(QStringLiteral("thumbnailColumns"),
                                     d->settings->thumbnailColumns);
            galleryElem.setAttribute(QStringLiteral("thumbnailRows"),
                                     d->settings->thumbnailRows);
            galleryElem.setAttribute(QStringLiteral("navPosition"),
                                     d->settings->thumbPosition());
            galleryElem.setAttribute(QStringLiteral("title"),                d->settings->title);
            galleryElem.setAttribute(QStringLiteral("imagePath"),            QStringLiteral("images/"));
            galleryElem.setAttribute(QStringLiteral("thumbPath"),            QStringLiteral("thumbs/"));
            break;
        }
        case 1:
        {
            galleryElem = xmlDoc.createElement(QStringLiteral("gallery"));
            xmlDoc.appendChild( galleryElem );
            galleryElem.setAttribute(QStringLiteral("enableRightClickOpen"),
                                     d->settings->enableRightClickToOpen());
            galleryElem.setAttribute(QStringLiteral("imagePadding"),
                                     d->settings->imagePadding);
            galleryElem.setAttribute(QStringLiteral("displayTime"),
                                     d->settings->displayTime);
            galleryElem.setAttribute(QStringLiteral("frameWidth"),
                                     d->settings->frameWidth);
            galleryElem.setAttribute(QStringLiteral("frameColor"),
                                     d->settings->frameColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            galleryElem.setAttribute(QStringLiteral("bgColor"),
                                     d->settings->backgroundColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            break;
        }
        case 2:
        {
            galleryElem = xmlDoc.createElement(QStringLiteral("tiltviewergallery"));
            xmlDoc.appendChild( galleryElem );
            photosElem  = xmlDoc.createElement(QStringLiteral("photos"));
            galleryElem.appendChild( photosElem);
            break;
        }
        case 3:
        {
            galleryElem = xmlDoc.createElement(QStringLiteral("gallery"));
            xmlDoc.appendChild( galleryElem );
            galleryElem.setAttribute(QStringLiteral("enableRightClickOpen"),
                                     d->settings->enableRightClickToOpen());
            galleryElem.setAttribute(QStringLiteral("cellDimension"),
                                     d->settings->cellDimension);
            galleryElem.setAttribute(QStringLiteral("columns"),
                                     d->settings->thumbnailColumns);
            galleryElem.setAttribute(QStringLiteral("captionColor"),
                                     d->settings->textColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            galleryElem.setAttribute(QStringLiteral("zoomInPerc"),
                                     d->settings->zoomInPerc);
            galleryElem.setAttribute(QStringLiteral("zoomOutPerc"),
                                     d->settings->zoomOutPerc);
            galleryElem.setAttribute(QStringLiteral("frameWidth"),
                                     d->settings->frameWidth);
            galleryElem.setAttribute(QStringLiteral("frameColor"),
                                     d->settings->frameColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            galleryElem.setAttribute(QStringLiteral("bgColor"),
                                     d->settings->backgroundColor.name().replace(QLatin1Char('#'), QStringLiteral("0x")));
            break;
        }

        default:
            break;
    }

    if (d->settings->imgGetOption == 0)
    {
        for( QList<ImageCollection>::ConstIterator it = d->settings->collections.constBegin() ;
            !d->canceled && (it != d->settings->collections.constEnd()) ; ++it )
        {
            QList<QUrl> images = (*it).images();
            processQUrlList(images,xmlDoc,galleryElem,photosElem);
        }
    }
    else
    {
        QList<QUrl> images = d->settings->imageDialogList;
        processQUrlList(images,xmlDoc,galleryElem,photosElem);
    }

    QByteArray data(xmlDoc.toByteArray());
    QDataStream stream( &file );
    stream.writeRawData(data.data(), data.size());
    file.close();

    return true;
}
void SimpleViewer::processQUrlList(QList<QUrl>& images, QDomDocument& xmlDoc,
                                   QDomElement& galleryElem, QDomElement& photosElem)
{
    QImage     image;
    QImage     thumbnail;
    QString    tmp;
    QString    newName;

    int index           = 1;
    int maxSize         = d->settings->imagesExportSize;
    bool resizeImages   = d->settings->resizeExportImages;
    bool fixOrientation = d->settings->fixOrientation;

    QUrl thumbsDir(d->tempDir->path());
    thumbsDir.setPath(thumbsDir.path() + QStringLiteral("/thumbs"));

    QUrl imagesDir(d->tempDir->path());
    imagesDir.setPath(imagesDir.path() + QStringLiteral("/images"));

    qSort(images.begin(), images.end(), cmpUrl);

    for (QList<QUrl>::ConstIterator it = images.constBegin();
         !d->canceled && (it != images.constEnd()) ; ++it)
    {
        QApplication::processEvents();
        QUrl url = *it;
        QFileInfo fi(url.path());

        //video can't be exported, need to add for all video files
        if (fi.suffix().toUpper() == QStringLiteral("MOV"))
            continue;

        d->progressWdg->addedAction(i18n("Processing %1", url.fileName()), StartingMessage);

        // Check if RAW file.
        if (d->interface)
        {
            QPointer<RawProcessor> rawdec = d->interface->createRawProcessor();

            // check if its a RAW file.
            if (rawdec && rawdec->isRawFile(url))
            {
                rawdec->loadRawPreview(url, image);
            }
        }

        if (image.isNull())
        {
            image.load(url.path());
        }

        if (image.isNull())
        {
            d->progressWdg->addedAction(i18n("Could not open image '%1'", url.fileName()),
                                        WarningMessage);
            continue;
        }

        if (d->settings->plugType == 0)
        {
            // Thumbnails are generated only for simpleviewer plugin

            if (!createThumbnail(image, thumbnail))
            {
                d->progressWdg->addedAction(i18n("Could not create thumbnail from '%1'", url.fileName()),
                                        WarningMessage);
                continue;
            }
        }

        if (resizeImages && !resizeImage(image, maxSize, image))
        {
            d->progressWdg->addedAction(i18n("Could not resize image '%1'", url.fileName()),
                                        WarningMessage);
            continue;
        }

        if (d->meta && d->meta->load(url))
        {
            bool rotated = false;
            newName      = QStringLiteral("%1.%2").arg(tmp.sprintf("%03i", index)).arg(QStringLiteral("jpg"));

            if (d->settings->plugType == 0)
            {
                QUrl thumbnailPath(thumbsDir);
                thumbnailPath.setPath(thumbnailPath.path() + newName);

                if (resizeImages && fixOrientation)
                    d->meta->rotateExifQImage(thumbnail, d->meta->getImageOrientation());

                thumbnail.save(thumbnailPath.path(), "JPEG");
            }

            QUrl imagePath(imagesDir);
            imagePath.setPath(imagePath.path() + newName);

            if (resizeImages && fixOrientation)
                rotated = d->meta->rotateExifQImage(image, d->meta->getImageOrientation());

            image.save(imagePath.path(), "JPEG");

            // Backup metadata from original image.
            d->meta->setImageProgramId(QStringLiteral("Kipi-plugins"), kipipluginsVersion());
            d->meta->setImageDimensions(image.size());

            if (rotated)
                d->meta->setImageOrientation(MetadataProcessor::NORMAL);

            d->meta->save(imagePath);
        }
        
        d->width  = image.width();
        d->height = image.height();

        if (d->settings->plugType!=2)
            cfgAddImage(xmlDoc, galleryElem, url, newName);
        else
            cfgAddImage(xmlDoc, photosElem, url, newName);

        d->progressWdg->setProgress(++d->action, d->totalActions);
        index++;
    }
}
bool SimpleViewer::createThumbnail(const QImage& image, QImage& thumbnail) const
{
    int w = image.width();
    int h = image.height();

    int maxSize = 0;

    if (w > d->maxThumbSize || h > d->maxThumbSize)
    {
        if (w > h)
        {
            maxSize = (int)(double)(w * d->maxThumbSize) / h;
        }
        else
        {
            maxSize = (int)(double)(h * d->maxThumbSize) / w;
        }
    }

    maxSize = (maxSize < d->maxThumbSize) ? d->maxThumbSize : maxSize;

    return resizeImage(image, maxSize, thumbnail);
}

bool SimpleViewer::resizeImage(const QImage& image, int maxSize, QImage& resizedImage) const
{
    int w = image.width();
    int h = image.height();

    if (w > maxSize || h > maxSize)
    {
        if (w > h)
        {
            h = (int)(double)(h * maxSize) / w;
            h = (h == 0) ? 1 : h;
            w = maxSize;
        }
        else
        {
            w = (int)(double)(w * maxSize) / h;
            w = (w == 0) ? 1 : w;
            h = maxSize;
        }

        resizedImage = image.scaled(w, h, Qt::KeepAspectRatio,
                                          Qt::SmoothTransformation);
    }

    return true;
}

void SimpleViewer::cfgAddImage(QDomDocument& xmlDoc, QDomElement& galleryElem,
                               const QUrl& url, const QString& newName) const
{
    if (d->canceled)
        return;

    QString comment;
    QString keywords;

    KPImageInfo info(url);

    if (d->settings->showComments)
    {
        comment = info.description();
    }
    else
    {
        comment.clear();
    }
    if (d->settings->showKeywords)
    {
        QStringList tagList = info.keywords();

        if (!tagList.join(QStringLiteral(" ")).isEmpty())
            keywords = QStringLiteral("\nTags: ") + tagList.join(QStringLiteral(", "));
    }
    else
    {
        keywords.clear();
    }

    switch (d->settings->plugType)
    {
        case 0: //Simpleviewer
        {

            QDomElement img      = xmlDoc.createElement(QStringLiteral("image"));
            galleryElem.appendChild(img);
            img.setAttribute(QStringLiteral("imageURL"), QStringLiteral("images/")+newName);
            img.setAttribute(QStringLiteral("thumbURL"), QStringLiteral("thumbs/")+newName);
            img.setAttribute(QStringLiteral("linkURL"), QString());
            img.setAttribute(QStringLiteral("targetURL"), QString());

            QDomElement caption1 = xmlDoc.createElement(QStringLiteral("caption"));
            img.appendChild(caption1);

            QDomText captiontxt1 = xmlDoc.createTextNode(comment+keywords);
            caption1.appendChild(captiontxt1);
            break;
        }

        case 1: //Autoviewer
        {
            QDomElement img        = xmlDoc.createElement(QStringLiteral("image"));

            galleryElem.appendChild(img);

            QDomElement urlElem    = xmlDoc.createElement(QStringLiteral("url"));
            img.appendChild(urlElem);
            QDomText    urlText    = xmlDoc.createTextNode(QStringLiteral("images/") + newName);
            urlElem.appendChild(urlText);

            QDomElement caption2   = xmlDoc.createElement(QStringLiteral("caption"));
            img.appendChild( caption2 );
            QDomText captiontxt2   = xmlDoc.createTextNode(comment+keywords);
            caption2.appendChild(captiontxt2);

            QDomElement widthElem  = xmlDoc.createElement(QStringLiteral("width"));
            img.appendChild(widthElem);

            QDomText    widthText  = xmlDoc.createTextNode(QString::number(d->width));

            widthElem.appendChild(widthText);

            QDomElement heightElem = xmlDoc.createElement(QStringLiteral("height"));
            img.appendChild(heightElem);

            QDomText    heightText = xmlDoc.createTextNode(QString::number(d->height));
            heightElem.appendChild(heightText);
            break;
        }

        case 2: //TiltWiever
        {
            QDomElement img       = xmlDoc.createElement(QStringLiteral("photo"));
            galleryElem.appendChild(img);
            img.setAttribute(QStringLiteral("imageurl"), QStringLiteral("images/")+newName);
            img.setAttribute(QStringLiteral("linkurl"), QString());

            QDomElement titleElem = xmlDoc.createElement(QStringLiteral("title"));
            img.appendChild(titleElem);
            QDomText    titleText = xmlDoc.createTextNode(newName);
            titleElem.appendChild(titleText);

            QDomElement caption1  = xmlDoc.createElement(QStringLiteral("description"));
            img.appendChild(caption1);

            QDomText captiontxt1  = xmlDoc.createTextNode(comment+keywords);
            caption1.appendChild(captiontxt1);
            break;
        }

        case 3: //PostcardViewer
        {
            QDomElement img      = xmlDoc.createElement(QStringLiteral("image"));
            galleryElem.appendChild(img);

            QDomElement urlElem  = xmlDoc.createElement(QStringLiteral("url"));
            img.appendChild(urlElem);
            QDomText    urlText  = xmlDoc.createTextNode(QStringLiteral("images/") + newName);
            urlElem.appendChild(urlText);

            QDomElement caption2 = xmlDoc.createElement(QStringLiteral("caption"));
            img.appendChild( caption2 );
            QDomText captiontxt2 = xmlDoc.createTextNode(comment+keywords);
            caption2.appendChild(captiontxt2);
            break;
        }

        default:
            break;
    }
}

bool SimpleViewer::createIndex() const
{
    if (d->canceled)
        return false;

    d->progressWdg->addedAction(i18n("Creating index.html..."), StartingMessage);

    switch(d->settings->plugType)
    {
        case 0:
        {
            QString indexTemplateName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                               QStringLiteral("kipiplugin_flashexport/index.template"));
            if (indexTemplateName.isEmpty())
            {
                //TODO: errormsg
                qCDebug(KIPIPLUGINS_LOG) << "No indexTemplateName" ;
                return false;
            }

            QFile infile(indexTemplateName);
            infile.open(QIODevice::ReadOnly);
            QTextStream in(&infile);
            QString indexTemplate = in.readAll();
            infile.close();

            indexTemplate.replace(QStringLiteral("{TITLE}"),    d->settings->title);
            indexTemplate.replace(QStringLiteral("{COLOR}"),    d->settings->textColor.name());
            indexTemplate.replace(QStringLiteral("{BGCOLOR}"),  d->settings->backgroundColor.name());
            indexTemplate.replace(QStringLiteral("{HOSTURL}"),  d->hostUrl);
            indexTemplate.replace(QStringLiteral("{HOSTNAME}"), d->hostName);

            QFile outfile(d->tempDir->path() + QStringLiteral("/index.html"));
            outfile.open(QIODevice::WriteOnly);
            QTextStream out(&outfile);
            out << indexTemplate;
            outfile.close();
            break;
        }

        case 1:
        {
            QString indexTemplateName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                               QStringLiteral("kipiplugin_flashexport/index2.template"));
            if (indexTemplateName.isEmpty())
            {
                //TODO: errormsg
                qCDebug(KIPIPLUGINS_LOG) << "No indexTemplateName" ;
                return false;
            }

            QFile infile(indexTemplateName);
            infile.open(QIODevice::ReadOnly);
            QTextStream in(&infile);
            QString indexTemplate = in.readAll();
            infile.close();

            indexTemplate.replace(QStringLiteral("{TITLE}"),    d->settings->title);
            indexTemplate.replace(QStringLiteral("{COLOR}"),    d->settings->textColor.name());
            indexTemplate.replace(QStringLiteral("{BGCOLOR}"),  d->settings->backgroundColor.name());
            //indexTemplate.replace("{HOSTNAME}", d->hostName);
            //indexTemplate.replace("{HOSTURL}",  d->hostUrl);

            QFile outfile(d->tempDir->path() + QStringLiteral("/index.html"));
            outfile.open(QIODevice::WriteOnly);
            QTextStream out(&outfile);
            out << indexTemplate;
            outfile.close();
            break;
        }

        case 2:
        {
            QString indexTemplateName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                               QStringLiteral("kipiplugin_flashexport/index3.template"));
            if (indexTemplateName.isEmpty())
            {
                //TODO: errormsg
                qCDebug(KIPIPLUGINS_LOG) << "No indexTemplateName" ;
                return false;
            }

            QFile infile(indexTemplateName);
            infile.open(QIODevice::ReadOnly);
            QTextStream in(&infile);
            QString indexTemplate = in.readAll();
            infile.close();

            indexTemplate.replace(QStringLiteral("{TITLE}"),    d->settings->title);
            indexTemplate.replace(QStringLiteral("{COLOR}"),    d->settings->textColor.name());

            if (d->settings->useReloadButton)
                indexTemplate.replace(QStringLiteral("{RELOADBUTTON}"), QStringLiteral("true"));
            else
                indexTemplate.replace(QStringLiteral("{RELOADBUTTON}"), QStringLiteral("false"));

            if (d->settings->showFlipButton)
                indexTemplate.replace(QStringLiteral("{FLIPBUTTON}"), QStringLiteral("true"));
            else
                indexTemplate.replace(QStringLiteral("{FLIPBUTTON}"), QStringLiteral("false"));

            indexTemplate.replace(QStringLiteral("{SIZE}"),
                                  QString::number(d->settings->maxImageDimension));
            indexTemplate.replace(QStringLiteral("{COLUMN}"),
                                  QString::number(d->settings->thumbnailColumns));
            indexTemplate.replace(QStringLiteral("{ROW}"),
                                  QString::number(d->settings->thumbnailRows));
            indexTemplate.replace(QStringLiteral("{FRAMECOLOR}"),
                                  d->settings->frameColor.name().replace(
                                      QLatin1Char('#'), QStringLiteral("0x")));
            indexTemplate.replace(QStringLiteral("{BACKINCOLOR}"),
                                  d->settings->bkgndInnerColor.name().replace(
                                      QLatin1Char('#'), QStringLiteral("0x")));
            indexTemplate.replace(QStringLiteral("{BACKCOLOR}"),
                                  d->settings->backColor.name().replace(
                                      QLatin1Char('#'), QStringLiteral("0x")));
            indexTemplate.replace(QStringLiteral("{BACKOUTCOLOR}"),
                                  d->settings->bkgndOuterColor.name().replace(
                                      QLatin1Char('#'), QStringLiteral("0x")));

            QFile outfile(d->tempDir->path() + QStringLiteral("/index.html"));
            outfile.open(QIODevice::WriteOnly);
            QTextStream out(&outfile);
            out << indexTemplate;
            outfile.close();
            break;
        }
        case 3:
        {
            QString indexTemplateName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
                                                               QStringLiteral("kipiplugin_flashexport/index4.template"));
            if (indexTemplateName.isEmpty())
            {
                //TODO: errormsg
                qCDebug(KIPIPLUGINS_LOG) << "No indexTemplateName" ;
                return false;
            }

            QFile infile(indexTemplateName);
            infile.open(QIODevice::ReadOnly);
            QTextStream in(&infile);
            QString indexTemplate = in.readAll();
            infile.close();

            indexTemplate.replace(QStringLiteral("{TITLE}"),    d->settings->title);
            indexTemplate.replace(QStringLiteral("{COLOR}"),    d->settings->textColor.name());
            indexTemplate.replace(QStringLiteral("{BGCOLOR}"),  d->settings->backgroundColor.name());

            QFile outfile(d->tempDir->path() + QStringLiteral("/index.html"));
            outfile.open(QIODevice::WriteOnly);
            QTextStream out(&outfile);
            out << indexTemplate;
            outfile.close();
            break;
        }

        default:
            break;
    }

    d->progressWdg->setProgress(++d->action, d->totalActions);
    d->progressWdg->addedAction(i18n("index.html created..."), SuccessMessage);

    return true;
}

bool SimpleViewer::copySimpleViewer() const
{
    if (d->canceled)
        return false;

    d->progressWdg->addedAction(i18n("Copying flash files..."), StartingMessage);

    // Due to its license, simpleviewer is installed in $KDEHOME
    QList<QUrl>  files;
    QStringList entries;
    QDir        dir;

    dir.setPath(d->dataDir);
    qCDebug(KIPIPLUGINS_LOG) << "Data dir is " << d->dataDir; 
    entries = dir.entryList(QDir::Files);

    for (QStringList::ConstIterator it = entries.constBegin(); it != entries.constEnd(); ++it)
    {
        files.append(QUrl(dir.absolutePath() + QLatin1Char('/') + *it));
    }

    // TODO: catch errors
    /*KIO::CopyJob *copyJob =*/ KIO::copy(files, d->settings->exportUrl, KIO::HideProgressInfo);

    d->progressWdg->addedAction(i18n("Flash files copied..."), SuccessMessage);

    return true;
}

bool SimpleViewer::upload() const
{
    if (d->canceled)
        return false;

    d->progressWdg->addedAction(i18n("Uploading gallery..."), StartingMessage);

    auto dircopyJob = KIO::copy(QUrl(d->tempDir->path() + QStringLiteral("./")), d->settings->exportUrl);
    KJobWidgets::setWindow(dircopyJob, 0);
    dircopyJob->exec();

    if (!dircopyJob->exec())
        return false;

    d->progressWdg->addedAction(i18n("Gallery uploaded..."), SuccessMessage);

    return true;
}

bool SimpleViewer::unzip(const QString& url) const
{
    KZip zip(url);

    if (!openArchive(zip))
    {
        qCDebug(KIPIPLUGINS_LOG) << "Cannot open zip archive" ;
        return false;
    }

    return extractArchive(zip);
}

bool SimpleViewer::openArchive(KZip& zip) const
{
    if (!zip.open(QIODevice::ReadOnly))
    {
        qCDebug(KIPIPLUGINS_LOG) << "Open archive failed\n";
        return false;
    }

    return true;
}

bool SimpleViewer::extractArchive(KZip& zip) const
{
    // read root directory content
    QStringList names = zip.directory()->entries();

    if (names.count() != 1)
    {
        qCDebug(KIPIPLUGINS_LOG) << "Wrong SimpleViewer Version or corrupted archive" ;
        qCDebug(KIPIPLUGINS_LOG) << "Content of the archive root folder" << names ;
        return false;
    }

    // open root directory
    const KArchiveEntry* const root = zip.directory()->entry(names[0]);

    if (!root || !root->isDirectory())
    {
        qCDebug(KIPIPLUGINS_LOG) << "could not open " << names[0] << " of zipname" ;
        return false;
    }

    const KArchiveDirectory* const dir = dynamic_cast<const KArchiveDirectory*>(root);

    // extract the needed files from SimpleViewer archive
    for (QStringList::ConstIterator it = d->simpleViewerFiles.constBegin();
         it != d->simpleViewerFiles.constEnd(); ++it )
    {
        const KArchiveEntry* const entry = dir->entry(*it);

        if (!extractFile(entry))
        {
            //TODO error msg
            qCDebug(KIPIPLUGINS_LOG) << "could not open " << *it << " of zipname" ;
            return false;
        }
    }

    return true;
}

bool SimpleViewer::extractFile(const KArchiveEntry* entry) const
{
    if ( !entry || !entry->isFile() )
        return false;

    const KArchiveFile* const entryFile = dynamic_cast<const KArchiveFile*>(entry);

    if (entryFile == NULL)
        return false;

    QByteArray array = entryFile->data();

    QFile file( d->dataLocal + entry->name() );

    if (file.open( QIODevice::WriteOnly ))
    {
        int ret = file.write(array);
        file.close();
        return ret > 0 ? true : false;
    }

    return false;
}

KPBatchProgressWidget* SimpleViewer::progressWidget() const
{
    initProgressWdg();
    return d->progressWdg;
}

void SimpleViewer::setSettings(SimpleViewerSettingsContainer* const setting)
{
    d->settings = setting;
    d->canceled = false;

    qCDebug(KIPIPLUGINS_LOG) << "Settings reached SimpleViewer";
}

} // namespace KIPIFlashExportPlugin
