/*
 * Copyright (C) 2019 Igalia S.L.
 * Copyright (C) 2017 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

// GtkEmojiChooser is private in GTK 3, so this is based in the GTK code, just adapted to
// WebKit coding style, using some internal types from WTF to simplify the implementation
// and not using GtkBuilder for the UI.

#include "config.h"
#include "WebKitEmojiChooser.h"

#if GTK_CHECK_VERSION(3, 24, 0)

#include <glib/gi18n-lib.h>
#include <wtf/HashSet.h>
#include <wtf/RunLoop.h>
#include <wtf/Vector.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/glib/WTFGType.h>
#include <wtf/text/CString.h>

enum {
    EMOJI_PICKED,

    LAST_SIGNAL
};

struct EmojiSection {
    GtkWidget* heading { nullptr };
    GtkWidget* box { nullptr };
    GtkWidget* button { nullptr };
    bool isEmpty { false };
    const char* firstEmojiName { nullptr };
};

using SectionList = Vector<EmojiSection, 9>;

class CallbackTimer final : public RunLoop::TimerBase {
public:
    CallbackTimer(Function<void()>&& callback)
        : RunLoop::TimerBase(RunLoop::main())
        , m_callback(WTFMove(callback))
    {
    }

    ~CallbackTimer() = default;

private:
    void fired() override
    {
        m_callback();
    }

    Function<void()> m_callback;
};

struct _WebKitEmojiChooserPrivate {
    GtkWidget* stack;
    GtkWidget* swindow;
    GtkWidget* searchEntry;
    SectionList sections;
    GRefPtr<GSettings> settings;
    HashSet<GRefPtr<GtkGesture>> gestures;
    int emojiMaxWidth;
    std::unique_ptr<CallbackTimer> populateSectionsTimer;
};

static guint signals[LAST_SIGNAL] = { 0, };

WEBKIT_DEFINE_TYPE(WebKitEmojiChooser, webkit_emoji_chooser, GTK_TYPE_POPOVER)

static void emojiPopupMenu(GtkWidget*, WebKitEmojiChooser*);

static const unsigned boxSpace = 6;

static void emojiHovered(GtkWidget* widget, GdkEvent* event)
{
    if (gdk_event_get_event_type(event) == GDK_ENTER_NOTIFY)
        gtk_widget_set_state_flags(widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
    else
        gtk_widget_unset_state_flags(widget, GTK_STATE_FLAG_PRELIGHT);
}

static GtkWidget* webkitEmojiChooserAddEmoji(WebKitEmojiChooser* chooser, GtkFlowBox* parent, GVariant* item, bool prepend = false, gunichar modifier = 0)
{
    char text[64];
    char* textPtr = text;
    GRefPtr<GVariant> codes = adoptGRef(g_variant_get_child_value(item, 0));
    for (unsigned i = 0; i < g_variant_n_children(codes.get()); ++i) {
        gunichar code;
        g_variant_get_child(codes.get(), i, "u", &code);
        if (!code)
            code = modifier;
        if (code)
            textPtr += g_unichar_to_utf8(code, textPtr);
    }
    // U+FE0F is the Emoji variation selector
    textPtr += g_unichar_to_utf8(0xFE0F, textPtr);
    textPtr[0] = '\0';

    GtkWidget* label = gtk_label_new(text);
    PangoAttrList* attributes = pango_attr_list_new();
    pango_attr_list_insert(attributes, pango_attr_scale_new(PANGO_SCALE_X_LARGE));
    gtk_label_set_attributes(GTK_LABEL(label), attributes);
    pango_attr_list_unref(attributes);

    PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(label));
    PangoRectangle rect;
    pango_layout_get_extents(layout, &rect, nullptr);
    // Check for fallback rendering that generates too wide items.
    if (pango_layout_get_unknown_glyphs_count(layout) || rect.width >= 1.5 * chooser->priv->emojiMaxWidth) {
        gtk_widget_destroy(label);
        return nullptr;
    }

    GtkWidget* child = gtk_flow_box_child_new();
    gtk_style_context_add_class(gtk_widget_get_style_context(child), "emoji");
    g_object_set_data_full(G_OBJECT(child), "emoji-data", g_variant_ref(item), reinterpret_cast<GDestroyNotify>(g_variant_unref));
    if (modifier)
        g_object_set_data(G_OBJECT(child), "modifier", GUINT_TO_POINTER(modifier));

    GtkWidget* eventBox = gtk_event_box_new();
    gtk_widget_add_events(eventBox, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
    g_signal_connect(eventBox, "enter-notify-event", G_CALLBACK(emojiHovered), nullptr);
    g_signal_connect(eventBox, "leave-notify-event", G_CALLBACK(emojiHovered), nullptr);
    gtk_container_add(GTK_CONTAINER(eventBox), label);
    gtk_widget_show(label);

    gtk_container_add(GTK_CONTAINER(child), eventBox);
    gtk_widget_show(eventBox);

    gtk_flow_box_insert(parent, child, prepend ? 0 : -1);
    gtk_widget_show(child);

    return child;
}

static void webkitEmojiChooserAddRecentItem(WebKitEmojiChooser* chooser, GVariant* item, gunichar modifier)
{
    GRefPtr<GVariant> protectItem(item);
    GVariantBuilder builder;
    g_variant_builder_init(&builder, G_VARIANT_TYPE("a((auss)u)"));
    g_variant_builder_add(&builder, "(@(auss)u)", item, modifier);

    auto& section = chooser->priv->sections.first();

    static const unsigned maxRecentItems = 7 * 3;

    GUniquePtr<GList> children(gtk_container_get_children(GTK_CONTAINER(section.box)));
    unsigned i = 1;
    for (auto* l = children.get(); l; l = g_list_next(l), ++i) {
        auto* item2 = static_cast<GVariant*>(g_object_get_data(G_OBJECT(l->data), "emoji-data"));
        auto modifier2 = static_cast<gunichar>(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(l->data), "modifier")));
        if (modifier == modifier2 && g_variant_equal(item, item2)) {
            gtk_widget_destroy(GTK_WIDGET(l->data));
            --i;
            continue;
        }

        if (i >= maxRecentItems) {
            gtk_widget_destroy(GTK_WIDGET(l->data));
            continue;
        }

        g_variant_builder_add(&builder, "(@(auss)u)", item2, modifier2);
    }

    auto* child = webkitEmojiChooserAddEmoji(chooser, GTK_FLOW_BOX(section.box), item, true, modifier);
    if (child)
        g_signal_connect(child, "popup-menu", G_CALLBACK(emojiPopupMenu), chooser);

    gtk_widget_show(section.box);
    gtk_widget_set_sensitive(section.button, TRUE);

    g_settings_set_value(chooser->priv->settings.get(), "recent-emoji", g_variant_builder_end(&builder));
}

static void emojiActivated(GtkFlowBox* box, GtkFlowBoxChild* child, WebKitEmojiChooser* chooser)
{
    GtkWidget* label = gtk_bin_get_child(GTK_BIN(gtk_bin_get_child(GTK_BIN(child))));
    GUniquePtr<char> text(g_strdup(gtk_label_get_label(GTK_LABEL(label))));

    auto* item = static_cast<GVariant*>(g_object_get_data(G_OBJECT(child), "emoji-data"));
    auto modifier = static_cast<gunichar>(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(child), "modifier")));
    webkitEmojiChooserAddRecentItem(chooser, item, modifier);
    g_signal_emit(chooser, signals[EMOJI_PICKED], 0, text.get());

    gtk_popover_popdown(GTK_POPOVER(chooser));
}

static bool emojiDataHasVariations(GVariant* emojiData)
{
    GRefPtr<GVariant> codes = adoptGRef(g_variant_get_child_value(emojiData, 0));
    for (size_t i = 0; i < g_variant_n_children(codes.get()); ++i) {
        gunichar code;
        g_variant_get_child(codes.get(), i, "u", &code);
        if (!code)
            return true;
    }
    return false;
}

static void webkitEmojiChooserShowVariations(WebKitEmojiChooser* chooser, GtkWidget* child)
{
    if (!child)
        return;

    auto* emojiData = static_cast<GVariant*>(g_object_get_data(G_OBJECT(child), "emoji-data"));
    if (!emojiData)
        return;

    if (!emojiDataHasVariations(emojiData))
        return;

    GtkWidget* popover = gtk_popover_new(child);
    GtkWidget* view = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_style_context_add_class(gtk_widget_get_style_context(view), "view");
    GtkWidget* box = gtk_flow_box_new();
    g_signal_connect(box, "child-activated", G_CALLBACK(emojiActivated), chooser);
    gtk_flow_box_set_homogeneous(GTK_FLOW_BOX(box), TRUE);
    gtk_flow_box_set_min_children_per_line(GTK_FLOW_BOX(box), 6);
    gtk_flow_box_set_max_children_per_line(GTK_FLOW_BOX(box), 6);
    gtk_flow_box_set_activate_on_single_click(GTK_FLOW_BOX(box), TRUE);
    gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(box), GTK_SELECTION_NONE);
    gtk_container_add(GTK_CONTAINER(view), box);
    gtk_widget_show(box);
    gtk_container_add(GTK_CONTAINER(popover), view);
    gtk_widget_show(view);

    webkitEmojiChooserAddEmoji(chooser, GTK_FLOW_BOX(box), emojiData);
    for (gunichar modifier = 0x1F3FB; modifier <= 0x1F3FF; ++modifier)
        webkitEmojiChooserAddEmoji(chooser, GTK_FLOW_BOX(box), emojiData, false, modifier);

    gtk_popover_popup(GTK_POPOVER(popover));
}

static void emojiLongPressed(GtkGesture* gesture, double x, double y, WebKitEmojiChooser* chooser)
{
    auto* box = GTK_FLOW_BOX(gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)));
    webkitEmojiChooserShowVariations(chooser, GTK_WIDGET(gtk_flow_box_get_child_at_pos(box, x, y)));
}

static void emojiPressed(GtkGesture* gesture, int, double x, double y, WebKitEmojiChooser* chooser)
{
    emojiLongPressed(gesture, x, y, chooser);
}

static void emojiPopupMenu(GtkWidget* child, WebKitEmojiChooser* chooser)
{
    webkitEmojiChooserShowVariations(chooser, child);
}

static void verticalAdjustmentChanged(GtkAdjustment* adjustment, WebKitEmojiChooser* chooser)
{
    double value = gtk_adjustment_get_value(adjustment);
    EmojiSection* sectionToSelect = nullptr;
    for (auto& section : chooser->priv->sections) {
        GtkAllocation allocation;
        if (section.heading)
            gtk_widget_get_allocation(section.heading, &allocation);
        else
            gtk_widget_get_allocation(section.box, &allocation);

        if (value < allocation.y - boxSpace)
            break;

        sectionToSelect = &section;
    }

    if (!sectionToSelect)
        sectionToSelect = &chooser->priv->sections[0];

    for (auto& section : chooser->priv->sections) {
        if (&section == sectionToSelect)
            gtk_widget_set_state_flags(section.button, GTK_STATE_FLAG_CHECKED, FALSE);
        else
            gtk_widget_unset_state_flags(section.button, GTK_STATE_FLAG_CHECKED);
    }
}

static GtkWidget* webkitEmojiChooserSetupSectionBox(WebKitEmojiChooser* chooser, GtkBox* parent, const char* firstEmojiName, const char* title, GtkAdjustment* adjustment, gboolean canHaveVariations = FALSE)
{
    EmojiSection section;
    section.firstEmojiName = firstEmojiName;
    if (title) {
        GtkWidget* label = gtk_label_new(title);
        section.heading = label;
        gtk_label_set_xalign(GTK_LABEL(label), 0);
        gtk_box_pack_start(parent, label, FALSE, FALSE, 0);
        gtk_widget_show(label);
    }

    GtkWidget* box = gtk_flow_box_new();
    section.box = box;
    g_signal_connect(box, "child-activated", G_CALLBACK(emojiActivated), chooser);
    gtk_flow_box_set_homogeneous(GTK_FLOW_BOX(box), TRUE);
    gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(box), GTK_SELECTION_NONE);
    gtk_container_set_focus_vadjustment(GTK_CONTAINER(box), adjustment);
    gtk_box_pack_start(parent, box, FALSE, FALSE, 0);
    gtk_widget_show(box);

    if (canHaveVariations) {
        GRefPtr<GtkGesture> gesture = adoptGRef(gtk_gesture_long_press_new(box));
        g_signal_connect(gesture.get(), "pressed", G_CALLBACK(emojiLongPressed), chooser);
        chooser->priv->gestures.add(WTFMove(gesture));
        GRefPtr<GtkGesture> multiGesture = adoptGRef(gtk_gesture_multi_press_new(box));
        gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(multiGesture.get()), GDK_BUTTON_SECONDARY);
        g_signal_connect(multiGesture.get(), "pressed", G_CALLBACK(emojiPressed), chooser);
        chooser->priv->gestures.add(WTFMove(multiGesture));
    }

    chooser->priv->sections.append(WTFMove(section));
    return box;
}

static void scrollToSection(GtkButton* button, gpointer data)
{
    auto* chooser = WEBKIT_EMOJI_CHOOSER(gtk_widget_get_ancestor(GTK_WIDGET(button), WEBKIT_TYPE_EMOJI_CHOOSER));
    auto& section = chooser->priv->sections[GPOINTER_TO_UINT(data)];
    GtkAdjustment* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(chooser->priv->swindow));
    if (section.heading) {
        GtkAllocation allocation = { 0, 0, 0, 0 };
        gtk_widget_get_allocation(section.heading, &allocation);
        gtk_adjustment_set_value(adjustment, allocation.y - boxSpace);
    } else
        gtk_adjustment_set_value(adjustment, 0);
}

static void webkitEmojiChooserSetupSectionButton(WebKitEmojiChooser* chooser, GtkBox* parent, const char* iconName, const char* tooltip)
{
    GtkWidget* button = gtk_button_new_from_icon_name(iconName, GTK_ICON_SIZE_BUTTON);
    chooser->priv->sections.last().button = button;
    gtk_style_context_add_class(gtk_widget_get_style_context(button), "emoji-section");
    gtk_widget_set_tooltip_text(button, tooltip);
    g_signal_connect(button, "clicked", G_CALLBACK(scrollToSection), GUINT_TO_POINTER(chooser->priv->sections.size() - 1));
    gtk_box_pack_start(parent, button, FALSE, FALSE, 0);
    gtk_widget_show(button);
}

static void webkitEmojiChooserSetupRecent(WebKitEmojiChooser* chooser, GtkBox* emojiBox, GtkBox* buttonBox, GtkAdjustment* adjustment)
{
    GtkWidget* flowBox = webkitEmojiChooserSetupSectionBox(chooser, emojiBox, nullptr, nullptr, adjustment, true);
    webkitEmojiChooserSetupSectionButton(chooser, buttonBox, "emoji-recent-symbolic", _("Recent"));

    bool isEmpty = true;
    GRefPtr<GVariant> variant = adoptGRef(g_settings_get_value(chooser->priv->settings.get(), "recent-emoji"));
    GVariantIter iter;
    g_variant_iter_init(&iter, variant.get());
    while (GRefPtr<GVariant> item = adoptGRef(g_variant_iter_next_value(&iter))) {
        GRefPtr<GVariant> emojiData = adoptGRef(g_variant_get_child_value(item.get(), 0));
        gunichar modifier;
        g_variant_get_child(item.get(), 1, "u", &modifier);
        if (auto* child = webkitEmojiChooserAddEmoji(chooser, GTK_FLOW_BOX(flowBox), emojiData.get(), true, modifier))
            g_signal_connect(child, "popup-menu", G_CALLBACK(emojiPopupMenu), chooser);
        isEmpty = false;
    }

    if (isEmpty) {
        gtk_widget_hide(flowBox);
        gtk_widget_set_sensitive(chooser->priv->sections.first().button, FALSE);
    }
}

static void webkitEmojiChooserEnsureEmptyResult(WebKitEmojiChooser* chooser)
{
    if (gtk_stack_get_child_by_name(GTK_STACK(chooser->priv->stack), "empty"))
        return;

    GtkWidget* grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 12);
    gtk_widget_set_halign(grid, GTK_ALIGN_CENTER);
    gtk_widget_set_valign(grid, GTK_ALIGN_CENTER);
    gtk_style_context_add_class(gtk_widget_get_style_context(grid), "dim-label");

    GtkWidget* image = gtk_image_new_from_icon_name("edit-find-symbolic", GTK_ICON_SIZE_DIALOG);
    gtk_image_set_pixel_size(GTK_IMAGE(image), 72);
    gtk_style_context_add_class(gtk_widget_get_style_context(image), "dim-label");
    gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 1);
    gtk_widget_show(image);

    GtkWidget* label = gtk_label_new(_("No Results Found"));
    PangoAttrList* attributes = pango_attr_list_new();
    pango_attr_list_insert(attributes, pango_attr_scale_new(1.44));
    pango_attr_list_insert(attributes, pango_attr_weight_new(PANGO_WEIGHT_BOLD));
    gtk_label_set_attributes(GTK_LABEL(label), attributes);
    pango_attr_list_unref(attributes);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
    gtk_widget_show(label);

    label = gtk_label_new(_("Try a different search"));
    gtk_style_context_add_class(gtk_widget_get_style_context(label), "dim-label");
    gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1);
    gtk_widget_show(label);

    gtk_stack_add_named(GTK_STACK(chooser->priv->stack), grid, "empty");
    gtk_widget_show(grid);
}

static void webkitEmojiChooserSearchChanged(WebKitEmojiChooser* chooser)
{
    for (auto& section : chooser->priv->sections) {
        section.isEmpty = true;
        gtk_flow_box_invalidate_filter(GTK_FLOW_BOX(section.box));
    }

    bool resultsFound = false;
    for (auto& section : chooser->priv->sections) {
        if (section.heading) {
            gtk_widget_set_visible(section.heading, !section.isEmpty);
            gtk_widget_set_visible(section.box, !section.isEmpty);
        }
        resultsFound = resultsFound || !section.isEmpty;
    }

    if (!resultsFound) {
        webkitEmojiChooserEnsureEmptyResult(chooser);
        gtk_stack_set_visible_child_name(GTK_STACK(chooser->priv->stack), "empty");
    } else
        gtk_stack_set_visible_child_name(GTK_STACK(chooser->priv->stack), "list");
}

static void webkitEmojiChooserSetupFilters(WebKitEmojiChooser* chooser)
{
    for (size_t i = 0; i < chooser->priv->sections.size(); ++i) {
        gtk_flow_box_set_filter_func(GTK_FLOW_BOX(chooser->priv->sections[i].box), [](GtkFlowBoxChild* child, gpointer userData) -> gboolean {
            auto* chooser = WEBKIT_EMOJI_CHOOSER(gtk_widget_get_ancestor(GTK_WIDGET(child), WEBKIT_TYPE_EMOJI_CHOOSER));
            auto& section = chooser->priv->sections[GPOINTER_TO_UINT(userData)];
            const char* text = gtk_entry_get_text(GTK_ENTRY(chooser->priv->searchEntry));
            if (!text || !*text) {
                section.isEmpty = false;
                return TRUE;
            }

            auto* emojiData = static_cast<GVariant*>(g_object_get_data(G_OBJECT(child), "emoji-data"));
            if (!emojiData) {
                section.isEmpty = false;
                return TRUE;
            }

            const char* name;
            g_variant_get_child(emojiData, 1, "&s", &name);
            if (g_str_match_string(text, name, TRUE)) {
                section.isEmpty = false;
                return TRUE;
            }

            return FALSE;
        }, GUINT_TO_POINTER(i), nullptr);
    }
}

static void webkitEmojiChooserSetupEmojiSections(WebKitEmojiChooser* chooser, GtkBox* emojiBox, GtkBox* buttonBox)
{
    static const struct {
        const char* firstEmojiName;
        const char* title;
        const char* iconName;
        bool canHaveVariations;
    } sections[] = {
        { "grinning face", N_("Smileys & People"), "emoji-people-symbolic", true },
        { "selfie", N_("Body & Clothing"), "emoji-body-symbolic", true },
        { "monkey", N_("Animals & Nature"), "emoji-nature-symbolic", false },
        { "grapes", N_("Food & Drink"), "emoji-food-symbolic", false },
        { "globe showing Europe-Africa", N_("Travel & Places"), "emoji-travel-symbolic", false },
        { "jack-o-lantern", N_("Activities"), "emoji-activities-symbolic", false },
        { "uted speaker", _("Objects"), "emoji-objects-symbolic", false },
        { "ATM sign", N_("Symbols"), "emoji-symbols-symbolic", false },
        { "chequered flag", _("Flags"), "emoji-flags-symbolic", false }
    };

    auto* vAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(chooser->priv->swindow));

    GtkWidget* flowBox = nullptr;
    for (unsigned i = 0; i < G_N_ELEMENTS(sections); ++i) {
        auto* box = webkitEmojiChooserSetupSectionBox(chooser, emojiBox, sections[i].firstEmojiName, sections[i].title, vAdjustment, sections[i].canHaveVariations);
        webkitEmojiChooserSetupSectionButton(chooser, buttonBox, sections[i].iconName, sections[i].title);
        if (!i)
            flowBox = box;
    }

    GRefPtr<GBytes> bytes = adoptGRef(g_resources_lookup_data("/org/gtk/libgtk/emoji/emoji.data", G_RESOURCE_LOOKUP_FLAGS_NONE, nullptr));
    GRefPtr<GVariant> data = g_variant_new_from_bytes(G_VARIANT_TYPE("a(auss)"), bytes.get(), TRUE);
    GUniquePtr<GVariantIter> iter(g_variant_iter_new(data.get()));

    Function<void()> populateSections = [chooser, iter = WTFMove(iter), flowBox]() mutable {
        auto start = MonotonicTime::now();
        while (GRefPtr<GVariant> item = adoptGRef(g_variant_iter_next_value(iter.get()))) {
            const char* name;
            g_variant_get_child(item.get(), 1, "&s", &name);

            auto index = chooser->priv->sections.findMatching([&name](const auto& section) {
                return !g_strcmp0(name, section.firstEmojiName);
            });
            flowBox = index == notFound ? flowBox : chooser->priv->sections[index].box;
            auto* child = webkitEmojiChooserAddEmoji(chooser, GTK_FLOW_BOX(flowBox), item.get());
            if (child)
                g_signal_connect(child, "popup-menu", G_CALLBACK(emojiPopupMenu), chooser);

            if (MonotonicTime::now() - start >= 8_ms)
                return;
        }
        chooser->priv->populateSectionsTimer = nullptr;
    };

    chooser->priv->populateSectionsTimer = makeUnique<CallbackTimer>(WTFMove(populateSections));
    chooser->priv->populateSectionsTimer->setPriority(G_PRIORITY_DEFAULT_IDLE);
    chooser->priv->populateSectionsTimer->setName("[WebKitEmojiChooser] populate sections timer");
    chooser->priv->populateSectionsTimer->startRepeating({ });
}

static void webkitEmojiChooserInitializeEmojiMaxWidth(WebKitEmojiChooser* chooser)
{
    // Get a reasonable maximum width for an emoji. We do this to skip overly wide fallback
    // rendering for certain emojis the font does not contain and therefore end up being
    // rendered as multiple glyphs.
    GRefPtr<PangoLayout> layout = adoptGRef(gtk_widget_create_pango_layout(GTK_WIDGET(chooser), "🙂"));
    auto* attributes = pango_attr_list_new();
    pango_attr_list_insert(attributes, pango_attr_scale_new(PANGO_SCALE_X_LARGE));
    pango_layout_set_attributes(layout.get(), attributes);
    pango_attr_list_unref(attributes);

    PangoRectangle rect;
    pango_layout_get_extents(layout.get(), &rect, nullptr);
    chooser->priv->emojiMaxWidth = rect.width;
}

static void webkitEmojiChooserConstructed(GObject* object)
{
    WebKitEmojiChooser* chooser = WEBKIT_EMOJI_CHOOSER(object);
    chooser->priv->settings = adoptGRef(g_settings_new("org.gtk.Settings.EmojiChooser"));

    G_OBJECT_CLASS(webkit_emoji_chooser_parent_class)->constructed(object);

    webkitEmojiChooserInitializeEmojiMaxWidth(chooser);

    gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(object)), "emoji-picker");

    GtkWidget* mainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    GtkWidget* searchEntry = gtk_search_entry_new();
    chooser->priv->searchEntry = searchEntry;
    g_signal_connect_swapped(searchEntry, "search-changed", G_CALLBACK(webkitEmojiChooserSearchChanged), chooser);
    gtk_entry_set_input_hints(GTK_ENTRY(searchEntry), GTK_INPUT_HINT_NO_EMOJI);
    gtk_box_pack_start(GTK_BOX(mainBox), searchEntry, TRUE, FALSE, 0);
    gtk_widget_show(searchEntry);

    GtkWidget* stack = gtk_stack_new();
    chooser->priv->stack = stack;
    GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    GtkWidget* swindow = gtk_scrolled_window_new(nullptr, nullptr);
    chooser->priv->swindow = swindow;
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(swindow), 250);
    gtk_style_context_add_class(gtk_widget_get_style_context(swindow), "view");
    gtk_box_pack_start(GTK_BOX(box), swindow, TRUE, TRUE, 0);
    gtk_widget_show(swindow);

    GtkWidget* emojiBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
    g_object_set(emojiBox, "margin", 6, nullptr);
    gtk_container_add(GTK_CONTAINER(swindow), emojiBox);
    gtk_widget_show(emojiBox);

    GtkWidget* buttonBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_box_pack_start(GTK_BOX(box), buttonBox, TRUE, FALSE, 0);
    gtk_widget_show(buttonBox);

    GtkAdjustment* vAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(swindow));
    g_signal_connect(vAdjustment, "value-changed", G_CALLBACK(verticalAdjustmentChanged), chooser);

    webkitEmojiChooserSetupRecent(chooser, GTK_BOX(emojiBox), GTK_BOX(buttonBox), vAdjustment);

    webkitEmojiChooserSetupEmojiSections(chooser, GTK_BOX(emojiBox), GTK_BOX(buttonBox));

    gtk_widget_set_state_flags(chooser->priv->sections.first().button, GTK_STATE_FLAG_CHECKED, FALSE);

    gtk_stack_add_named(GTK_STACK(stack), box, "list");
    gtk_widget_show(box);

    gtk_box_pack_start(GTK_BOX(mainBox), stack, TRUE, TRUE, 0);
    gtk_widget_show(stack);

    gtk_container_add(GTK_CONTAINER(object), mainBox);
    gtk_widget_show(mainBox);

    webkitEmojiChooserSetupFilters(chooser);
}

static void webkitEmojiChooserShow(GtkWidget* widget)
{
    GTK_WIDGET_CLASS(webkit_emoji_chooser_parent_class)->show(widget);

    WebKitEmojiChooser* chooser = WEBKIT_EMOJI_CHOOSER(widget);
    auto* adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(chooser->priv->swindow));
    gtk_adjustment_set_value(adjustment, 0);

    gtk_entry_set_text(GTK_ENTRY(chooser->priv->searchEntry), "");
}

static void webkit_emoji_chooser_class_init(WebKitEmojiChooserClass* klass)
{
    GObjectClass* objectClass = G_OBJECT_CLASS(klass);
    objectClass->constructed = webkitEmojiChooserConstructed;

    GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(klass);
    widgetClass->show = webkitEmojiChooserShow;

    signals[EMOJI_PICKED] = g_signal_new(
        "emoji-picked",
        G_OBJECT_CLASS_TYPE(objectClass),
        G_SIGNAL_RUN_LAST,
        0,
        nullptr, nullptr,
        nullptr,
        G_TYPE_NONE, 1,
        G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
}

GtkWidget* webkitEmojiChooserNew()
{
    WebKitEmojiChooser* authDialog = WEBKIT_EMOJI_CHOOSER(g_object_new(WEBKIT_TYPE_EMOJI_CHOOSER, nullptr));
    return GTK_WIDGET(authDialog);
}

#endif // GTK_CHECK_VERSION(3, 24, 0)
