/*
 * Copyright (C) 2012 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2,1 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.
 */

#include "config.h"
#include "WebKitFindController.h"

#include "APIFindClient.h"
#include "WebKitEnumTypes.h"
#include "WebKitWebViewPrivate.h"
#include <glib/gi18n-lib.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/WTFGType.h>
#include <wtf/text/CString.h>

using namespace WebKit;
using namespace WebCore;

/**
 * SECTION: WebKitFindController
 * @Short_description: Controls text search in a #WebKitWebView
 * @Title: WebKitFindController
 *
 * A #WebKitFindController is used to search text in a #WebKitWebView. You
 * can get a #WebKitWebView<!-- -->'s #WebKitFindController with
 * webkit_web_view_get_find_controller(), and later use it to search
 * for text using webkit_find_controller_search(), or get the
 * number of matches using webkit_find_controller_count_matches(). The
 * operations are asynchronous and trigger signals when ready, such as
 * #WebKitFindController::found-text,
 * #WebKitFindController::failed-to-find-text or
 * #WebKitFindController::counted-matches<!-- -->.
 *
 */

enum {
    FOUND_TEXT,
    FAILED_TO_FIND_TEXT,
    COUNTED_MATCHES,

    LAST_SIGNAL
};

enum {
    PROP_0,

    PROP_TEXT,
    PROP_OPTIONS,
    PROP_MAX_MATCH_COUNT,
    PROP_WEB_VIEW
};

typedef enum {
    FindOperation,
    FindNextPrevOperation,
    CountOperation
} WebKitFindControllerOperation;

struct _WebKitFindControllerPrivate {
    CString searchText;
    // Interpreted as WebKit::FindOptions.
    uint32_t findOptions;
    unsigned maxMatchCount;
    WebKitWebView* webView;
};

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

WEBKIT_DEFINE_TYPE(WebKitFindController, webkit_find_controller, G_TYPE_OBJECT)

static inline WebKit::FindOptions toWebFindOptions(uint32_t findOptions)
{
    return static_cast<WebKit::FindOptions>((findOptions & WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE ? FindOptionsCaseInsensitive : 0)
        | (findOptions & WEBKIT_FIND_OPTIONS_AT_WORD_STARTS ? FindOptionsAtWordStarts : 0)
        | (findOptions & WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START ? FindOptionsTreatMedialCapitalAsWordStart : 0)
        | (findOptions & WEBKIT_FIND_OPTIONS_BACKWARDS ? FindOptionsBackwards : 0)
        | (findOptions & WEBKIT_FIND_OPTIONS_WRAP_AROUND ? FindOptionsWrapAround : 0));
}

static inline WebKitFindOptions toWebKitFindOptions(uint32_t findOptions)
{
    return static_cast<WebKitFindOptions>((findOptions & FindOptionsCaseInsensitive ? WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE : 0)
        | (findOptions & FindOptionsAtWordStarts ? WEBKIT_FIND_OPTIONS_AT_WORD_STARTS : 0)
        | (findOptions & FindOptionsTreatMedialCapitalAsWordStart ? WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START : 0)
        | (findOptions & FindOptionsBackwards ? WEBKIT_FIND_OPTIONS_BACKWARDS : 0)
        | (findOptions & FindOptionsWrapAround ? WEBKIT_FIND_OPTIONS_WRAP_AROUND : 0));
}

static inline WebPageProxy& getPage(WebKitFindController* findController)
{
    return webkitWebViewGetPage(findController->priv->webView);
}

class FindClient final : public API::FindClient {
public:
    explicit FindClient(WebKitFindController* findController)
        : m_findController(findController)
    {
    }

private:
    void didCountStringMatches(WebPageProxy*, const String&, uint32_t matchCount) override
    {
        g_signal_emit(m_findController, signals[COUNTED_MATCHES], 0, matchCount);
    }

    void didFindString(WebPageProxy*, const String&, const Vector<IntRect>&, uint32_t matchCount, int32_t, bool /*didWrapAround*/) override
    {
        g_signal_emit(m_findController, signals[FOUND_TEXT], 0, matchCount);
    }

    void didFailToFindString(WebPageProxy*, const String&) override
    {
        g_signal_emit(m_findController, signals[FAILED_TO_FIND_TEXT], 0);
    }

    WebKitFindController* m_findController;
};

static void webkitFindControllerConstructed(GObject* object)
{
    G_OBJECT_CLASS(webkit_find_controller_parent_class)->constructed(object);

    WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object);
    getPage(findController).setFindClient(makeUnique<FindClient>(findController));
}

static void webkitFindControllerGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
{
    WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object);

    switch (propId) {
    case PROP_TEXT:
        g_value_set_string(value, webkit_find_controller_get_search_text(findController));
        break;
    case PROP_OPTIONS:
        g_value_set_uint(value, webkit_find_controller_get_options(findController));
        break;
    case PROP_MAX_MATCH_COUNT:
        g_value_set_uint(value, webkit_find_controller_get_max_match_count(findController));
        break;
    case PROP_WEB_VIEW:
        g_value_set_object(value, webkit_find_controller_get_web_view(findController));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static void webkitFindControllerSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
{
    WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object);

    switch (propId) {
    case PROP_WEB_VIEW:
        findController->priv->webView = WEBKIT_WEB_VIEW(g_value_get_object(value));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static void webkit_find_controller_class_init(WebKitFindControllerClass* findClass)
{
    GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
    gObjectClass->constructed = webkitFindControllerConstructed;
    gObjectClass->get_property = webkitFindControllerGetProperty;
    gObjectClass->set_property = webkitFindControllerSetProperty;

    /**
     * WebKitFindController:text:
     *
     * The current search text for this #WebKitFindController.
     */
    g_object_class_install_property(gObjectClass,
                                    PROP_TEXT,
                                    g_param_spec_string("text",
                                                        _("Search text"),
                                                        _("Text to search for in the view"),
                                                        0,
                                                        WEBKIT_PARAM_READABLE));

    /**
     * WebKitFindController:options:
     *
     * The options to be used in the search operation.
     */
    g_object_class_install_property(gObjectClass,
                                    PROP_OPTIONS,
                                    g_param_spec_flags("options",
                                                       _("Search Options"),
                                                       _("Search options to be used in the search operation"),
                                                       WEBKIT_TYPE_FIND_OPTIONS,
                                                       WEBKIT_FIND_OPTIONS_NONE,
                                                       WEBKIT_PARAM_READABLE));

    /**
     * WebKitFindController:max-match-count:
     *
     * The maximum number of matches to report for a given search.
     */
    g_object_class_install_property(gObjectClass,
                                    PROP_MAX_MATCH_COUNT,
                                    g_param_spec_uint("max-match-count",
                                                      _("Maximum matches count"),
                                                      _("The maximum number of matches in a given text to report"),
                                                      0, G_MAXUINT, 0,
                                                      WEBKIT_PARAM_READABLE));

    /**
     * WebKitFindController:web-view:
     *
     * The #WebKitWebView this controller is associated to.
     */
    g_object_class_install_property(gObjectClass,
                                    PROP_WEB_VIEW,
                                    g_param_spec_object("web-view",
                                                        _("WebView"),
                                                        _("The WebView associated with this find controller"),
                                                        WEBKIT_TYPE_WEB_VIEW,
                                                        static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));

    /**
     * WebKitFindController::found-text:
     * @find_controller: the #WebKitFindController
     * @match_count: the number of matches found of the search text
     *
     * This signal is emitted when a given text is found in the web
     * page text. It will be issued if the text is found
     * asynchronously after a call to webkit_find_controller_search(),
     * webkit_find_controller_search_next() or
     * webkit_find_controller_search_previous().
     */
    signals[FOUND_TEXT] =
        g_signal_new("found-text",
                     G_TYPE_FROM_CLASS(gObjectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     g_cclosure_marshal_VOID__UINT,
                     G_TYPE_NONE, 1, G_TYPE_UINT);

    /**
     * WebKitFindController::failed-to-find-text:
     * @find_controller: the #WebKitFindController
     *
     * This signal is emitted when a search operation does not find
     * any result for the given text. It will be issued if the text
     * is not found asynchronously after a call to
     * webkit_find_controller_search(), webkit_find_controller_search_next()
     * or webkit_find_controller_search_previous().
     */
    signals[FAILED_TO_FIND_TEXT] =
        g_signal_new("failed-to-find-text",
                     G_TYPE_FROM_CLASS(gObjectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     g_cclosure_marshal_VOID__VOID,
                     G_TYPE_NONE, 0);

    /**
     * WebKitFindController::counted-matches:
     * @find_controller: the #WebKitFindController
     * @match_count: the number of matches of the search text
     *
     * This signal is emitted when the #WebKitFindController has
     * counted the number of matches for a given text after a call
     * to webkit_find_controller_count_matches().
     */
    signals[COUNTED_MATCHES] =
        g_signal_new("counted-matches",
                     G_TYPE_FROM_CLASS(gObjectClass),
                     G_SIGNAL_RUN_LAST,
                     0, 0, 0,
                     g_cclosure_marshal_VOID__UINT,
                     G_TYPE_NONE, 1, G_TYPE_UINT);
}

/**
 * webkit_find_controller_get_search_text:
 * @find_controller: the #WebKitFindController
 *
 * Gets the text that @find_controller is currently searching
 * for. This text is passed to either
 * webkit_find_controller_search() or
 * webkit_find_controller_count_matches().
 *
 * Returns: the text to look for in the #WebKitWebView.
 */
const char* webkit_find_controller_get_search_text(WebKitFindController* findController)
{
    g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0);

    return findController->priv->searchText.data();
}

/**
 * webkit_find_controller_get_options:
 * @find_controller: the #WebKitFindController
 *
 * Gets a bitmask containing the #WebKitFindOptions associated with
 * the current search.
 *
 * Returns: a bitmask containing the #WebKitFindOptions associated
 * with the current search.
 */
guint32 webkit_find_controller_get_options(WebKitFindController* findController)
{
    g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), WEBKIT_FIND_OPTIONS_NONE);

    return toWebKitFindOptions(findController->priv->findOptions);
}

/**
 * webkit_find_controller_get_max_match_count:
 * @find_controller: the #WebKitFindController
 *
 * Gets the maximum number of matches to report during a text
 * lookup. This number is passed as the last argument of
 * webkit_find_controller_search() or
 * webkit_find_controller_count_matches().
 *
 * Returns: the maximum number of matches to report.
 */
guint webkit_find_controller_get_max_match_count(WebKitFindController* findController)
{
    g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0);

    return findController->priv->maxMatchCount;
}

/**
 * webkit_find_controller_get_web_view:
 * @find_controller: the #WebKitFindController
 *
 * Gets the #WebKitWebView this find controller is associated to. Do
 * not dereference the returned instance as it belongs to the
 * #WebKitFindController.
 *
 * Returns: (transfer none): the #WebKitWebView.
 */
WebKitWebView* webkit_find_controller_get_web_view(WebKitFindController* findController)
{
    g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0);

    return findController->priv->webView;
}

static void webKitFindControllerPerform(WebKitFindController* findController, WebKitFindControllerOperation operation)
{
    WebKitFindControllerPrivate* priv = findController->priv;
    if (operation == CountOperation) {
        getPage(findController).countStringMatches(String::fromUTF8(priv->searchText.data()),
            static_cast<WebKit::FindOptions>(priv->findOptions), priv->maxMatchCount);
        return;
    }

    uint32_t findOptions = priv->findOptions;
    if (operation == FindOperation)
        // Unconditionally highlight text matches when the search
        // starts. WK1 API was forcing clients to enable/disable
        // highlighting. Since most of them (all?) where using that
        // feature we decided to simplify the WK2 API and
        // unconditionally show highlights. Both search_next() and
        // search_prev() should not enable highlighting to avoid an
        // extra unmarkAllTextMatches() + markAllTextMatches()
        findOptions |= FindOptionsShowHighlight;

    getPage(findController).findString(String::fromUTF8(priv->searchText.data()), static_cast<WebKit::FindOptions>(findOptions), priv->maxMatchCount);
}

static inline void webKitFindControllerSetSearchData(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount)
{
    findController->priv->searchText = searchText;
    findController->priv->findOptions = findOptions;
    findController->priv->maxMatchCount = maxMatchCount;
}

/**
 * webkit_find_controller_search:
 * @find_controller: the #WebKitFindController
 * @search_text: the text to look for
 * @find_options: a bitmask with the #WebKitFindOptions used in the search
 * @max_match_count: the maximum number of matches allowed in the search
 *
 * Looks for @search_text in the #WebKitWebView associated with
 * @find_controller since the beginning of the document highlighting
 * up to @max_match_count matches. The outcome of the search will be
 * asynchronously provided by the #WebKitFindController::found-text
 * and #WebKitFindController::failed-to-find-text signals.
 *
 * To look for the next or previous occurrences of the same text
 * with the same find options use webkit_find_controller_search_next()
 * and/or webkit_find_controller_search_previous(). The
 * #WebKitFindController will use the same text and options for the
 * following searches unless they are modified by another call to this
 * method.
 *
 * Note that if the number of matches is higher than @max_match_count
 * then #WebKitFindController::found-text will report %G_MAXUINT matches
 * instead of the actual number.
 *
 * Callers should call webkit_find_controller_search_finish() to
 * finish the current search operation.
 */
void webkit_find_controller_search(WebKitFindController* findController, const gchar* searchText, guint findOptions, guint maxMatchCount)
{
    g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
    g_return_if_fail(searchText);
    webKitFindControllerSetSearchData(findController, searchText, toWebFindOptions(findOptions), maxMatchCount);
    webKitFindControllerPerform(findController, FindOperation);
}

/**
 * webkit_find_controller_search_next:
 * @find_controller: the #WebKitFindController
 *
 * Looks for the next occurrence of the search text.
 *
 * Calling this method before webkit_find_controller_search() or
 * webkit_find_controller_count_matches() is a programming error.
 */
void webkit_find_controller_search_next(WebKitFindController* findController)
{
    g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));

    findController->priv->findOptions &= ~FindOptionsBackwards;
    findController->priv->findOptions &= ~FindOptionsShowHighlight;
    webKitFindControllerPerform(findController, FindNextPrevOperation);
}

/**
 * webkit_find_controller_search_previous:
 * @find_controller: the #WebKitFindController
 *
 * Looks for the previous occurrence of the search text.
 *
 * Calling this method before webkit_find_controller_search() or
 * webkit_find_controller_count_matches() is a programming error.
 */
void webkit_find_controller_search_previous(WebKitFindController* findController)
{
    g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));

    findController->priv->findOptions |= FindOptionsBackwards;
    findController->priv->findOptions &= ~FindOptionsShowHighlight;
    webKitFindControllerPerform(findController, FindNextPrevOperation);
}

/**
 * webkit_find_controller_count_matches:
 * @find_controller: the #WebKitFindController
 * @search_text: the text to look for
 * @find_options: a bitmask with the #WebKitFindOptions used in the search
 * @max_match_count: the maximum number of matches allowed in the search
 *
 * Counts the number of matches for @search_text found in the
 * #WebKitWebView with the provided @find_options. The number of
 * matches will be provided by the
 * #WebKitFindController::counted-matches signal.
 */
void webkit_find_controller_count_matches(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount)
{
    g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
    g_return_if_fail(searchText);

    webKitFindControllerSetSearchData(findController, searchText, toWebFindOptions(findOptions), maxMatchCount);
    webKitFindControllerPerform(findController, CountOperation);
}

/**
 * webkit_find_controller_search_finish:
 * @find_controller: a #WebKitFindController
 *
 * Finishes a find operation started by
 * webkit_find_controller_search(). It will basically unhighlight
 * every text match found.
 *
 * This method will be typically called when the search UI is
 * closed/hidden by the client application.
 */
void webkit_find_controller_search_finish(WebKitFindController* findController)
{
    g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));

    getPage(findController).hideFindUI();
}
