/*
    kopetemimetypehandler.cpp - Kopete mime type handlers

    Copyright (c) 2004      by Richard Smith         <kde@metafoo.co.uk>

    Kopete    (c) 2004      by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#include "kopetemimetypehandler.h"
#include "kopeteglobal.h"
#include "kopeteuiglobal.h"

#include <qwidget.h>

#include "libkopete_debug.h"
#include <KLocalizedString>
#include <kio/netaccess.h>
#include <kmimetype.h>
#include <kmessagebox.h>

#include <kemoticons.h>
#include <kopeteemoticons.h>

namespace Kopete {
namespace {
static QHash<QString, Kopete::MimeTypeHandler *> g_mimeHandlers;
static QHash<QString, Kopete::MimeTypeHandler *> g_protocolHandlers;
}

class MimeTypeHandler::Private
{
public:
    Private(bool carf) : canAcceptRemoteFiles(carf)
    {
    }

    bool canAcceptRemoteFiles;
    QStringList mimeTypes;
    QStringList protocols;
};

MimeTypeHandler::MimeTypeHandler(bool canAcceptRemoteFiles)
    : d(new Private(canAcceptRemoteFiles))
{
}

MimeTypeHandler::~MimeTypeHandler()
{
    for (QStringList::iterator it = d->mimeTypes.begin(); it != d->mimeTypes.end(); ++it) {
        g_mimeHandlers.remove(*it);
    }

    for (QStringList::iterator it = d->protocols.begin(); it != d->protocols.end(); ++it) {
        g_protocolHandlers.remove(*it);
    }

    delete d;
}

bool MimeTypeHandler::registerAsMimeHandler(const QString &mimeType)
{
    if (g_mimeHandlers[ mimeType ]) {
        qCWarning(LIBKOPETE_LOG) << "Warning: Two mime type handlers attempting"
                                    " to handle " << mimeType << endl;
        return false;
    }

    g_mimeHandlers.insert(mimeType, this);
    d->mimeTypes.append(mimeType);
//	qCDebug(LIBKOPETE_LOG) << "Mime type " << mimeType << " registered";
    return true;
}

bool MimeTypeHandler::registerAsProtocolHandler(const QString &protocol)
{
    if (g_protocolHandlers[ protocol ]) {
        qCWarning(LIBKOPETE_LOG) << "Warning: Two protocol handlers attempting"
                                    " to handle " << protocol << endl;
        return false;
    }

    g_protocolHandlers.insert(protocol, this);
    d->protocols.append(protocol);
    qCDebug(LIBKOPETE_LOG) << "Mime type " << protocol << " registered";
    return true;
}

const QStringList MimeTypeHandler::mimeTypes() const
{
    return d->mimeTypes;
}

const QStringList MimeTypeHandler::protocols() const
{
    return d->protocols;
}

bool MimeTypeHandler::canAcceptRemoteFiles() const
{
    return d->canAcceptRemoteFiles;
}

bool MimeTypeHandler::dispatchURL(const QUrl &url)
{
    if (url.isEmpty()) {
        return false;
    }

    QString type = KMimeType::findByUrl(url)->name();

    MimeTypeHandler *mimeHandler = g_mimeHandlers[ type ];

    if (mimeHandler) {
        return dispatchToHandler(url, type, mimeHandler);
    } else {
        mimeHandler = g_protocolHandlers[ url.scheme() ];

        if (mimeHandler) {
            mimeHandler->handleURL(QString(), url);
            return true;
        } else {
            qCDebug(LIBKOPETE_LOG) << "No mime type handler can handle this URL: " << url.toDisplayString();
            return false;
        }
    }
}

bool MimeTypeHandler::dispatchToHandler(const QUrl &url, const QString &mimeType, MimeTypeHandler *handler)
{
    if (!handler->canAcceptRemoteFiles()) {
        QString file;
        if (!KIO::NetAccess::download(url, file, Kopete::UI::Global::mainWidget())) {
            QString sorryText;
            if (url.isLocalFile()) {
                sorryText = i18n("Unable to find the file %1.", url.toDisplayString());
            } else {
                sorryText = i18n("<qt>Unable to download the requested file;<br />"
                                 "please check that address %1 is correct.</qt>",
                                 url.toDisplayString());
            }

            KMessageBox::sorry(Kopete::UI::Global::mainWidget(), sorryText);
            return false;
        }

        QUrl dest;
        dest.setPath(file);

        handler->handleURL(mimeType, dest);

        // for now, local-only handlers have to be synchronous
        KIO::NetAccess::removeTempFile(file);
    } else {
        handler->handleURL(mimeType, url);
    }

    return true;
}

void MimeTypeHandler::handleURL(const QString &mimeType, const QUrl &url) const
{
    Q_UNUSED(mimeType);
    Q_UNUSED(url);
}

void MimeTypeHandler::handleURL(const QUrl &url) const
{
    handleURL(QString(), url);
}

EmoticonMimeTypeHandler::EmoticonMimeTypeHandler()
    : MimeTypeHandler(false)
{
    registerAsMimeHandler(QStringLiteral("application/x-kopete-emoticons"));
    registerAsMimeHandler(QStringLiteral("application/x-compressed-tar"));
    registerAsMimeHandler(QStringLiteral("application/x-bzip-compressed-tar"));
}

void EmoticonMimeTypeHandler::handleURL(const QString &, const QUrl &url) const
{
    Emoticons::self()->installTheme(url.toLocalFile());
}

void EmoticonMimeTypeHandler::handleURL(const QUrl &url) const
{
    handleURL(QString(), url);
}
} // END namespace Kopete

// vim: set noet ts=4 sts=4 sw=4:
