/*
 * Copyright (C) 2013 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 "cmakeconfig.h"
#include "BrowserSearchBar.h"

static const char *searchEntryFailedStyle = "GtkEntry#searchEntry {background-color: #ff6666;}";

struct _BrowserSearchBar {
    GtkToolbar parent;

    WebKitWebView *webView;
    GtkWidget *entry;
    GtkCssProvider *cssProvider;
    GtkWidget *prevButton;
    GtkWidget *nextButton;
    GtkWidget *optionsMenu;
    GtkWidget *caseCheckButton;
    GtkWidget *begginigWordCheckButton;
    GtkWidget *capitalAsBegginigWordCheckButton;
};

G_DEFINE_TYPE(BrowserSearchBar, browser_search_bar, GTK_TYPE_TOOLBAR)

static void setFailedStyleForEntry(BrowserSearchBar *searchBar, gboolean failedSearch)
{
    gtk_css_provider_load_from_data(searchBar->cssProvider, failedSearch ? searchEntryFailedStyle : "", -1, NULL);
}

static void doSearch(BrowserSearchBar *searchBar)
{
    GtkEntry *entry = GTK_ENTRY(searchBar->entry);

    if (!gtk_entry_get_text_length(entry)) {
        webkit_find_controller_search_finish(webkit_web_view_get_find_controller(searchBar->webView));
        gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_SECONDARY, NULL);
        setFailedStyleForEntry(searchBar, FALSE);
        return;
    }

    if (!gtk_entry_get_icon_stock(entry, GTK_ENTRY_ICON_SECONDARY))
        gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);

    WebKitFindOptions options = WEBKIT_FIND_OPTIONS_WRAP_AROUND;
    if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(searchBar->caseCheckButton)))
        options |= WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE;
    if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(searchBar->begginigWordCheckButton)))
        options |= WEBKIT_FIND_OPTIONS_AT_WORD_STARTS;
    if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(searchBar->capitalAsBegginigWordCheckButton)))
        options |= WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START;

    const gchar *text = gtk_entry_get_text(entry);
    webkit_find_controller_search(webkit_web_view_get_find_controller(searchBar->webView), text, options, G_MAXUINT);
}

static void searchNext(BrowserSearchBar *searchBar)
{
    webkit_find_controller_search_next(webkit_web_view_get_find_controller(searchBar->webView));
}

static void searchPrevious(BrowserSearchBar *searchBar)
{
    webkit_find_controller_search_previous(webkit_web_view_get_find_controller(searchBar->webView));
}

static void searchCloseButtonClickedCallback(BrowserSearchBar *searchBar)
{
    browser_search_bar_close(searchBar);
}

static void searchEntryMenuIconPressedCallback(BrowserSearchBar *searchBar, GtkEntryIconPosition iconPosition, GdkEvent *event)
{
    if (iconPosition == GTK_ENTRY_ICON_PRIMARY) {
        GdkEventButton *eventButton = (GdkEventButton *)event;
        gtk_menu_popup(GTK_MENU(searchBar->optionsMenu), NULL, NULL, NULL, NULL, eventButton->button, eventButton->time);
    }
}

static void searchEntryClearIconReleasedCallback(BrowserSearchBar *searchBar, GtkEntryIconPosition iconPosition)
{
    if (iconPosition == GTK_ENTRY_ICON_SECONDARY)
        gtk_entry_set_text(GTK_ENTRY(searchBar->entry), "");
}

static void searchEntryChangedCallback(GtkEntry *entry, BrowserSearchBar *searchBar)
{
    doSearch(searchBar);
}

static void searchEntryActivatedCallback(BrowserSearchBar *searchBar)
{
    searchNext(searchBar);
}

static void searchPrevButtonClickedCallback(BrowserSearchBar *searchBar)
{
    searchPrevious(searchBar);
}

static void searchNextButtonClickedCallback(BrowserSearchBar *searchBar)
{
    searchNext(searchBar);
}

static void searchMenuCheckButtonToggledCallback(BrowserSearchBar *searchBar)
{
    doSearch(searchBar);
}

static void findControllerFailedToFindTextCallback(BrowserSearchBar *searchBar)
{
    setFailedStyleForEntry(searchBar, TRUE);
}

static void findControllerFoundTextCallback(BrowserSearchBar *searchBar)
{
    setFailedStyleForEntry(searchBar, FALSE);
}

static void browser_search_bar_init(BrowserSearchBar *searchBar)
{
    gtk_widget_set_hexpand(GTK_WIDGET(searchBar), TRUE);

    GtkToolItem *toolItem = gtk_tool_item_new();
    gtk_tool_item_set_expand(toolItem, TRUE);
    gtk_toolbar_insert(GTK_TOOLBAR(searchBar), toolItem, 0);

    GtkBox *hBox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5));
    gtk_box_set_homogeneous(hBox, TRUE);
    gtk_container_add(GTK_CONTAINER(toolItem), GTK_WIDGET(hBox));

    gtk_box_pack_start(hBox, gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), TRUE, TRUE, 0);

    searchBar->entry = gtk_entry_new();
    gtk_widget_set_name(searchBar->entry, "searchEntry");
    gtk_entry_set_placeholder_text(GTK_ENTRY(searchBar->entry), "Search");
    gtk_entry_set_icon_from_stock(GTK_ENTRY(searchBar->entry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND);
    gtk_box_pack_start(hBox, searchBar->entry, TRUE, TRUE, 0);

    searchBar->cssProvider = gtk_css_provider_new();
    gtk_style_context_add_provider(gtk_widget_get_style_context(searchBar->entry), GTK_STYLE_PROVIDER(searchBar->cssProvider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

    GtkBox *hBoxButtons = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
    gtk_box_pack_start(hBox, GTK_WIDGET(hBoxButtons), TRUE, TRUE, 0);

    searchBar->prevButton = gtk_button_new();
    GtkButton *button = GTK_BUTTON(searchBar->prevButton);
    GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_GO_UP, GTK_ICON_SIZE_SMALL_TOOLBAR);
    gtk_button_set_image(button, image);
    gtk_button_set_relief(button, GTK_RELIEF_NONE);
    gtk_button_set_focus_on_click(button, FALSE);
    gtk_box_pack_start(hBoxButtons, searchBar->prevButton, FALSE, FALSE, 0);

    searchBar->nextButton = gtk_button_new();
    button = GTK_BUTTON(searchBar->nextButton);
    image = gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_SMALL_TOOLBAR);
    gtk_button_set_image(button, image);
    gtk_button_set_relief(button, GTK_RELIEF_NONE);
    gtk_button_set_focus_on_click(button, FALSE);
    gtk_box_pack_start(hBoxButtons, searchBar->nextButton, FALSE, FALSE, 0);

    GtkWidget *closeButton = gtk_button_new();
    button = GTK_BUTTON(closeButton);
    image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_SMALL_TOOLBAR);
    gtk_button_set_image(button, image);
    gtk_button_set_relief(button, GTK_RELIEF_NONE);
    gtk_button_set_focus_on_click(button, FALSE);
    gtk_box_pack_end(hBoxButtons, closeButton, FALSE, FALSE, 0);

    searchBar->optionsMenu = g_object_ref_sink(gtk_menu_new());

    searchBar->caseCheckButton = gtk_check_menu_item_new_with_mnemonic("Ca_se sensitive");
    gtk_container_add(GTK_CONTAINER(searchBar->optionsMenu), searchBar->caseCheckButton);

    searchBar->begginigWordCheckButton = gtk_check_menu_item_new_with_mnemonic("Only at the _beginning of words");
    gtk_container_add(GTK_CONTAINER(searchBar->optionsMenu), searchBar->begginigWordCheckButton);

    searchBar->capitalAsBegginigWordCheckButton = gtk_check_menu_item_new_with_mnemonic("Capital _always as beginning of word");
    gtk_container_add(GTK_CONTAINER(searchBar->optionsMenu), searchBar->capitalAsBegginigWordCheckButton);

    g_signal_connect_swapped(closeButton, "clicked", G_CALLBACK(searchCloseButtonClickedCallback), searchBar);
    g_signal_connect_swapped(searchBar->entry, "icon-press", G_CALLBACK(searchEntryMenuIconPressedCallback), searchBar);
    g_signal_connect_swapped(searchBar->entry, "icon-release", G_CALLBACK(searchEntryClearIconReleasedCallback), searchBar);
    g_signal_connect_after(searchBar->entry, "changed", G_CALLBACK(searchEntryChangedCallback), searchBar);
    g_signal_connect_swapped(searchBar->entry, "activate", G_CALLBACK(searchEntryActivatedCallback), searchBar);
    g_signal_connect_swapped(searchBar->nextButton, "clicked", G_CALLBACK(searchNextButtonClickedCallback), searchBar);
    g_signal_connect_swapped(searchBar->prevButton, "clicked", G_CALLBACK(searchPrevButtonClickedCallback), searchBar);
    g_signal_connect_swapped(searchBar->caseCheckButton, "toggled", G_CALLBACK(searchMenuCheckButtonToggledCallback), searchBar);
    g_signal_connect_swapped(searchBar->begginigWordCheckButton, "toggled", G_CALLBACK(searchMenuCheckButtonToggledCallback), searchBar);
    g_signal_connect_swapped(searchBar->capitalAsBegginigWordCheckButton, "toggled", G_CALLBACK(searchMenuCheckButtonToggledCallback), searchBar);

    gtk_widget_show_all(GTK_WIDGET(toolItem));
    gtk_widget_show_all(searchBar->optionsMenu);
}

static void browserSearchBarFinalize(GObject *gObject)
{
    BrowserSearchBar *searchBar = BROWSER_SEARCH_BAR(gObject);

    if (searchBar->webView) {
        g_object_unref(searchBar->webView);
        searchBar->webView = NULL;
    }

    if (searchBar->cssProvider) {
        g_object_unref(searchBar->cssProvider);
        searchBar->cssProvider = NULL;
    }

    if (searchBar->optionsMenu) {
        g_object_unref(searchBar->optionsMenu);
        searchBar->optionsMenu = NULL;
    }

    G_OBJECT_CLASS(browser_search_bar_parent_class)->finalize(gObject);
}

static void browser_search_bar_class_init(BrowserSearchBarClass *klass)
{
    GObjectClass *gObjectClass = G_OBJECT_CLASS(klass);

    gObjectClass->finalize = browserSearchBarFinalize;
}

GtkWidget *browser_search_bar_new(WebKitWebView *webView)
{
    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);

    GtkWidget *searchBar = GTK_WIDGET(g_object_new(BROWSER_TYPE_SEARCH_BAR, NULL));
    BROWSER_SEARCH_BAR(searchBar)->webView = g_object_ref(webView);

    WebKitFindController *controller = webkit_web_view_get_find_controller(webView);
    g_signal_connect_swapped(controller, "failed-to-find-text", G_CALLBACK(findControllerFailedToFindTextCallback), searchBar);
    g_signal_connect_swapped(controller, "found-text", G_CALLBACK(findControllerFoundTextCallback), searchBar);

    return searchBar;
}

void browser_search_bar_add_accelerators(BrowserSearchBar *searchBar, GtkAccelGroup *accelGroup)
{
    g_return_if_fail(BROWSER_IS_SEARCH_BAR(searchBar));
    g_return_if_fail(GTK_IS_ACCEL_GROUP(accelGroup));

    gtk_widget_add_accelerator(searchBar->nextButton, "clicked", accelGroup, GDK_KEY_F3, 0, GTK_ACCEL_VISIBLE);
    gtk_widget_add_accelerator(searchBar->nextButton, "clicked", accelGroup, GDK_KEY_G, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);

    gtk_widget_add_accelerator(searchBar->prevButton, "clicked", accelGroup, GDK_KEY_F3, GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
    gtk_widget_add_accelerator(searchBar->prevButton, "clicked", accelGroup, GDK_KEY_G, GDK_SHIFT_MASK | GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
}

void browser_search_bar_open(BrowserSearchBar *searchBar)
{
    g_return_if_fail(BROWSER_IS_SEARCH_BAR(searchBar));

    GtkEntry *entry = GTK_ENTRY(searchBar->entry);

    gtk_widget_show(GTK_WIDGET(searchBar));
    gtk_widget_grab_focus(GTK_WIDGET(entry));
    gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
    if (gtk_entry_get_text_length(entry))
        doSearch(searchBar);
}

void browser_search_bar_close(BrowserSearchBar *searchBar)
{
    g_return_if_fail(BROWSER_IS_SEARCH_BAR(searchBar));

    gtk_widget_hide(GTK_WIDGET(searchBar));
    WebKitFindController *controller = webkit_web_view_get_find_controller(searchBar->webView);
    webkit_find_controller_search_finish(controller);
}
