/*
    Copyright (C) 2009-2010 ProFUSION embedded systems
    Copyright (C) 2009-2010 Samsung Electronics

    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.
*/

// Uncomment to view frame regions and debug messages
// #define EWK_FRAME_DEBUG

#include "config.h"
#include "ewk_frame.h"

#include "DocumentMarkerController.h"
#include "EWebKit.h"
#include "EventHandler.h"
#include "FocusController.h"
#include "FrameLoaderClientEfl.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLPlugInElement.h"
#include "HistoryItem.h"
#include "HitTestResult.h"
#include "IntSize.h"
#include "KURL.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformTouchEvent.h"
#include "PlatformWheelEvent.h"
#include "ProgressTracker.h"
#include "RefPtr.h"
#include "RenderTheme.h"
#include "ResourceRequest.h"
#include "ScriptValue.h"
#include "SharedBuffer.h"
#include "SubstituteData.h"
#include "WindowsKeyboardCodes.h"
#include "ewk_private.h"

#include <Eina.h>
#include <Evas.h>
#include <algorithm>
#include <eina_safety_checks.h>
#include <wtf/text/CString.h>

static const char EWK_FRAME_TYPE_STR[] = "EWK_Frame";

struct Ewk_Frame_Smart_Data {
    Evas_Object_Smart_Clipped_Data base;
    Evas_Object* self;
    Evas_Object* view;
#ifdef EWK_FRAME_DEBUG
    Evas_Object* region;
#endif
    WebCore::Frame* frame;
    const char* theme;
    const char* title;
    const char* uri;
    const char* name;
    struct {
        Evas_Coord w, h;
    } contents_size;
    Eina_Bool textZoom:1;
    Eina_Bool editable:1;
};

struct Eina_Iterator_Ewk_Frame {
    Eina_Iterator base;
    Evas_Object* obj;
    WebCore::Frame* last;
};

#ifndef EWK_TYPE_CHECK
#define EWK_FRAME_TYPE_CHECK(o, ...) do { } while (0)
#else
#define EWK_FRAME_TYPE_CHECK(o, ...)                                    \
    do {                                                                \
        const char* _tmp_otype = evas_object_type_get(o);               \
        if (EINA_UNLIKELY(_tmp_otype != EWK_FRAME_TYPE_STR)) {          \
            EINA_LOG_CRIT                                               \
                ("%p (%s) is not of an ewk_frame!", o,                  \
                 _tmp_otype ? _tmp_otype : "(null)");                   \
            return __VA_ARGS__;                                         \
        }                                                               \
    } while (0)
#endif

#define EWK_FRAME_SD_GET(o, ptr)                                \
    Ewk_Frame_Smart_Data* ptr = (Ewk_Frame_Smart_Data*)evas_object_smart_data_get(o)

#define EWK_FRAME_SD_GET_OR_RETURN(o, ptr, ...)         \
    EWK_FRAME_TYPE_CHECK(o, __VA_ARGS__);               \
    EWK_FRAME_SD_GET(o, ptr);                           \
    if (!ptr) {                                         \
        CRITICAL("no smart data for object %p (%s)",    \
                 o, evas_object_type_get(o));           \
        return __VA_ARGS__;                             \
    }

static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;

#ifdef EWK_FRAME_DEBUG
static inline void _ewk_frame_debug(Evas_Object* o)
{
    Evas_Object* clip, *parent;
    Evas_Coord x, y, w, h, cx, cy, cw, ch;
    int r, g, b, a, cr, cg, cb, ca;

    evas_object_color_get(o, &r, &g, &b, &a);
    evas_object_geometry_get(o, &x, &y, &w, &h);

    clip = evas_object_clip_get(o);
    evas_object_color_get(clip, &cr, &cg, &cb, &ca);
    evas_object_geometry_get(clip, &cx, &cy, &cw, &ch);

    fprintf(stderr, "%p: type=%s name=%s, visible=%d, color=%02x%02x%02x%02x, %d,%d+%dx%d, clipper=%p (%d, %02x%02x%02x%02x, %d,%d+%dx%d)\n",
            o, evas_object_type_get(o), evas_object_name_get(o), evas_object_visible_get(o),
            r, g, b, a, x, y, w, h,
            clip, evas_object_visible_get(clip), cr, cg, cb, ca, cx, cy, cw, ch);
    parent = evas_object_smart_parent_get(o);
    if (!parent)
        fprintf(stderr, "\n");
    else
        _ewk_frame_debug(parent);
}
#endif

static WebCore::FrameLoaderClientEfl* _ewk_frame_loader_efl_get(WebCore::Frame* frame)
{
    return static_cast<WebCore::FrameLoaderClientEfl*>(frame->loader()->client());
}

static inline Evas_Object* kit(WebCore::Frame* frame)
{
    if (!frame)
        return 0;
    WebCore::FrameLoaderClientEfl* fl = _ewk_frame_loader_efl_get(frame);
    if (!fl)
        return 0;
    return fl->webFrame();
}

static Eina_Bool _ewk_frame_children_iterator_next(Eina_Iterator_Ewk_Frame* it, Evas_Object** data)
{
    EWK_FRAME_SD_GET_OR_RETURN(it->obj, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);

    WebCore::FrameTree* tree = sd->frame->tree(); // check if it's still valid
    EINA_SAFETY_ON_NULL_RETURN_VAL(tree, EINA_FALSE);

    WebCore::Frame* frame;
    if (it->last)
        frame = it->last->tree()->nextSibling();
    else
        frame = tree->firstChild();

    if (!frame)
        return EINA_FALSE;

    *data = kit(frame);
    return EINA_TRUE;
}

static Evas_Object* _ewk_frame_children_iterator_get_container(Eina_Iterator_Ewk_Frame* it)
{
    return it->obj;
}

static void _ewk_frame_smart_add(Evas_Object* o)
{
    EWK_FRAME_SD_GET(o, sd);

    if (!sd) {
        sd = (Ewk_Frame_Smart_Data*)calloc(1, sizeof(Ewk_Frame_Smart_Data));
        if (!sd)
            CRITICAL("could not allocate Ewk_Frame_Smart_Data");
        else
            evas_object_smart_data_set(o, sd);
    }

    sd->self = o;

    _parent_sc.add(o);
    evas_object_static_clip_set(sd->base.clipper, EINA_FALSE);
    evas_object_move(sd->base.clipper, 0, 0);
    evas_object_resize(sd->base.clipper, 0, 0);

#ifdef EWK_FRAME_DEBUG
    sd->region = evas_object_rectangle_add(sd->base.evas);
    static int i = 0;
    switch (i) {
    case 0:
        evas_object_color_set(sd->region, 128, 0, 0, 128);
        break;
    case 1:
        evas_object_color_set(sd->region, 0, 128, 0, 128);
        break;
    case 2:
        evas_object_color_set(sd->region, 0, 0, 128, 128);
        break;
    case 3:
        evas_object_color_set(sd->region, 128, 0, 0, 128);
        break;
    case 4:
        evas_object_color_set(sd->region, 128, 128, 0, 128);
        break;
    case 5:
        evas_object_color_set(sd->region, 128, 0, 128, 128);
        break;
    case 6:
        evas_object_color_set(sd->region, 0, 128, 128, 128);
        break;
    default:
        break;
    }
    i++;
    if (i > 6)
        i = 0;

    evas_object_smart_member_add(sd->region, o);
    evas_object_hide(sd->region);
#endif
}

static void _ewk_frame_smart_del(Evas_Object* o)
{
    WRN("o=%p", o); // XXX REMOVE ME LATER
    EWK_FRAME_SD_GET(o, sd);

    if (sd) {
        if (sd->frame) {
            WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(sd->frame);
            flc->setWebFrame(0);
            sd->frame->loader()->cancelAndClear();
            sd->frame = 0;
        }

        eina_stringshare_del(sd->title);
        eina_stringshare_del(sd->uri);
        eina_stringshare_del(sd->name);
    }

    _parent_sc.del(o);
}

static void _ewk_frame_smart_resize(Evas_Object* o, Evas_Coord w, Evas_Coord h)
{
    EWK_FRAME_SD_GET(o, sd);
    evas_object_resize(sd->base.clipper, w, h);

#ifdef EWK_FRAME_DEBUG
    evas_object_resize(sd->region, w, h);
    Evas_Coord x, y;
    evas_object_geometry_get(sd->region, &x, &y, &w, &h);
    INF("region=%p, visible=%d, geo=%d,%d + %dx%d",
        sd->region, evas_object_visible_get(sd->region), x, y, w, h);
    _ewk_frame_debug(o);
#endif
}

static void _ewk_frame_smart_set(Evas_Smart_Class* api)
{
    evas_object_smart_clipped_smart_set(api);
    api->add = _ewk_frame_smart_add;
    api->del = _ewk_frame_smart_del;
    api->resize = _ewk_frame_smart_resize;
}

static inline Evas_Smart* _ewk_frame_smart_class_new(void)
{
    static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION(EWK_FRAME_TYPE_STR);
    static Evas_Smart* smart = 0;

    if (EINA_UNLIKELY(!smart)) {
        evas_object_smart_clipped_smart_set(&_parent_sc);
        _ewk_frame_smart_set(&sc);
        smart = evas_smart_class_new(&sc);
    }

    return smart;
}

/**
 * @internal
 *
 * Creates a new EFL WebKit Frame object.
 *
 * Frames are low level entries contained in a page that is contained
 * by a view. Usually one operates on the view and not directly on the
 * frame.
 *
 * @param e canvas where to create the frame object.
 *
 * @return frame object or @c NULL if errors.
 */
Evas_Object* ewk_frame_add(Evas* e)
{
    return evas_object_smart_add(e, _ewk_frame_smart_class_new());
}

/**
 * Retrieves the ewk_view object that owns this frame.
 *
 * @param o frame object to get view from.
 *
 * @return view object or @c NULL if errors.
 */
Evas_Object* ewk_frame_view_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    return sd->view;
}

/**
 * Set the theme path to be used by this frame.
 *
 * Frames inherit theme from their parent, this will have all frames
 * with unset theme to use this one.
 *
 * @param o frame object to change theme.
 * @param path theme path, may be @c NULL to reset to default or inherit parent.
 */
void ewk_frame_theme_set(Evas_Object* o, const char* path)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    if (!eina_stringshare_replace(&sd->theme, path))
        return;
    if (sd->frame && sd->frame->view()) {
        sd->frame->view()->setEdjeTheme(WTF::String(path));
        sd->frame->page()->theme()->themeChanged();
    }
}

/**
 * Gets the immediate theme set on this frame.
 *
 * This returns the value set by ewk_frame_theme_set(). Note that if
 * it is @c NULL, the frame will inherit parent's theme.
 *
 * @param o frame object to get theme path.
 *
 * @return theme path, may be @c NULL if not set.
 */
const char* ewk_frame_theme_get(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    return sd->theme;
}

/**
 * Returns a new iterator over all direct children frames.
 *
 * Keep frame object intact while iteration happens otherwise frame
 * may be destroyed while iterated.
 *
 * Iteration results are Evas_Object*, so give eina_iterator_next() a
 * pointer to it.
 *
 * @return a newly allocated iterator, free using
 *         eina_iterator_free(). If not possible to create the
 *         iterator, @c NULL is returned.
 */
Eina_Iterator* ewk_frame_children_iterator_new(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    Eina_Iterator_Ewk_Frame* it = (Eina_Iterator_Ewk_Frame*)
        calloc(1, sizeof(Eina_Iterator_Ewk_Frame));
    if (!it)
        return 0;

    EINA_MAGIC_SET(&it->base, EINA_MAGIC_ITERATOR);
    it->base.next = FUNC_ITERATOR_NEXT(_ewk_frame_children_iterator_next);
    it->base.get_container = FUNC_ITERATOR_GET_CONTAINER(_ewk_frame_children_iterator_get_container);
    it->base.free = FUNC_ITERATOR_FREE(free);
    it->obj = o;
    return &it->base;
}

/**
 * Finds a child frame by its name, recursively.
 *
 * For pre-defined names, returns @a o if @a name is "_self" or
 * "_current", returns @a o's parent frame if @a name is "_parent",
 * and returns the main frame if @a name is "_top". Also returns @a o
 * if it is the main frame and @a name is either "_parent" or
 * "_top". For other names, this function returns the first frame that
 * matches @a name. This function searches @a o and its descendents
 * first, then @a o's parent and its children moving up the hierarchy
 * until a match is found. If no match is found in @a o's hierarchy,
 * this function will search for a matching frame in other main frame
 * hierarchies.
 *
 * @return object if found, @c NULL if nothing with that name.
 */
Evas_Object* ewk_frame_child_find(Evas_Object* o, const char* name)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0);
    WTF::String s = WTF::String::fromUTF8(name);
    return kit(sd->frame->tree()->find(WTF::AtomicString(s)));
}

/**
 * Ask main frame to load the given URI.
 *
 * @param o frame object to load uri.
 * @param uri uniform resource identifier to load.
 */
Eina_Bool ewk_frame_uri_set(Evas_Object* o, const char* uri)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri));
    WebCore::ResourceRequest req(kurl);
    WebCore::FrameLoader* loader = sd->frame->loader();
    loader->load(req, false);
    return EINA_TRUE;
}

/**
 * Gets the uri of this frame.
 *
 * @param o frame object to get uri.
 *
 * @return frame uri or @c NULL. It's a internal string and should
 *         not be modified. The string is guaranteed to be stringshared.
 */
const char* ewk_frame_uri_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    return sd->uri;
}

/**
 * Gets the title of this frame.
 *
 * @param o frame object to get title.
 *
 * @return frame title or @c NULL. It's a internal string and should
 *         not be modified. The string is guaranteed to be stringshared.
 */
const char* ewk_frame_title_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    return sd->title;
}

/**
 * Gets the name of this frame.
 *
 * @param o frame object to get name.
 *
 * @return frame name or @c NULL. It's a internal string and should
 *         not be modified. The string is guaranteed to be stringshared.
 */
const char* ewk_frame_name_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);

    if (sd->name)
        return sd->name;

    if (!sd->frame) {
        ERR("could not get name of uninitialized frame.");
        return 0;
    }

    WTF::String s = sd->frame->tree()->uniqueName();
    WTF::CString cs = s.utf8();
    sd->name = eina_stringshare_add_length(cs.data(), cs.length());
    return sd->name;
}

/**
 * Get last known contents size.
 *
 * @param o frame object to get contents size.
 * @param w where to store contents size width. May be @c NULL.
 * @param h where to store contents size height. May be @c NULL.
 *
 * @return @c EINA_TRUE on success or @c EINA_FALSE on failure and
 *         @a w and @a h will be zeroed.
 */
Eina_Bool ewk_frame_contents_size_get(const Evas_Object* o, Evas_Coord* w, Evas_Coord* h)
{
    if (w)
        *w = 0;
    if (h)
        *h = 0;
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    if (w)
        *w = sd->contents_size.w;
    if (h)
        *h = sd->contents_size.h;
    return EINA_TRUE;
}

static Eina_Bool _ewk_frame_contents_set_internal(Ewk_Frame_Smart_Data *sd, const char* contents, size_t contents_size, const char* mime_type, const char* encoding, const char* base_uri, const char* unreachable_uri)
{
    size_t len = strlen(contents);
    if (contents_size < 1 || contents_size > len)
        contents_size = len;
    if (!mime_type)
        mime_type = "text/html";
    if (!encoding)
        encoding = "UTF-8";
    if (!base_uri)
        base_uri = "about:blank";

    WebCore::KURL baseKURL(WebCore::KURL(), WTF::String::fromUTF8(base_uri));
    WebCore::KURL unreachableKURL;
    if (unreachable_uri)
        unreachableKURL = WebCore::KURL(WebCore::KURL(), WTF::String::fromUTF8(unreachable_uri));
    else
        unreachableKURL = WebCore::KURL();

    WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(contents, contents_size);
    WebCore::SubstituteData substituteData
        (buffer.release(),
         WTF::String::fromUTF8(mime_type),
         WTF::String::fromUTF8(encoding),
         baseKURL, unreachableKURL);
    WebCore::ResourceRequest request(baseKURL);

    sd->frame->loader()->load(request, substituteData, false);
    return EINA_TRUE;
}

/**
 * Requests loading the given contents in this frame.
 *
 * @param o frame object to load document.
 * @param contents what to load into frame. Must not be @c NULL.
 * @param contents_size byte size of data in @a contents.
 *        If zero, strlen() is used.
 * @param mime_type type of @a contents data. If @c NULL "text/html" is assumed.
 * @param encoding used for @a contents data. If @c NULL "UTF-8" is assumed.
 * @param base_uri base uri to use for relative resources. May be @c NULL.
 *        If provided must be an absolute uri.
 *
 * @return @c EINA_TRUE on successful request, @c EINA_FALSE on errors.
 */
Eina_Bool ewk_frame_contents_set(Evas_Object* o, const char* contents, size_t contents_size, const char* mime_type, const char* encoding, const char* base_uri)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(contents, EINA_FALSE);
    return _ewk_frame_contents_set_internal
        (sd, contents, contents_size, mime_type, encoding, base_uri, 0);
}

/**
 * Requests loading alternative contents for unreachable URI in this frame.
 *
 * This is similar to ewk_frame_contents_set(), but is used when some
 * URI failed to load, using the provided content instead. The main
 * difference is that back-forward navigation list is not changed.
 *
 * @param o frame object to load document.
 * @param contents what to load into frame. Must not be @c NULL.
 * @param contents_size byte size of data in @a contents.
 *        If zero, strlen() is used.
 * @param mime_type type of @a contents data. If @c NULL "text/html" is assumed.
 * @param encoding used for @a contents data. If @c NULL "UTF-8" is assumed.
 * @param base_uri base uri to use for relative resources. May be @c NULL.
 *        If provided must be an absolute uri.
 * @param unreachable_uri the URI that failed to load and is getting the
 *        alternative representation.
 *
 * @return @c EINA_TRUE on successful request, @c EINA_FALSE on errors.
 */
Eina_Bool ewk_frame_contents_alternate_set(Evas_Object* o, const char* contents, size_t contents_size, const char* mime_type, const char* encoding, const char* base_uri, const char* unreachable_uri)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(contents, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(unreachable_uri, EINA_FALSE);
    return _ewk_frame_contents_set_internal
        (sd, contents, contents_size, mime_type, encoding, base_uri,
         unreachable_uri);
}

/**
 * Requests execution of given script.
 *
 * @param o frame object to execute script.
 * @param script java script to execute.
 *
 * @return @c EINA_TRUE if request was done, @c EINA_FALSE on errors.
 */
Eina_Bool ewk_frame_script_execute(Evas_Object* o, const char* script)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(script, EINA_FALSE);
    sd->frame->script()->executeScript(WTF::String::fromUTF8(script), true);
    return EINA_TRUE;
}

/**
 * Gets if frame is editable.
 *
 * @param o frame object to get editable state.
 *
 * @return @c EINA_TRUE if editable, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_editable_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return sd->editable;
}

/**
 * Sets if frame is editable.
 *
 * @param o frame object to set editable state.
 * @param editable new state.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_editable_set(Evas_Object* o, Eina_Bool editable)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    editable = !!editable;
    if (sd->editable == editable)
        return EINA_TRUE;
    if (editable)
        sd->frame->editor()->applyEditingStyleToBodyElement();
    return EINA_TRUE;
}

/**
 * Get the copy of the selection text.
 *
 * @param o frame object to get selection text.
 *
 * @return newly allocated string or @c NULL if nothing is selected or failure.
 */
char* ewk_frame_selection_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0);
    WTF::CString s = sd->frame->editor()->selectedText().utf8();
    if (s.isNull())
        return 0;
    return strdup(s.data());
}

static inline Eina_Bool _ewk_frame_editor_command(Ewk_Frame_Smart_Data* sd, const char* command)
{
    return sd->frame->editor()->command(WTF::String::fromUTF8(command)).execute();
}

/**
 * Unselects whatever was selected.
 *
 * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_select_none(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return _ewk_frame_editor_command(sd, "Unselect");
}

/**
 * Selects everything.
 *
 * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_select_all(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return _ewk_frame_editor_command(sd, "SelectAll");
}

/**
 * Selects the current paragrah.
 *
 * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_select_paragraph(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return _ewk_frame_editor_command(sd, "SelectParagraph");
}

/**
 * Selects the current sentence.
 *
 * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_select_sentence(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return _ewk_frame_editor_command(sd, "SelectSentence");
}

/**
 * Selects the current line.
 *
 * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_select_line(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return _ewk_frame_editor_command(sd, "SelectLine");
}

/**
 * Selects the current word.
 *
 * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_select_word(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return _ewk_frame_editor_command(sd, "SelectWord");
}

/**
 * Search the given text string in document.
 *
 * @param o frame object where to search text.
 * @param string reference string to search.
 * @param case_sensitive if search should be case sensitive or not.
 * @param forward if search is from cursor and on or backwards.
 * @param wrap if search should wrap at end.
 *
 * @return @c EINA_TRUE if found, @c EINA_FALSE if not or failure.
 */
Eina_Bool ewk_frame_text_search(const Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);

    return sd->frame->editor()->findString(WTF::String::fromUTF8(string), forward, case_sensitive, wrap, true);
}

/**
 * Mark matches the given text string in document.
 *
 * @param o frame object where to search text.
 * @param string reference string to match.
 * @param case_sensitive if match should be case sensitive or not.
 * @param highlight if matches should be highlighted.
 * @param limit maximum amount of matches, or zero to unlimited.
 *
 * @return number of matches.
 */
unsigned int ewk_frame_text_matches_mark(Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);

    sd->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
    return sd->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), case_sensitive, limit, true);
}

/**
 * Reverses the effect of ewk_frame_text_matches_mark()
 *
 * @param o frame object where to search text.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE for failure.
 */
Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);

    sd->frame->document()->markers()->removeMarkers(WebCore::DocumentMarker::TextMatch);
    return EINA_TRUE;
}

/**
 * Set if should highlight matches marked with ewk_frame_text_matches_mark().
 *
 * @param o frame object where to set if matches are highlighted or not.
 * @param highlight if @c EINA_TRUE, matches will be highlighted.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE for failure.
 */
Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* o, Eina_Bool highlight)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    sd->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight);
    return EINA_TRUE;
}

/**
 * Get if should highlight matches marked with ewk_frame_text_matches_mark().
 *
 * @param o frame object to query if matches are highlighted or not.
 *
 * @return @c EINA_TRUE if they are highlighted, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    return sd->frame->editor()->markedTextMatchesAreHighlighted();
}

/** 
 * Comparison function used by ewk_frame_text_matches_nth_pos_get
 */
static bool _ewk_frame_rect_cmp_less_than(const WebCore::IntRect& i, const WebCore::IntRect& j)
{
    return (i.y() < j.y() || (i.y() == j.y() && i.x() < j.x()));
}   
    
/**
 * Predicate used by ewk_frame_text_matches_nth_pos_get
 */
static bool _ewk_frame_rect_is_negative_value(const WebCore::IntRect& i)
{
    return (i.x() < 0 || i.y() < 0);
}

/**
 * Get x, y position of n-th text match in frame
 *
 * @param o frame object where matches are highlighted.
 * @param n index of element 
 * @param x where to return x position. May be @c NULL. 
 * @param y where to return y position. May be @c NULL.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE for failure - when no matches found or 
 *         n bigger than search results.
 */
Eina_Bool ewk_frame_text_matches_nth_pos_get(Evas_Object* o, size_t n, int* x, int* y)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);

    Vector<WebCore::IntRect> intRects = sd->frame->document()->markers()->renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch);

    /* remove useless values */
    std::remove_if(intRects.begin(), intRects.end(), _ewk_frame_rect_is_negative_value);

    if (intRects.isEmpty() || n > intRects.size())
      return EINA_FALSE;

    std::sort(intRects.begin(), intRects.end(), _ewk_frame_rect_cmp_less_than);

    if (x)
      *x = intRects[n - 1].x();
    if (y)
      *y = intRects[n - 1].y();
    return EINA_TRUE;
}

/**
 * Ask frame to stop loading.
 *
 * @param o frame object to stop loading.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_stop(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    sd->frame->loader()->stopAllLoaders();
    return EINA_TRUE;
}

/**
 * Ask frame to reload current document.
 *
 * @param o frame object to reload.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 *
 * @see ewk_frame_reload_full()
 */
Eina_Bool ewk_frame_reload(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    sd->frame->loader()->reload();
    return EINA_TRUE;
}

/**
 * Ask frame to fully reload current document, using no previous caches.
 *
 * @param o frame object to reload.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_reload_full(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    sd->frame->loader()->reload(true);
    return EINA_TRUE;
}

/**
 * Ask frame to navigate back in history.
 *
 * @param o frame object to navigate back.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 *
 * @see ewk_frame_navigate()
 */
Eina_Bool ewk_frame_back(Evas_Object* o)
{
    return ewk_frame_navigate(o, -1);
}

/**
 * Ask frame to navigate forward in history.
 *
 * @param o frame object to navigate forward.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 *
 * @see ewk_frame_navigate()
 */
Eina_Bool ewk_frame_forward(Evas_Object* o)
{
    return ewk_frame_navigate(o, 1);
}

/**
 * Navigate back or forward in history.
 *
 * @param o frame object to navigate.
 * @param steps if positive navigates that amount forwards, if negative
 *        does backwards.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_navigate(Evas_Object* o, int steps)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    WebCore::Page* page = sd->frame->page();
    if (!page->canGoBackOrForward(steps))
        return EINA_FALSE;
    page->goBackOrForward(steps);
    return EINA_TRUE;
}

/**
 * Check if it is possible to navigate backwards one item in history.
 *
 * @param o frame object to check if backward navigation is possible.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
 *
 * @see ewk_frame_navigate_possible()
 */
Eina_Bool ewk_frame_back_possible(Evas_Object* o)
{
    return ewk_frame_navigate_possible(o, -1);
}

/**
 * Check if it is possible to navigate forwards one item in history.
 *
 * @param o frame object to check if forward navigation is possible.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
 *
 * @see ewk_frame_navigate_possible()
 */
Eina_Bool ewk_frame_forward_possible(Evas_Object* o)
{
    return ewk_frame_navigate_possible(o, 1);
}

/**
 * Check if it is possible to navigate given @a steps in history.
 *
 * @param o frame object to navigate.
 * @param steps if positive navigates that amount forwards, if negative
 *        does backwards.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_navigate_possible(Evas_Object* o, int steps)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    WebCore::Page* page = sd->frame->page();
    return page->canGoBackOrForward(steps);
}

/**
 * Get current zoom level used by this frame.
 *
 * @param o frame object to query zoom level.
 *
 * @return zoom level or -1.0 on failure.
 */
float ewk_frame_zoom_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, -1.0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, -1.0);

    if (sd->textZoom)
        return sd->frame->textZoomFactor();
    return sd->frame->pageZoomFactor();
}

/**
 * Set current zoom level used by this frame.
 *
 * @param o frame object to change zoom level.
 * @param zoom new level.
 *
 * @return @c EINA_TRUE on success or @c EINA_FALSE on failure.
 *
 * @see ewk_frame_zoom_text_only_set()
 */
Eina_Bool ewk_frame_zoom_set(Evas_Object* o, float zoom)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    if (sd->textZoom)
        sd->frame->setTextZoomFactor(zoom);
    else
        sd->frame->setPageZoomFactor(zoom);
    return EINA_TRUE;
}

/**
 * Query if zoom level just applies to text and not other elements.
 *
 * @param o frame to query setting.
 *
 * @return @c EINA_TRUE if just text are scaled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_zoom_text_only_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    return sd->textZoom;
}

/**
 * Set if zoom level just applies to text and not other elements.
 *
 * @param o frame to change setting.
 * @param setting @c EINA_TRUE if zoom should just be applied to text.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_zoom_text_only_set(Evas_Object* o, Eina_Bool setting)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    if (sd->textZoom == setting)
        return EINA_TRUE;

    float zoom_level = sd->textZoom ? sd->frame->textZoomFactor() : sd->frame->pageZoomFactor();
    sd->textZoom = setting;
    if (sd->textZoom)
        sd->frame->setPageAndTextZoomFactors(1, zoom_level);
    else
        sd->frame->setPageAndTextZoomFactors(zoom_level, 1);
    return EINA_TRUE;
}

/**
 * Free hit test created with ewk_frame_hit_test_new().
 *
 * @param hit_test instance. Must @b not be @c NULL.
 */
void ewk_frame_hit_test_free(Ewk_Hit_Test* hit_test)
{
    EINA_SAFETY_ON_NULL_RETURN(hit_test);
    eina_stringshare_del(hit_test->title);
    eina_stringshare_del(hit_test->alternate_text);
    eina_stringshare_del(hit_test->link.text);
    eina_stringshare_del(hit_test->link.url);
    eina_stringshare_del(hit_test->link.title);
    free(hit_test);
}

/**
 * Creates a new hit test for given frame and point.
 *
 * @param o frame to do hit test on.
 * @param x horizontal position to query.
 * @param y vertical position to query.
 *
 * @return a newly allocated hit test on success, @c NULL otherwise.
 *         Free memory with ewk_frame_hit_test_free()
 */
Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* o, int x, int y)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0);

    WebCore::FrameView* view = sd->frame->view();
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->contentRenderer(), 0);

    WebCore::HitTestResult result = sd->frame->eventHandler()->hitTestResultAtPoint
        (view->windowToContents(WebCore::IntPoint(x, y)),
         /*allowShadowContent*/ false, /*ignoreClipping*/ true);

    if (result.scrollbar())
        return 0;
    if (!result.innerNode())
        return 0;

    Ewk_Hit_Test* hit_test = (Ewk_Hit_Test*)calloc(1, sizeof(Ewk_Hit_Test));
    if (!hit_test) {
        CRITICAL("Could not allocate memory for hit test.");
        return 0;
    }

    hit_test->x = result.point().x();
    hit_test->y = result.point().y();
#if 0
    // FIXME
    hit_test->bounding_box.x = result.boundingBox().x();
    hit_test->bounding_box.y = result.boundingBox().y();
    hit_test->bounding_box.w = result.boundingBox().width();
    hit_test->bounding_box.h = result.boundingBox().height();
#else
    hit_test->bounding_box.x = 0;
    hit_test->bounding_box.y = 0;
    hit_test->bounding_box.w = 0;
    hit_test->bounding_box.h = 0;
#endif

    WebCore::TextDirection dir;
    hit_test->title = eina_stringshare_add(result.title(dir).utf8().data());
    hit_test->alternate_text = eina_stringshare_add(result.altDisplayString().utf8().data());
    if (result.innerNonSharedNode() && result.innerNonSharedNode()->document()
        && result.innerNonSharedNode()->document()->frame())
        hit_test->frame = kit(result.innerNonSharedNode()->document()->frame());

    hit_test->link.text = eina_stringshare_add(result.textContent().utf8().data());
    hit_test->link.url = eina_stringshare_add(result.absoluteLinkURL().string().utf8().data());
    hit_test->link.title = eina_stringshare_add(result.titleDisplayString().utf8().data());
    hit_test->link.target_frame = kit(result.targetFrame());

    hit_test->flags.editable = result.isContentEditable();
    hit_test->flags.selected = result.isSelected();

    return hit_test;
}

/**
 * Relative scroll of given frame.
 *
 * @param o frame object to scroll.
 * @param dx horizontal offset to scroll.
 * @param dy vertical offset to scroll.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
 */
Eina_Bool
ewk_frame_scroll_add(Evas_Object* o, int dx, int dy)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE);
    sd->frame->view()->scrollBy(WebCore::IntSize(dx, dy));
    return EINA_TRUE;
}

/**
 * Set absolute scroll of given frame.
 *
 * Both values are from zero to the contents size minus the viewport
 * size. See ewk_frame_scroll_size_get().
 *
 * @param o frame object to scroll.
 * @param x horizontal position to scroll.
 * @param y vertical position to scroll.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
 */
Eina_Bool
ewk_frame_scroll_set(Evas_Object* o, int x, int y)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE);
    sd->frame->view()->setScrollPosition(WebCore::IntPoint(x, y));
    return EINA_TRUE;
}

/**
 * Get the possible scroll size of given frame.
 *
 * Possible scroll size is contents size minus the viewport
 * size. It's the last allowed value for ewk_frame_scroll_set()
 *
 * @param o frame object to scroll.
 * @param w where to return horizontal size that is possible to
 *        scroll. May be @c NULL.
 * @param h where to return vertical size that is possible to scroll.
 *        May be @c NULL.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise and
 *         values are zeroed.
 */
Eina_Bool
ewk_frame_scroll_size_get(const Evas_Object* o, int* w, int* h)
{
    if (w)
        *w = 0;
    if (h)
        *h = 0;
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE);
    WebCore::IntPoint point = sd->frame->view()->maximumScrollPosition();
    if (w)
        *w = point.x();
    if (h)
        *h = point.y();
    return EINA_TRUE;
}

/**
 * Get the current scroll position of given frame.
 *
 * @param o frame object to scroll.
 * @param x where to return horizontal position. May be @c NULL.
 * @param y where to return vertical position. May be @c NULL.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise and
 *         values are zeroed.
 */
Eina_Bool
ewk_frame_scroll_pos_get(const Evas_Object* o, int* x, int* y)
{
    if (x)
        *x = 0;
    if (y)
        *y = 0;
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE);
    WebCore::IntPoint pos = sd->frame->view()->scrollPosition();
    if (x)
        *x = pos.x();
    if (y)
        *y = pos.y();
    return EINA_TRUE;
}

/**
 * Get the current frame visible content geometry.
 *
 * @param o frame object to query visible content geometry.
 * @param include_scrollbars whenever to include scrollbars size.
 * @param x horizontal position. May be @c NULL.
 * @param y vertical position. May be @c NULL.
 * @param w width. May be @c NULL.
 * @param h height. May be @c NULL.
 *
 * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise and
 *         values are zeroed.
 */
Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object* o, Eina_Bool include_scrollbars, int* x, int* y, int* w, int* h)
{
    if (x)
        *x = 0;
    if (y)
        *y = 0;
    if (w)
        *w = 0;
    if (h)
        *h = 0;
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE);
    WebCore::IntRect rect = sd->frame->view()->visibleContentRect(include_scrollbars);
    if (x)
        *x = rect.x();
    if (y)
        *y = rect.y();
    if (w)
        *w = rect.width();
    if (h)
        *h = rect.height();
    return EINA_TRUE;
}

/**
 * Get the current paintsEntireContents flag.
 *
 * This flag tells if dirty areas should be repainted even if they are
 * out of the screen.
 *
 * @param o frame object to query paintsEntireContents flag.
 *
 * @return @c EINA_TRUE if repainting any dirty area, @c EINA_FALSE
 *         otherwise.
 */
Eina_Bool ewk_frame_paint_full_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE);
    return sd->frame->view()->paintsEntireContents();
}

/**
 * Set the current paintsEntireContents flag.
 *
 * This flag tells if dirty areas should be repainted even if they are
 * out of the screen.
 *
 * @param o frame object to set paintsEntireContents flag.
 * @param flag @c EINA_TRUE if want to always repaint any dirty area,
 *             @c EINA_FALSE otherwise.
 */
void ewk_frame_paint_full_set(Evas_Object* o, Eina_Bool flag)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    EINA_SAFETY_ON_NULL_RETURN(sd->frame);
    EINA_SAFETY_ON_NULL_RETURN(sd->frame->view());
    sd->frame->view()->setPaintsEntireContents(flag);
}

/**
 * Feed the focus in signal to this frame.
 *
 * @param o frame object to focus.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_focus_in(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    WebCore::FocusController* c = sd->frame->page()->focusController();
    c->setFocusedFrame(sd->frame);
    return EINA_TRUE;
}

/**
 * Feed the focus out signal to this frame.
 *
 * @param o frame object to remove focus.
 */
Eina_Bool ewk_frame_feed_focus_out(Evas_Object* o)
{
    // TODO: what to do on focus out?
    ERR("what to do?");
    return EINA_FALSE;
}

/**
 * Feed the mouse wheel event to the frame.
 *
 * @param o frame object to feed event.
 * @param ev mouse wheel event.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object* o, const Evas_Event_Mouse_Wheel* ev)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE);

    WebCore::FrameView* view = sd->frame->view();
    DBG("o=%p, view=%p, direction=%d, z=%d, pos=%d,%d",
        o, view, ev->direction, ev->z, ev->canvas.x, ev->canvas.y);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);

    WebCore::PlatformWheelEvent event(ev);
    return sd->frame->eventHandler()->handleWheelEvent(event);
}

/**
 * Feed the mouse down event to the frame.
 *
 * @param o frame object to feed event.
 * @param ev mouse down event.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_mouse_down(Evas_Object* o, const Evas_Event_Mouse_Down* ev)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE);

    WebCore::FrameView* view = sd->frame->view();
    DBG("o=%p, view=%p, button=%d, pos=%d,%d",
        o, view, ev->button, ev->canvas.x, ev->canvas.y);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);

    Evas_Coord x, y;
    evas_object_geometry_get(sd->view, &x, &y, 0, 0);

    WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y));
    return sd->frame->eventHandler()->handleMousePressEvent(event);
}

/**
 * Feed the mouse up event to the frame.
 *
 * @param o frame object to feed event.
 * @param ev mouse up event.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_mouse_up(Evas_Object* o, const Evas_Event_Mouse_Up* ev)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE);

    WebCore::FrameView* view = sd->frame->view();
    DBG("o=%p, view=%p, button=%d, pos=%d,%d",
        o, view, ev->button, ev->canvas.x, ev->canvas.y);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);

    Evas_Coord x, y;
    evas_object_geometry_get(sd->view, &x, &y, 0, 0);

    WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y));
    return sd->frame->eventHandler()->handleMouseReleaseEvent(event);
}

/**
 * Feed the mouse move event to the frame.
 *
 * @param o frame object to feed event.
 * @param ev mouse move event.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_mouse_move(Evas_Object* o, const Evas_Event_Mouse_Move* ev)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE);

    WebCore::FrameView* view = sd->frame->view();
    DBG("o=%p, view=%p, pos: old=%d,%d, new=%d,%d, buttons=%d",
        o, view, ev->cur.canvas.x, ev->cur.canvas.y,
        ev->prev.canvas.x, ev->prev.canvas.y, ev->buttons);
    EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);

    Evas_Coord x, y;
    evas_object_geometry_get(sd->view, &x, &y, 0, 0);

    WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y));
    return sd->frame->eventHandler()->mouseMoved(event);
}

Eina_Bool ewk_frame_feed_touch_event(Evas_Object* o, Ewk_Touch_Event_Type action, Eina_List* points, int metaState)
{
    Eina_Bool ret = EINA_FALSE;

#if ENABLE(TOUCH_EVENTS)
    EINA_SAFETY_ON_NULL_RETURN_VAL(points, EINA_FALSE);
    EWK_FRAME_SD_GET(o, sd);

    if (!sd || !sd->frame || !ewk_view_need_touch_events_get(sd->view)) {
        void* point;
        EINA_LIST_FREE(points, point);
        return EINA_FALSE;
    }

    Evas_Coord x, y;
    evas_object_geometry_get(sd->view, &x, &y, 0, 0);

    WebCore::TouchEventType type = WebCore::TouchStart;
    switch (action) {
    case EWK_TOUCH_START:
        type = WebCore::TouchStart;
        break;
    case EWK_TOUCH_END:
        type = WebCore::TouchEnd;
        break;
    case EWK_TOUCH_MOVE:
        type = WebCore::TouchMove;
        break;
    case EWK_TOUCH_CANCEL:
        type = WebCore::TouchCancel;
        break;
    default:
        return EINA_FALSE;
    }

    WebCore::PlatformTouchEvent te(points, WebCore::IntPoint(x, y), type, metaState);
    ret = sd->frame->eventHandler()->handleTouchEvent(te);
#endif
    return ret;
}

static inline Eina_Bool _ewk_frame_handle_key_scrolling(WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent &event)
{
    WebCore::ScrollDirection direction;
    WebCore::ScrollGranularity granularity;

    int keyCode = event.windowsVirtualKeyCode();

    switch (keyCode) {
    case VK_SPACE:
        granularity = WebCore::ScrollByPage;
        if (event.shiftKey())
            direction = WebCore::ScrollUp;
        else
            direction = WebCore::ScrollDown;
        break;
    case VK_NEXT:
        granularity = WebCore::ScrollByPage;
        direction = WebCore::ScrollDown;
        break;
    case VK_PRIOR:
        granularity = WebCore::ScrollByPage;
        direction = WebCore::ScrollUp;
        break;
    case VK_HOME:
        granularity = WebCore::ScrollByDocument;
        direction = WebCore::ScrollUp;
        break;
    case VK_END:
        granularity = WebCore::ScrollByDocument;
        direction = WebCore::ScrollDown;
        break;
    case VK_LEFT:
        granularity = WebCore::ScrollByLine;
        direction = WebCore::ScrollLeft;
        break;
    case VK_RIGHT:
        granularity = WebCore::ScrollByLine;
        direction = WebCore::ScrollRight;
        break;
    case VK_UP:
        direction = WebCore::ScrollUp;
        if (event.ctrlKey())
            granularity = WebCore::ScrollByDocument;
        else
            granularity = WebCore::ScrollByLine;
        break;
    case VK_DOWN:
        direction = WebCore::ScrollDown;
         if (event.ctrlKey())
            granularity = WebCore::ScrollByDocument;
        else
            granularity = WebCore::ScrollByLine;
        break;
    default:
        return EINA_FALSE;
    }

    if (frame->eventHandler()->scrollOverflow(direction, granularity))
        return EINA_FALSE;

    frame->view()->scroll(direction, granularity);
    return EINA_TRUE;
}

/**
 * Feed the keyboard key down event to the frame.
 *
 * @param o frame object to feed event.
 * @param ev keyboard key down event.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_key_down(Evas_Object* o, const Evas_Event_Key_Down* ev)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE);

    DBG("o=%p keyname=%s (key=%s, string=%s)",
        o, ev->keyname, ev->key ? ev->key : "", ev->string ? ev->string : "");

    WebCore::PlatformKeyboardEvent event(ev);
    if (sd->frame->eventHandler()->keyEvent(event))
        return EINA_TRUE;

    return _ewk_frame_handle_key_scrolling(sd->frame, event);
}

/**
 * Feed the keyboard key up event to the frame.
 *
 * @param o frame object to feed event.
 * @param ev keyboard key up event.
 *
 * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_frame_feed_key_up(Evas_Object* o, const Evas_Event_Key_Up* ev)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE);

    DBG("o=%p keyname=%s (key=%s, string=%s)",
        o, ev->keyname, ev->key ? ev->key : "", ev->string ? ev->string : "");

    WebCore::PlatformKeyboardEvent event(ev);
    return sd->frame->eventHandler()->keyEvent(event);
}

/* internal methods ****************************************************/

/**
 * @internal
 *
 * Initialize frame based on actual WebKit frame.
 *
 * This is internal and should never be called by external users.
 */
Eina_Bool ewk_frame_init(Evas_Object* o, Evas_Object* view, WebCore::Frame* frame)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    if (!sd->frame) {
        WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(frame);
        flc->setWebFrame(o);
        sd->frame = frame;
        sd->view = view;
        frame->init();
        return EINA_TRUE;
    }

    ERR("frame %p already set for %p, ignored new %p",
        sd->frame, o, frame);
    return EINA_FALSE;
}

Evas_Object* ewk_frame_child_add(Evas_Object* o, WTF::PassRefPtr<WebCore::Frame> child, const WTF::String& name, const WebCore::KURL& url, const WTF::String& referrer)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    char buf[256];
    Evas_Object* frame;
    WebCore::Frame* cf;

    frame = ewk_frame_add(sd->base.evas);
    if (!frame) {
        ERR("Could not create ewk_frame object.");
        return 0;
    }

    cf = child.get();
    if (cf->tree())
        cf->tree()->setName(name);
    else
        ERR("no tree for child object");
    sd->frame->tree()->appendChild(child);

    if (!ewk_frame_init(frame, sd->view, cf)) {
        evas_object_del(frame);
        return 0;
    }
    snprintf(buf, sizeof(buf), "EWK_Frame:child/%s", name.utf8().data());
    evas_object_name_set(frame, buf);
    evas_object_smart_member_add(frame, o);
    evas_object_show(frame);

    if (!cf->page())
        goto died;

    sd->frame->loader()->loadURLIntoChildFrame(url, referrer, cf);
    if (!cf->tree()->parent())
        goto died;

    // TODO: announce frame was created?
    return frame;

died:
    CRITICAL("does this work: BEGIN");
    ewk_frame_core_gone(frame); // CONFIRM
    evas_object_del(frame); // CONFIRM
    CRITICAL("does this work: END");
    return 0;
}

/**
 * @internal
 * Frame was destroyed by loader, remove internal reference.
 */
void ewk_frame_core_gone(Evas_Object* o)
{
    DBG("o=%p", o);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    sd->frame = 0;
}

/**
 * @internal
 * Retrieve WebCore::Frame associated with this object.
 *
 * Avoid using this call from outside, add specific ewk_frame_*
 * actions instead.
 */
WebCore::Frame* ewk_frame_core_get(const Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0);
    return sd->frame;
}


/**
 * @internal
 * Reports a resource will be requested. User may override behavior of webkit by
 * changing values in @param request.
 *
 * @param o Frame.
 * @param request Request details that user may override. Whenever values on
 * this struct changes, it must be properly malloc'd as it will be freed
 * afterwards.
 *
 * Emits signal: "resource,request,willsend"
 */
void ewk_frame_request_will_send(Evas_Object *o, Ewk_Frame_Resource_Request *request)
{
    evas_object_smart_callback_call(o, "resource,request,willsend", request);
}

/**
 * @internal
 * Reports that there's a new resource.
 *
 * @param o Frame.
 * @param request New request details. No changes are allowed to fields.
 *
 * Emits signal: "resource,request,new"
 */
void ewk_frame_request_assign_identifier(Evas_Object *o, const Ewk_Frame_Resource_Request *request)
{
    evas_object_smart_callback_call(o, "resource,request,new", (void *)request);
}

/**
 * @internal
 * Reports that first navigation occurred
 *
 * @param o Frame.
 *
 * Emits signal: "navigation,first"
 */
void ewk_frame_did_perform_first_navigation(Evas_Object *o)
{
    evas_object_smart_callback_call(o, "navigation,first", 0);
}

/**
 * @internal
 * Reports frame will be saved to current state
 *
 * @param o Frame.
 * @param item History item to save details to.
 *
 * Emits signal: "state,save"
 */
void ewk_frame_view_state_save(Evas_Object *o, WebCore::HistoryItem* item)
{
    evas_object_smart_callback_call(o, "state,save", 0);
}

/**
 * @internal
 * Reports the frame started loading something.
 *
 * Emits signal: "load,started" with no parameters.
 */
void ewk_frame_load_started(Evas_Object* o)
{
    Evas_Object* main_frame;
    DBG("o=%p", o);
    evas_object_smart_callback_call(o, "load,started", 0);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    ewk_view_load_started(sd->view);

    main_frame = ewk_view_frame_main_get(sd->view);
    if (main_frame == o)
        ewk_view_frame_main_load_started(sd->view);
}

/**
 * @internal
 * Reports the frame started provisional load.
 *
 * @param o Frame.
 *
 * Emits signal: "load,provisional" with no parameters.
 */
void ewk_frame_load_provisional(Evas_Object* o)
{
    evas_object_smart_callback_call(o, "load,provisional", 0);
}

/**
 * @internal
 * Reports the frame finished first layout.
 *
 * @param o Frame.
 *
 * Emits signal: "load,firstlayout,finished" with no parameters.
 */
void ewk_frame_load_firstlayout_finished(Evas_Object *o)
{
    evas_object_smart_callback_call(o, "load,firstlayout,finished", 0);
}

/**
 * @internal
 * Reports the frame finished first non empty layout.
 *
 * @param o Frame.
 *
 * Emits signal: "load,nonemptylayout,finished" with no parameters.
 */
void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object *o)
{
    evas_object_smart_callback_call(o, "load,nonemptylayout,finished", 0);
}

/**
 * @internal
 * Reports the loading of a document has finished on frame.
 *
 * @param o Frame.
 *
 * Emits signal: "load,document,finished" with no parameters.
 */
void ewk_frame_load_document_finished(Evas_Object *o)
{
    evas_object_smart_callback_call(o, "load,document,finished", 0);
}

/**
 * @internal
 * Reports load finished, optionally with error information.
 *
 * Emits signal: "load,finished" with pointer to Ewk_Frame_Load_Error
 * if any error, or @c NULL if successful load.
 *
 * @note there should notbe any error stuff here, but trying to be
 *       compatible with previous WebKit.
 */
void ewk_frame_load_finished(Evas_Object* o, const char* error_domain, int error_code, Eina_Bool is_cancellation, const char* error_description, const char* failing_url)
{
    Ewk_Frame_Load_Error buf, *error;
    if (!error_domain) {
        DBG("o=%p, success.", o);
        error = 0;
    } else {
        DBG("o=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
            o, error_domain, error_code, is_cancellation,
            error_description, failing_url);

        buf.domain = error_domain;
        buf.code = error_code;
        buf.is_cancellation = is_cancellation;
        buf.description = error_description;
        buf.failing_url = failing_url;
        buf.frame = o;
        error = &buf;
    }
    evas_object_smart_callback_call(o, "load,finished", error);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    ewk_view_load_finished(sd->view, error);
}

/**
 * @internal
 * Reports load failed with error information.
 *
 * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
 */
void ewk_frame_load_error(Evas_Object* o, const char* error_domain, int error_code, Eina_Bool is_cancellation, const char* error_description, const char* failing_url)
{
    Ewk_Frame_Load_Error error;

    DBG("o=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
        o, error_domain, error_code, is_cancellation,
        error_description, failing_url);

    EINA_SAFETY_ON_NULL_RETURN(error_domain);

    error.code = error_code;
    error.is_cancellation = is_cancellation;
    error.domain = error_domain;
    error.description = error_description;
    error.failing_url = failing_url;
    error.frame = o;
    evas_object_smart_callback_call(o, "load,error", &error);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    ewk_view_load_error(sd->view, &error);
}

/**
 * @internal
 * Reports load progress changed.
 *
 * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
 */
void ewk_frame_load_progress_changed(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    EINA_SAFETY_ON_NULL_RETURN(sd->frame);

    // TODO: this is per page, there should be a way to have per-frame.
    double progress = sd->frame->page()->progress()->estimatedProgress();

    DBG("o=%p (p=%0.3f)", o, progress);

    evas_object_smart_callback_call(o, "load,progress", &progress);
    ewk_view_load_progress_changed(sd->view);
}


/**
 * @internal
 *
 * Reports contents size changed.
 */
void ewk_frame_contents_size_changed(Evas_Object* o, Evas_Coord w, Evas_Coord h)
{
    DBG("o=%p: %dx%d", o, w, h);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    if (sd->contents_size.w == w && sd->contents_size.h == h)
        return;
    sd->contents_size.w = w;
    sd->contents_size.h = h;
    // TODO: update something else internally?

    Evas_Coord size[2] = {w, h};
    evas_object_smart_callback_call(o, "contents,size,changed", size);
}

/**
 * @internal
 *
 * Reports title changed.
 */
void ewk_frame_title_set(Evas_Object* o, const char* title)
{
    DBG("o=%p, title=%s", o, title ? title : "(null)");
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    if (!eina_stringshare_replace(&sd->title, title))
        return;
    evas_object_smart_callback_call(o, "title,changed", (void*)sd->title);
}

void ewk_frame_view_create_for_view(Evas_Object* o, Evas_Object* view)
{
    DBG("o=%p, view=%p", o, view);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    EINA_SAFETY_ON_NULL_RETURN(sd->frame);
    Evas_Coord w, h;

    if (sd->frame->view())
        return;

    evas_object_geometry_get(view, 0, 0, &w, &h);

    WebCore::IntSize size(w, h);
    int r, g, b, a;
    WebCore::Color bg;

    ewk_view_bg_color_get(view, &r, &g, &b, &a);
    if (!a)
        bg = WebCore::Color(0, 0, 0, 0);
    else if (a == 255)
        bg = WebCore::Color(r, g, b, a);
    else
        bg = WebCore::Color(r * 255 / a, g * 255 / a, b * 255 / a, a);

    sd->frame->createView(size, bg, !a, WebCore::IntSize(), false);
    if (!sd->frame->view())
        return;

    const char* theme = ewk_view_theme_get(view);
    sd->frame->view()->setEdjeTheme(theme);
    sd->frame->view()->setEvasObject(o);
}

/**
 * @internal
 * Reports uri changed and swap internal string reference.
 *
 * Emits signal: "uri,changed" with new uri as parameter.
 */
Eina_Bool ewk_frame_uri_changed(Evas_Object* o)
{
    EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE);
    WTF::CString uri(sd->frame->document()->url().string().utf8());

    INF("uri=%s", uri.data());
    if (!uri.data()) {
        ERR("no uri");
        return EINA_FALSE;
    }

    eina_stringshare_replace(&sd->uri, uri.data());
    evas_object_smart_callback_call(o, "uri,changed", (void*)sd->uri);
    return EINA_TRUE;
}

void ewk_frame_force_layout(Evas_Object* o)
{
    DBG("o=%p", o);
    EWK_FRAME_SD_GET_OR_RETURN(o, sd);
    EINA_SAFETY_ON_NULL_RETURN(sd->frame);
    WebCore::FrameView* view = sd->frame->view();
    if (view)
        view->forceLayout(true);
}

WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object* o, const WebCore::IntSize& pluginSize, WebCore::HTMLPlugInElement* element, const WebCore::KURL& url, const WTF::Vector<WTF::String>& paramNames, const WTF::Vector<WTF::String>& paramValues, const WTF::String& mimeType, bool loadManually)
{
    return 0;
}
