/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qxcbmime.h"

#include <QtCore/QTextCodec>
#include <QtGui/QImageWriter>
#include <QtCore/QBuffer>
#include <qdebug.h>

QT_BEGIN_NAMESPACE

QXcbMime::QXcbMime()
    : QInternalMimeData()
{ }

QXcbMime::~QXcbMime()
{}



QString QXcbMime::mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
{
    if (a == XCB_NONE)
        return QString();

    // special cases for string type
    if (a == XCB_ATOM_STRING
        || a == connection->atom(QXcbAtom::UTF8_STRING)
        || a == connection->atom(QXcbAtom::TEXT))
        return QLatin1String("text/plain");

    // special case for images
    if (a == XCB_ATOM_PIXMAP)
        return QLatin1String("image/ppm");

    QByteArray atomName = connection->atomName(a);

    // special cases for uris
    if (atomName == "text/x-moz-url")
        atomName = "text/uri-list";

    return QString::fromLatin1(atomName.constData());
}

bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
                               xcb_atom_t *atomFormat, int *dataFormat)
{
    if (!data)
        return false;

    bool ret = false;
    *atomFormat = a;
    *dataFormat = 8;

    if ((a == connection->atom(QXcbAtom::UTF8_STRING)
         || a == XCB_ATOM_STRING
         || a == connection->atom(QXcbAtom::TEXT))
        && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
        if (a == connection->atom(QXcbAtom::UTF8_STRING)) {
            *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
            ret = true;
        } else if (a == XCB_ATOM_STRING ||
                   a == connection->atom(QXcbAtom::TEXT)) {
            // ICCCM says STRING is latin1
            *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
                        QLatin1String("text/plain"), mimeData)).toLatin1();
            ret = true;
        }
        return ret;
    }

    QString atomName = mimeAtomToString(connection, a);
    if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
        *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
        // mimeAtomToString() converts "text/x-moz-url" to "text/uri-list",
        // so QXcbConnection::atomName() has to be used.
        if (atomName == QLatin1String("text/uri-list")
            && connection->atomName(a) == "text/x-moz-url") {
            const QString mozUri = QLatin1String(data->split('\n').constFirst()) + QLatin1Char('\n');
            *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()),
                               mozUri.length() * 2);
        } else if (atomName == QLatin1String("application/x-color"))
            *dataFormat = 16;
        ret = true;
    } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
        ret = true;
    } else if (atomName == QLatin1String("text/plain")
               && mimeData->hasFormat(QLatin1String("text/uri-list"))) {
        // Return URLs also as plain text.
        *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
        ret = true;
    }
    return ret;
}

QVector<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
{
    QVector<xcb_atom_t> atoms;
    atoms.reserve(7);
    atoms.append(connection->internAtom(format.toLatin1()));

    // special cases for strings
    if (format == QLatin1String("text/plain")) {
        atoms.append(connection->atom(QXcbAtom::UTF8_STRING));
        atoms.append(XCB_ATOM_STRING);
        atoms.append(connection->atom(QXcbAtom::TEXT));
    }

    // special cases for uris
    if (format == QLatin1String("text/uri-list")) {
        atoms.append(connection->internAtom("text/x-moz-url"));
        atoms.append(connection->internAtom("text/plain"));
    }

    //special cases for images
    if (format == QLatin1String("image/ppm"))
        atoms.append(XCB_ATOM_PIXMAP);
    if (format == QLatin1String("image/pbm"))
        atoms.append(XCB_ATOM_BITMAP);

    return atoms;
}

QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &d, const QString &format,
                                       QVariant::Type requestedType, const QByteArray &encoding)
{
    QByteArray data = d;
    QString atomName = mimeAtomToString(connection, a);
//    qDebug() << "mimeConvertDataToFormat" << format << atomName << data;

    if (!encoding.isEmpty()
        && atomName == format + QLatin1String(";charset=") + QLatin1String(encoding)) {

#if QT_CONFIG(textcodec)
        if (requestedType == QVariant::String) {
            QTextCodec *codec = QTextCodec::codecForName(encoding);
            if (codec)
                return codec->toUnicode(data);
        }
#endif

        return data;
    }

    // special cases for string types
    if (format == QLatin1String("text/plain")) {
        if (data.endsWith('\0'))
            data.chop(1);
        if (a == connection->atom(QXcbAtom::UTF8_STRING)) {
            return QString::fromUtf8(data);
        }
        if (a == XCB_ATOM_STRING ||
            a == connection->atom(QXcbAtom::TEXT))
            return QString::fromLatin1(data);
    }
    // If data contains UTF16 text, convert it to a string.
    // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html",
    // Google Chrome uses UTF16 without BOM for "text/x-moz-url",
    // UTF16 with BOM for "text/html".
    if ((format == QLatin1String("text/html") || format == QLatin1String("text/uri-list"))
        && data.size() > 1) {
        const quint8 byte0 = data.at(0);
        const quint8 byte1 = data.at(1);
        if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff)
            || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) {
            const QString str = QString::fromUtf16(
                  reinterpret_cast<const ushort *>(data.constData()), data.size() / 2);
            if (!str.isNull()) {
                if (format == QLatin1String("text/uri-list")) {
                    const auto urls = str.splitRef(QLatin1Char('\n'));
                    QList<QVariant> list;
                    list.reserve(urls.size());
                    for (const QStringRef &s : urls) {
                        const QUrl url(s.trimmed().toString());
                        if (url.isValid())
                            list.append(url);
                    }
                    // We expect "text/x-moz-url" as <url><space><title>.
                    // The atomName variable is not used because mimeAtomToString()
                    // converts "text/x-moz-url" to "text/uri-list".
                    if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url")
                        return list.constFirst();
                    return list;
                } else {
                    return str;
                }
            }
        }
        // 8 byte encoding, remove a possible 0 at the end
        if (data.endsWith('\0'))
            data.chop(1);
    }

    if (atomName == format)
        return data;

#if 0 // ###
    // special case for images
    if (format == QLatin1String("image/ppm")) {
        if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
            Pixmap xpm = *((Pixmap*)data.data());
            if (!xpm)
                return QByteArray();
            Window root;
            int x;
            int y;
            uint width;
            uint height;
            uint border_width;
            uint depth;

            XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
            XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
            QImage qimg = QXlibStatic::qimageFromXImage(ximg);
            XDestroyImage(ximg);

            QImageWriter imageWriter;
            imageWriter.setFormat("PPMRAW");
            QBuffer buf;
            buf.open(QIODevice::WriteOnly);
            imageWriter.setDevice(&buf);
            imageWriter.write(qimg);
            return buf.buffer();
        }
    }
#endif
    return QVariant();
}

xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
                                 const QVector<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
{
    requestedEncoding->clear();

    // find matches for string types
    if (format == QLatin1String("text/plain")) {
        if (atoms.contains(connection->atom(QXcbAtom::UTF8_STRING)))
            return connection->atom(QXcbAtom::UTF8_STRING);
        if (atoms.contains(XCB_ATOM_STRING))
            return XCB_ATOM_STRING;
        if (atoms.contains(connection->atom(QXcbAtom::TEXT)))
            return connection->atom(QXcbAtom::TEXT);
    }

    // find matches for uri types
    if (format == QLatin1String("text/uri-list")) {
        xcb_atom_t a = connection->internAtom(format.toLatin1());
        if (a && atoms.contains(a))
            return a;
        a = connection->internAtom("text/x-moz-url");
        if (a && atoms.contains(a))
            return a;
    }

    // find match for image
    if (format == QLatin1String("image/ppm")) {
        if (atoms.contains(XCB_ATOM_PIXMAP))
            return XCB_ATOM_PIXMAP;
    }

    // for string/text requests try to use a format with a well-defined charset
    // first to avoid encoding problems
    if (requestedType == QVariant::String
        && format.startsWith(QLatin1String("text/"))
        && !format.contains(QLatin1String("charset="))) {

        QString formatWithCharset = format;
        formatWithCharset.append(QLatin1String(";charset=utf-8"));

        xcb_atom_t a = connection->internAtom(std::move(formatWithCharset).toLatin1());
        if (a && atoms.contains(a)) {
            *requestedEncoding = "utf-8";
            return a;
        }
    }

    xcb_atom_t a = connection->internAtom(format.toLatin1());
    if (a && atoms.contains(a))
        return a;

    return 0;
}

QT_END_NAMESPACE
