/****************************************************************************
**
** 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 "qwinrtclipboard.h"

#include <QtCore/QCoreApplication>
#include <QtCore/qfunctions_winrt.h>
#include <QtCore/private/qeventdispatcher_winrt_p.h>

#include <Windows.ApplicationModel.datatransfer.h>

#include <functional>

using namespace ABI::Windows::ApplicationModel::DataTransfer;
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

typedef IEventHandler<IInspectable *> ContentChangedHandler;

#define RETURN_NULLPTR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return nullptr)

QT_BEGIN_NAMESPACE

QWinRTClipboard::QWinRTClipboard()
    : m_mimeData(nullptr)
{
    QEventDispatcherWinRT::runOnXamlThread([this]() {
        HRESULT hr;
        hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(),
                                  &m_nativeClipBoard);
        Q_ASSERT_SUCCEEDED(hr);

        EventRegistrationToken tok;
        hr = m_nativeClipBoard->add_ContentChanged(Callback<ContentChangedHandler>(this, &QWinRTClipboard::onContentChanged).Get(), &tok);
        Q_ASSERT_SUCCEEDED(hr);

        return hr;
    });
}

QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
{
    if (!supportsMode(mode))
        return nullptr;

    ComPtr<IDataPackageView> view;
    HRESULT hr;
    hr = m_nativeClipBoard->GetContent(&view);
    RETURN_NULLPTR_IF_FAILED("Could not get clipboard content.");

    ComPtr<IAsyncOperation<HSTRING>> op;
    HString result;
    // This throws a security exception (WinRT originate error / 0x40080201.
    // Unfortunately there seems to be no way to avoid this, neither
    // running on the XAML thread, nor some other way. Stack Overflow
    // confirms this problem since Windows (Phone) 8.0.
    hr = view->GetTextAsync(&op);
    RETURN_NULLPTR_IF_FAILED("Could not get clipboard text.");

    hr = QWinRTFunctions::await(op, result.GetAddressOf());
    RETURN_NULLPTR_IF_FAILED("Could not get clipboard text content");

    quint32 size;
    const wchar_t *textStr = result.GetRawBuffer(&size);
    QString text = QString::fromWCharArray(textStr, int(size));
    text.replace(QLatin1String("\r\n"), QLatin1String("\n"));

    if (m_mimeData) {
        if (m_mimeData->text() == text)
            return m_mimeData;
        delete m_mimeData;
    }
    m_mimeData = new QMimeData();
    m_mimeData->setText(text);

    return m_mimeData;
}

// Inspired by QWindowsMimeText::convertFromMime
inline QString convertToWindowsLineEnding(const QString &text)
{
    const QChar *u = text.unicode();
    QString res;
    const int s = text.length();
    int maxsize = s + s / 40 + 3;
    res.resize(maxsize);
    int ri = 0;
    bool cr = false;
    for (int i = 0; i < s; ++i) {
        if (*u == QLatin1Char('\r'))
            cr = true;
        else {
            if (*u == QLatin1Char('\n') && !cr)
                res[ri++] = QLatin1Char('\r');
            cr = false;
        }
        res[ri++] = *u;
        if (ri+3 >= maxsize) {
            maxsize += maxsize / 4;
            res.resize(maxsize);
        }
        ++u;
    }
    res.truncate(ri);
    return res;
}

void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
    if (!supportsMode(mode))
        return;

    const bool newData = !m_mimeData || m_mimeData != data;
    if (newData) {
        if (m_mimeData)
            delete m_mimeData;
        m_mimeData = data;
    }
    const QString text = data ? data->text() : QString();
    HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() {
        HRESULT hr;
        ComPtr<IDataPackage> package;
        hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(),
                                &package);

        const QString nativeString = convertToWindowsLineEnding(text);
        HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()),
                                 uint(nativeString.length()));

        hr = package->SetText(textRef.Get());
        RETURN_HR_IF_FAILED("Could not set text to clipboard data package.");

        hr = m_nativeClipBoard->SetContent(package.Get());
        RETURN_HR_IF_FAILED("Could not set clipboard content.");
        return S_OK;
    });
    RETURN_VOID_IF_FAILED("Could not set clipboard text.");
}

bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const
{
    return mode == QClipboard::Clipboard;
}

HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *)
{
    emitChanged(QClipboard::Clipboard);
    return S_OK;
}

QT_END_NAMESPACE
