/*
 * Copyright (C) 2019 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 INC. AND ITS CONTRIBUTORS 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 INC. OR ITS 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 "WebDataListSuggestionsDropdownGtk.h"

#if ENABLE(DATALIST_ELEMENT)

#include "WebPageProxy.h"
#include <WebCore/DataListSuggestionInformation.h>
#include <WebCore/GtkUtilities.h>
#include <WebCore/IntPoint.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>

namespace WebKit {

static void firstTimeItemSelectedCallback(GtkTreeSelection* selection, GtkWidget* treeView)
{
    if (gtk_widget_is_focus(treeView))
        gtk_tree_selection_unselect_all(selection);
    g_signal_handlers_disconnect_by_func(selection, reinterpret_cast<gpointer>(firstTimeItemSelectedCallback), treeView);
}

WebDataListSuggestionsDropdownGtk::WebDataListSuggestionsDropdownGtk(GtkWidget* webView, WebPageProxy& page)
    : WebDataListSuggestionsDropdown(page)
    , m_webView(webView)
{
    GRefPtr<GtkListStore> model = adoptGRef(gtk_list_store_new(1, G_TYPE_STRING));
    m_treeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model.get()));
    auto* treeView = GTK_TREE_VIEW(m_treeView);
    g_signal_connect(treeView, "row-activated", G_CALLBACK(treeViewRowActivatedCallback), this);
    gtk_tree_view_set_enable_search(treeView, FALSE);
    gtk_tree_view_set_activate_on_single_click(treeView, TRUE);
    gtk_tree_view_set_hover_selection(treeView, TRUE);
    gtk_tree_view_set_headers_visible(treeView, FALSE);
    gtk_tree_view_insert_column_with_attributes(treeView, 0, nullptr, gtk_cell_renderer_text_new(), "text", 0, nullptr);

    auto* selection = gtk_tree_view_get_selection(treeView);
    // The first time it's shown the first item is always selected, so we connect to selection changed to unselect it.
    g_signal_connect_object(selection, "changed", G_CALLBACK(firstTimeItemSelectedCallback), treeView, static_cast<GConnectFlags>(0));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);

    auto* swindow = gtk_scrolled_window_new(nullptr, nullptr);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
#if USE(GTK4)
    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(swindow), m_treeView);
#else
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_ETCHED_IN);
    gtk_container_add(GTK_CONTAINER(swindow), m_treeView);
    gtk_widget_show(m_treeView);
#endif

#if USE(GTK4)
    m_popup = gtk_popover_new();
    gtk_popover_set_has_arrow(GTK_POPOVER(m_popup), FALSE);
    gtk_popover_set_autohide(GTK_POPOVER(m_popup), FALSE);
    gtk_popover_set_position(GTK_POPOVER(m_popup), GTK_POS_BOTTOM);
    gtk_popover_set_child(GTK_POPOVER(m_popup), swindow);
    gtk_widget_set_parent(m_popup, m_webView);
#else
    m_popup = gtk_window_new(GTK_WINDOW_POPUP);
    gtk_window_set_type_hint(GTK_WINDOW(m_popup), GDK_WINDOW_TYPE_HINT_COMBO);
    gtk_window_set_resizable(GTK_WINDOW(m_popup), FALSE);
    gtk_container_add(GTK_CONTAINER(m_popup), swindow);
    gtk_widget_show(swindow);

    g_signal_connect_object(m_webView, "focus-out-event", G_CALLBACK(gtk_widget_hide), m_popup, G_CONNECT_SWAPPED);
    g_signal_connect_object(m_webView, "unmap-event", G_CALLBACK(gtk_widget_hide), m_popup, G_CONNECT_SWAPPED);
#endif

#if ENABLE(DEVELOPER_MODE)
    g_object_set_data(G_OBJECT(m_webView), "wk-datalist-popup", m_popup);
#endif
}

WebDataListSuggestionsDropdownGtk::~WebDataListSuggestionsDropdownGtk()
{
#if !USE(GTK4)
    gtk_window_set_transient_for(GTK_WINDOW(m_popup), nullptr);
    gtk_window_set_attached_to(GTK_WINDOW(m_popup), nullptr);
#endif

#if ENABLE(DEVELOPER_MODE)
    g_object_set_data(G_OBJECT(m_webView), "wk-datalist-popup", nullptr);
#endif

#if USE(GTK4)
    g_clear_pointer(&m_popup, gtk_widget_unparent);
#else
    gtk_widget_destroy(m_popup);
#endif
}

void WebDataListSuggestionsDropdownGtk::treeViewRowActivatedCallback(GtkTreeView* treeView, GtkTreePath* path, GtkTreeViewColumn*, WebDataListSuggestionsDropdownGtk* menu)
{
    auto* model = gtk_tree_view_get_model(treeView);
    GtkTreeIter iter;
    gtk_tree_model_get_iter(model, &iter, path);
    GUniqueOutPtr<char> item;
    gtk_tree_model_get(model, &iter, 0, &item.outPtr(), -1);

    menu->didSelectOption(String::fromUTF8(item.get()));
}

void WebDataListSuggestionsDropdownGtk::didSelectOption(const String& selectedOption)
{
    if (!m_page)
        return;

    m_page->didSelectOption(selectedOption);
    close();
}

void WebDataListSuggestionsDropdownGtk::show(WebCore::DataListSuggestionInformation&& information)
{
    auto* model = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(m_treeView)));
    gtk_list_store_clear(model);
    for (const auto& suggestion : information.suggestions) {
        GtkTreeIter iter;
        gtk_list_store_append(model, &iter);
        gtk_list_store_set(model, &iter, 0, suggestion.value.utf8().data(), -1);
    }

    GtkRequisition treeViewRequisition;
    gtk_widget_get_preferred_size(m_treeView, &treeViewRequisition, nullptr);
    auto* column = gtk_tree_view_get_column(GTK_TREE_VIEW(m_treeView), 0);
    gint itemHeight;
    gtk_tree_view_column_cell_get_size(column, nullptr, nullptr, nullptr, nullptr, &itemHeight);
#if !USE(GTK4)
    gint verticalSeparator;
    gtk_widget_style_get(m_treeView, "vertical-separator", &verticalSeparator, nullptr);
    itemHeight += verticalSeparator;
#endif
    if (!itemHeight)
        return;

    auto* display = gtk_widget_get_display(m_webView);
#if USE(GTK4)
    auto* monitor = gdk_display_get_monitor_at_surface(display, gtk_native_get_surface(gtk_widget_get_native(m_webView)));
#else
    auto* monitor = gdk_display_get_monitor_at_window(display, gtk_widget_get_window(m_webView));
#endif
    GdkRectangle area;
    gdk_monitor_get_workarea(monitor, &area);
    int width = std::min(information.elementRect.width(), area.width);
    size_t itemCount = std::min<size_t>(information.suggestions.size(), (area.height / 3) / itemHeight);

#if USE(GTK4)
    auto* swindow = GTK_SCROLLED_WINDOW(gtk_popover_get_child(GTK_POPOVER(m_popup)));
#else
    auto* swindow = GTK_SCROLLED_WINDOW(gtk_bin_get_child(GTK_BIN(m_popup)));
#endif
    // Disable scrollbars when there's only one item to ensure the scrolled window doesn't take them into account when calculating its minimum size.
    gtk_scrolled_window_set_policy(swindow, GTK_POLICY_NEVER, itemCount > 1 ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER);
    gtk_widget_realize(m_treeView);
    gtk_tree_view_columns_autosize(GTK_TREE_VIEW(m_treeView));
    gtk_scrolled_window_set_min_content_width(swindow, width);
    gtk_widget_set_size_request(m_popup, width, -1);
    gtk_scrolled_window_set_min_content_height(swindow, itemCount * itemHeight);

#if USE(GTK4)
    GdkRectangle windowRect(information.elementRect);
    gtk_popover_set_pointing_to(GTK_POPOVER(m_popup), &windowRect);
#else
    GtkRequisition menuRequisition;
    gtk_widget_get_preferred_size(m_popup, &menuRequisition, nullptr);
    WebCore::IntPoint menuPosition = convertWidgetPointToScreenPoint(m_webView, information.elementRect.location());
    // FIXME: We can't ensure the menu will be on screen in Wayland.
    // https://blog.gtk.org/2016/07/15/future-of-relative-window-positioning/
    // https://gitlab.gnome.org/GNOME/gtk/issues/997
    if (menuPosition.x() + menuRequisition.width > area.x + area.width)
        menuPosition.setX(area.x + area.width - menuRequisition.width);

    if (menuPosition.y() + information.elementRect.height() + menuRequisition.height <= area.y + area.height
        || menuPosition.y() - area.y < (area.y + area.height) - (menuPosition.y() + information.elementRect.height()))
        menuPosition.move(0, information.elementRect.height());
    else
        menuPosition.move(0, -menuRequisition.height);
    gtk_window_move(GTK_WINDOW(m_popup), menuPosition.x(), menuPosition.y());

    auto* toplevel = gtk_widget_get_toplevel(m_webView);
    if (GTK_IS_WINDOW(toplevel)) {
        gtk_window_set_transient_for(GTK_WINDOW(m_popup), GTK_WINDOW(toplevel));
        gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(toplevel)), GTK_WINDOW(m_popup));
    }
    gtk_window_set_attached_to(GTK_WINDOW(m_popup), m_webView);
    gtk_window_set_screen(GTK_WINDOW(m_popup), gtk_widget_get_screen(m_webView));
#endif

    gtk_widget_show(m_popup);
}

void WebDataListSuggestionsDropdownGtk::handleKeydownWithIdentifier(const String& key)
{
    auto* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_treeView));
    GtkTreeModel* model;
    GtkTreeIter iter;
    bool hasSelection = gtk_tree_selection_get_selected(selection, &model, &iter);
    if (key == "Enter") {
        if (hasSelection) {
            GUniqueOutPtr<char> item;
            gtk_tree_model_get(model, &iter, 0, &item.outPtr(), -1);
            m_page->didSelectOption(String::fromUTF8(item.get()));
        }
        close();
        return;
    }

    if (key == "Up") {
        if ((hasSelection && gtk_tree_model_iter_previous(model, &iter)) || gtk_tree_model_iter_nth_child(model, &iter, nullptr, gtk_tree_model_iter_n_children(model, nullptr) - 1))
            gtk_tree_selection_select_iter(selection, &iter);
        else
            return;
    } else if (key == "Down") {
        if ((hasSelection && gtk_tree_model_iter_next(model, &iter)) || gtk_tree_model_get_iter_first(model, &iter))
            gtk_tree_selection_select_iter(selection, &iter);
        else
            return;
    }

    GUniquePtr<GtkTreePath> path(gtk_tree_model_get_path(model, &iter));
    gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(m_treeView), path.get(), nullptr, FALSE, 0, 0);
}

void WebDataListSuggestionsDropdownGtk::close()
{
    gtk_widget_hide(m_popup);
}

} // namespace WebKit

#endif // ENABLE(DATALIST_ELEMENT)
