/*
 * Copyright (C) 2020 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "DropTarget.h"

#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)

#include "WebKitWebViewBasePrivate.h"
#include <WebCore/DragData.h>
#include <WebCore/GRefPtrGtk.h>
#include <WebCore/GtkUtilities.h>
#include <gtk/gtk.h>
#include <wtf/glib/GUniquePtr.h>

namespace WebKit {
using namespace WebCore;

enum DropTargetType { Markup, Text, URIList, NetscapeURL, SmartPaste };

DropTarget::DropTarget(GtkWidget* webView)
    : m_webView(webView)
    , m_leaveTimer(RunLoop::main(), this, &DropTarget::leaveTimerFired)
{
    GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(nullptr, 0));
    gtk_target_list_add_text_targets(list.get(), DropTargetType::Text);
    gtk_target_list_add(list.get(), gdk_atom_intern_static_string("text/html"), 0, DropTargetType::Markup);
    gtk_target_list_add_uri_targets(list.get(), DropTargetType::URIList);
    gtk_target_list_add(list.get(), gdk_atom_intern_static_string("_NETSCAPE_URL"), 0, DropTargetType::NetscapeURL);
    gtk_target_list_add(list.get(), gdk_atom_intern_static_string("application/vnd.webkitgtk.smartpaste"), 0, DropTargetType::SmartPaste);
    gtk_drag_dest_set(m_webView, static_cast<GtkDestDefaults>(0), nullptr, 0,
        static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK));
    gtk_drag_dest_set_target_list(m_webView, list.get());

    g_signal_connect(m_webView, "drag-motion", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gint x, gint y, guint time, gpointer userData) -> gboolean {
        auto& drop = *static_cast<DropTarget*>(userData);
        if (!drop.m_drop) {
            drop.m_drop = context;
            drop.m_position = IntPoint(x, y);
            drop.accept(time);
        } else if (drop.m_drop == context)
            drop.update({ x, y }, time);
        return TRUE;
    }), this);

    g_signal_connect(m_webView, "drag-leave", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, guint time, gpointer userData) {
        auto& drop = *static_cast<DropTarget*>(userData);
        if (drop.m_drop != context)
            return;
        drop.leave();
    }), this);

    g_signal_connect(m_webView, "drag-drop", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gint x, gint y, guint time, gpointer userData) -> gboolean {
        auto& drop = *static_cast<DropTarget*>(userData);
        if (drop.m_drop != context) {
            gtk_drag_finish(context, FALSE, FALSE, time);
            return TRUE;
        }
        drop.drop({ x, y }, time);
        return TRUE;
    }), this);

    g_signal_connect(m_webView, "drag-data-received", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gint x, gint y, GtkSelectionData* data, guint info, guint time, gpointer userData) {
        auto& drop = *static_cast<DropTarget*>(userData);
        if (drop.m_drop != context)
            return;
        drop.dataReceived({ x, y }, data, info, time);
    }), this);
}

DropTarget::~DropTarget()
{
    g_signal_handlers_disconnect_by_data(m_webView, this);
}

void DropTarget::accept(unsigned time)
{
    if (m_leaveTimer.isActive()) {
        m_leaveTimer.stop();
        leaveTimerFired();
    }

    m_dataRequestCount = 0;
    m_selectionData = SelectionData();

    // WebCore needs the selection data to decide, so we need to preload the
    // data of targets we support. Once all data requests are done we start
    // notifying the web process about the DND events.
    auto* list = gdk_drag_context_list_targets(m_drop.get());
    static const char* const supportedTargets[] = {
        "text/plain;charset=utf-8",
        "text/html",
        "_NETSCAPE_URL",
        "text/uri-list",
        "application/vnd.webkitgtk.smartpaste"
    };
    Vector<GdkAtom, 4> targets;
    for (unsigned i = 0; i < G_N_ELEMENTS(supportedTargets); ++i) {
        GdkAtom atom = gdk_atom_intern_static_string(supportedTargets[i]);
        if (g_list_find(list, atom))
            targets.append(atom);
        else if (!i) {
            atom = gdk_atom_intern_static_string("text/plain");
            if (g_list_find(list, atom))
                targets.append(atom);
        }
    }

    m_dataRequestCount = targets.size();
    for (auto* atom : targets)
        gtk_drag_get_data(m_webView, m_drop.get(), atom, time);
}

void DropTarget::enter(IntPoint&& position, unsigned time)
{
    m_position = WTFMove(position);

    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
    ASSERT(page);
    page->resetCurrentDragInformation();

    DragData dragData(&m_selectionData.value(), *m_position, convertWidgetPointToScreenPoint(m_webView, *m_position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(m_drop.get())));
    page->dragEntered(dragData);
}

void DropTarget::update(IntPoint&& position, unsigned time)
{
    if (m_dataRequestCount || !m_selectionData)
        return;

    m_position = WTFMove(position);

    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
    ASSERT(page);

    DragData dragData(&m_selectionData.value(), *m_position, convertWidgetPointToScreenPoint(m_webView, *m_position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(m_drop.get())));
    page->dragUpdated(dragData);
}

void DropTarget::dataReceived(IntPoint&& position, GtkSelectionData* data, unsigned info, unsigned time)
{
    switch (info) {
    case DropTargetType::Text: {
        GUniquePtr<char> text(reinterpret_cast<char*>(gtk_selection_data_get_text(data)));
        m_selectionData->setText(String::fromUTF8(text.get()));
        break;
    }
    case DropTargetType::Markup: {
        gint length;
        const auto* markupData = gtk_selection_data_get_data_with_length(data, &length);
        if (length) {
            // If data starts with UTF-16 BOM assume it's UTF-16, otherwise assume UTF-8.
            if (length >= 2 && reinterpret_cast<const UChar*>(markupData)[0] == 0xFEFF)
                m_selectionData->setMarkup(String(reinterpret_cast<const UChar*>(markupData) + 1, (length / 2) - 1));
            else
                m_selectionData->setMarkup(String::fromUTF8(markupData, length));
        }
        break;
    }
    case DropTargetType::URIList: {
        gint length;
        const auto* uriListData = gtk_selection_data_get_data_with_length(data, &length);
        if (length)
            m_selectionData->setURIList(String::fromUTF8(uriListData, length));
        break;
    }
    case DropTargetType::NetscapeURL: {
        gint length;
        const auto* urlData = gtk_selection_data_get_data_with_length(data, &length);
        if (length) {
            Vector<String> tokens = String::fromUTF8(urlData, length).split('\n');
            URL url({ }, tokens[0]);
            if (url.isValid())
                m_selectionData->setURL(url, tokens.size() > 1 ? tokens[1] : String());
        }
        break;
    }
    case DropTargetType::SmartPaste:
        m_selectionData->setCanSmartReplace(true);
        break;
    }

    if (--m_dataRequestCount)
        return;

    enter(WTFMove(position), time);
}

void DropTarget::didPerformAction()
{
    if (!m_drop)
        return;

    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
    ASSERT(page);

    auto operation = page->currentDragOperation();
    if ((!operation && !m_operation) || *operation == *m_operation)
        return;

    m_operation = operation;
    gdk_drag_status(m_drop.get(), dragOperationToSingleGdkDragAction(m_operation), GDK_CURRENT_TIME);
}

void DropTarget::leaveTimerFired()
{
    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
    ASSERT(page);

    DragData dragData(&m_selectionData.value(), *m_position, convertWidgetPointToScreenPoint(m_webView, *m_position), { });
    page->dragExited(dragData);
    page->resetCurrentDragInformation();

    m_drop = nullptr;
    m_position = WTF::nullopt;
    m_selectionData = WTF::nullopt;
}

void DropTarget::leave()
{
    // GTK emits drag-leave before drag-drop, but we need to know whether a drop
    // happened to notify the web process about the drag exit.
    m_leaveTimer.startOneShot(0_s);
}

void DropTarget::drop(IntPoint&& position, unsigned time)
{
    if (m_leaveTimer.isActive())
        m_leaveTimer.stop();

    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
    ASSERT(page);

    uint32_t flags = 0;
    if (gdk_drag_context_get_selected_action(m_drop.get()) == GDK_ACTION_COPY)
        flags |= DragApplicationIsCopyKeyDown;
    DragData dragData(&m_selectionData.value(), position, convertWidgetPointToScreenPoint(m_webView, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(m_drop.get())), static_cast<DragApplicationFlags>(flags));
    page->performDragOperation(dragData, { }, { }, { });
    gtk_drag_finish(m_drop.get(), TRUE, FALSE, time);

    m_drop = nullptr;
    m_position = WTF::nullopt;
    m_selectionData = WTF::nullopt;
}

} // namespace WebKit

#endif // ENABLE(DRAG_SUPPORT) && !USE(GTK4)
