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

#include "config.h"
#include "ewk_history.h"

#include "BackForwardListImpl.h"
#include "EWebKit.h"
#include "HistoryItem.h"
#include "IconDatabaseBase.h"
#include "Image.h"
#include "IntSize.h"
#include "ewk_private.h"
#include <wtf/text/CString.h>

#include <Eina.h>
#include <eina_safety_checks.h>

struct _Ewk_History {
    WebCore::BackForwardListImpl *core;
};

#define EWK_HISTORY_CORE_GET_OR_RETURN(history, core_, ...)      \
    if (!(history)) {                                            \
        CRITICAL("history is NULL.");                            \
        return __VA_ARGS__;                                      \
    }                                                            \
    if (!(history)->core) {                                      \
        CRITICAL("history->core is NULL.");                      \
        return __VA_ARGS__;                                      \
    }                                                            \
    if (!(history)->core->enabled()) {                           \
        ERR("history->core is disabled!.");                      \
        return __VA_ARGS__;                                      \
    }                                                            \
    WebCore::BackForwardListImpl *core_ = (history)->core


struct _Ewk_History_Item {
    WebCore::HistoryItem *core;

    const char *title;
    const char *alternate_title;
    const char *uri;
    const char *original_uri;
};

#define EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core_, ...) \
    if (!(item)) {                                            \
        CRITICAL("item is NULL.");                            \
        return __VA_ARGS__;                                   \
    }                                                         \
    if (!(item)->core) {                                      \
        CRITICAL("item->core is NULL.");                      \
        return __VA_ARGS__;                                   \
    }                                                         \
    WebCore::HistoryItem *core_ = (item)->core


static inline Ewk_History_Item *_ewk_history_item_new(WebCore::HistoryItem *core)
{
    Ewk_History_Item* item;

    if (!core) {
        ERR("WebCore::HistoryItem is NULL.");
        return 0;
    }

    item = (Ewk_History_Item *)calloc(1, sizeof(Ewk_History_Item));
    if (!item) {
        CRITICAL("Could not allocate item memory.");
        return 0;
    }

    core->ref();
    item->core = core;

    return item;
}

static inline Eina_List *_ewk_history_item_list_get(const WebCore::HistoryItemVector &core_items)
{
    Eina_List* ret = 0;
    unsigned int i, size;

    size = core_items.size();
    for (i = 0; i < size; i++) {
        Ewk_History_Item* item = _ewk_history_item_new(core_items[i].get());
        if (item)
            ret = eina_list_append(ret, item);
    }

    return ret;
}

/**
 * Go forward in history one item, if possible.
 *
 * @param history which history instance to modify.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
 */
Eina_Bool ewk_history_forward(Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE);
    if (core->forwardListCount() < 1)
        return EINA_FALSE;
    core->goForward();
    return EINA_TRUE;
}

/**
 * Go back in history one item, if possible.
 *
 * @param history which history instance to modify.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
 */
Eina_Bool ewk_history_back(Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE);
    if (core->backListCount() < 1)
        return EINA_FALSE;
    core->goBack();
    return EINA_TRUE;
}

/**
 * Adds the given item to history.
 *
 * Memory handling: This will not modify or even take references to
 * given item (Ewk_History_Item), so you should still handle it with
 * ewk_history_item_free().
 *
 * @param history which history instance to modify.
 * @param item reference to add to history. Unmodified. Must @b not be @c NULL.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
 */
Eina_Bool ewk_history_history_item_add(Ewk_History* history, const Ewk_History_Item* item)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE);
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE);
    history_core->addItem(item_core);
    return EINA_TRUE;
}

/**
 * Sets the given item as current in history (go to item).
 *
 * Memory handling: This will not modify or even take references to
 * given item (Ewk_History_Item), so you should still handle it with
 * ewk_history_item_free().
 *
 * @param history which history instance to modify.
 * @param item reference to go to history. Unmodified. Must @b not be @c NULL.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE on failure.
 */
Eina_Bool ewk_history_history_item_set(Ewk_History* history, const Ewk_History_Item* item)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE);
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE);
    history_core->goToItem(item_core);
    return EINA_TRUE;
}

/**
 * Get the first item from back list, if any.
 *
 * @param history which history instance to query.
 *
 * @return the @b newly allocated item instance. This memory must be
 *         released with ewk_history_item_free() after use.
 */
Ewk_History_Item* ewk_history_history_item_back_get(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return _ewk_history_item_new(core->backItem());
}

/**
 * Get the current item in history, if any.
 *
 * @param history which history instance to query.
 *
 * @return the @b newly allocated item instance. This memory must be
 *         released with ewk_history_item_free() after use.
 */
Ewk_History_Item* ewk_history_history_item_current_get(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return _ewk_history_item_new(core->currentItem());
}

/**
 * Get the first item from forward list, if any.
 *
 * @param history which history instance to query.
 *
 * @return the @b newly allocated item instance. This memory must be
 *         released with ewk_history_item_free() after use.
 */
Ewk_History_Item* ewk_history_history_item_forward_get(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return _ewk_history_item_new(core->forwardItem());
}

/**
 * Get item at given position, if any at that index.
 *
 * @param history which history instance to query.
 * @param index position of item to get.
 *
 * @return the @b newly allocated item instance. This memory must be
 *         released with ewk_history_item_free() after use.
 */
Ewk_History_Item* ewk_history_history_item_nth_get(const Ewk_History* history, int index)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return _ewk_history_item_new(core->itemAtIndex(index));
}

/**
 * Queries if given item is in history.
 *
 * Memory handling: This will not modify or even take references to
 * given item (Ewk_History_Item), so you should still handle it with
 * ewk_history_item_free().
 *
 * @param history which history instance to modify.
 * @param item reference to check in history. Must @b not be @c NULL.
 *
 * @return @c EINA_TRUE if in history, @c EINA_FALSE if not or failure.
 */
Eina_Bool ewk_history_history_item_contains(const Ewk_History* history, const Ewk_History_Item* item)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE);
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE);
    return history_core->containsItem(item_core);
}

/**
 * Get the whole forward list.
 *
 * @param history which history instance to query.
 *
 * @return a newly allocated list of @b newly allocated item
 *         instance. This memory of each item must be released with
 *         ewk_history_item_free() after use. use
 *         ewk_history_item_list_free() for convenience.
 *
 * @see ewk_history_item_list_free()
 * @see ewk_history_forward_list_get_with_limit()
 */
Eina_List* ewk_history_forward_list_get(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    WebCore::HistoryItemVector items;
    int limit = core->forwardListCount();
    core->forwardListWithLimit(limit, items);
    return _ewk_history_item_list_get(items);
}

/**
 * Get the forward list within the given limit.
 *
 * @param history which history instance to query.
 * @param limit the maximum number of items to return.
 *
 * @return a newly allocated list of @b newly allocated item
 *         instance. This memory of each item must be released with
 *         ewk_history_item_free() after use. use
 *         ewk_history_item_list_free() for convenience.
 *
 * @see ewk_history_item_list_free()
 * @see ewk_history_forward_list_length()
 * @see ewk_history_forward_list_get()
 */
Eina_List* ewk_history_forward_list_get_with_limit(const Ewk_History* history, int limit)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    WebCore::HistoryItemVector items;
    core->forwardListWithLimit(limit, items);
    return _ewk_history_item_list_get(items);
}

/**
 * Get the whole size of forward list.
 *
 * @param history which history instance to query.
 *
 * @return number of elements in whole list.
 *
 * @see ewk_history_forward_list_get_with_limit()
 */
int ewk_history_forward_list_length(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return core->forwardListCount();
}

/**
 * Get the whole back list.
 *
 * @param history which history instance to query.
 *
 * @return a newly allocated list of @b newly allocated item
 *         instance. This memory of each item must be released with
 *         ewk_history_item_free() after use. use
 *         ewk_history_item_list_free() for convenience.
 *
 * @see ewk_history_item_list_free()
 * @see ewk_history_back_list_get_with_limit()
 */
Eina_List* ewk_history_back_list_get(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    WebCore::HistoryItemVector items;
    int limit = core->backListCount();
    core->backListWithLimit(limit, items);
    return _ewk_history_item_list_get(items);
}

/**
 * Get the back list within the given limit.
 *
 * @param history which history instance to query.
 * @param limit the maximum number of items to return.
 *
 * @return a newly allocated list of @b newly allocated item
 *         instance. This memory of each item must be released with
 *         ewk_history_item_free() after use. use
 *         ewk_history_item_list_free() for convenience.
 *
 * @see ewk_history_item_list_free()
 * @see ewk_history_back_list_length()
 * @see ewk_history_back_list_get()
 */
Eina_List* ewk_history_back_list_get_with_limit(const Ewk_History* history, int limit)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    WebCore::HistoryItemVector items;
    core->backListWithLimit(limit, items);
    return _ewk_history_item_list_get(items);
}

/**
 * Get the whole size of back list.
 *
 * @param history which history instance to query.
 *
 * @return number of elements in whole list.
 *
 * @see ewk_history_back_list_get_with_limit()
 */
int ewk_history_back_list_length(const Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return core->backListCount();
}

/**
 * Get maximum capacity of given history.
 *
 * @param history which history instance to query.
 *
 * @return maximum number of entries this history will hold.
 */
int ewk_history_limit_get(Ewk_History* history)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
    return core->capacity();
}

/**
 * Set maximum capacity of given history.
 *
 * @param history which history instance to modify.
 * @param limit maximum size to allow.
 *
 * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_history_limit_set(const Ewk_History* history, int limit)
{
    EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE);
    core->setCapacity(limit);
    return EINA_TRUE;
}

/**
 * Create a new history item with given URI and title.
 *
 * @param uri where this resource is located.
 * @param title resource title.
 *
 * @return newly allocated history item or @c NULL on errors. You must
 *         free this item with ewk_history_item_free().
 */
Ewk_History_Item* ewk_history_item_new(const char* uri, const char* title)
{
    WTF::String u = WTF::String::fromUTF8(uri);
    WTF::String t = WTF::String::fromUTF8(title);
    WTF::RefPtr<WebCore::HistoryItem> core = WebCore::HistoryItem::create(u, t, 0);
    Ewk_History_Item* item = _ewk_history_item_new(core.release().releaseRef());
    return item;
}

static inline void _ewk_history_item_free(Ewk_History_Item* item, WebCore::HistoryItem* core)
{
    core->deref();
    free(item);
}

/**
 * Free given history item instance.
 *
 * @param item what to free.
 */
void ewk_history_item_free(Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core);
    _ewk_history_item_free(item, core);
}

/**
 * Free given list and associated history items instances.
 *
 * @param history_items list of items to free (both list nodes and
 *        item instances).
 */
void ewk_history_item_list_free(Eina_List* history_items)
{
    void* d;
    EINA_LIST_FREE(history_items, d) {
        Ewk_History_Item* item = (Ewk_History_Item*)d;
        _ewk_history_item_free(item, item->core);
    }
}

/**
 * Query title for given history item.
 *
 * @param item history item to query.
 *
 * @return the title pointer, that may be @c NULL. This pointer is
 *         guaranteed to be eina_stringshare, so whenever possible
 *         save yourself some cpu cycles and use
 *         eina_stringshare_ref() instead of eina_stringshare_add() or
 *         strdup().
 */
const char* ewk_history_item_title_get(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    // hide the following optimzation from outside
    Ewk_History_Item* i = (Ewk_History_Item*)item;
    eina_stringshare_replace(&i->title, core->title().utf8().data());
    return i->title;
}

/**
 * Query alternate title for given history item.
 *
 * @param item history item to query.
 *
 * @return the alternate title pointer, that may be @c NULL. This
 *         pointer is guaranteed to be eina_stringshare, so whenever
 *         possible save yourself some cpu cycles and use
 *         eina_stringshare_ref() instead of eina_stringshare_add() or
 *         strdup().
 */
const char* ewk_history_item_title_alternate_get(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    // hide the following optimzation from outside
    Ewk_History_Item* i = (Ewk_History_Item*)item;
    eina_stringshare_replace(&i->alternate_title,
                             core->alternateTitle().utf8().data());
    return i->alternate_title;
}

/**
 * Set alternate title for given history item.
 *
 * @param item history item to query.
 * @param title new alternate title to use for given item. No
 *        references are kept after this function returns.
 */
void ewk_history_item_title_alternate_set(Ewk_History_Item* item, const char* title)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core);
    if (!eina_stringshare_replace(&item->alternate_title, title))
        return;
    core->setAlternateTitle(WTF::String::fromUTF8(title));
}

/**
 * Query URI for given history item.
 *
 * @param item history item to query.
 *
 * @return the URI pointer, that may be @c NULL. This pointer is
 *         guaranteed to be eina_stringshare, so whenever possible
 *         save yourself some cpu cycles and use
 *         eina_stringshare_ref() instead of eina_stringshare_add() or
 *         strdup().
 */
const char* ewk_history_item_uri_get(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    // hide the following optimzation from outside
    Ewk_History_Item* i = (Ewk_History_Item*)item;
    eina_stringshare_replace(&i->uri, core->urlString().utf8().data());
    return i->uri;
}

/**
 * Query original URI for given history item.
 *
 * @param item history item to query.
 *
 * @return the original URI pointer, that may be @c NULL. This pointer
 *         is guaranteed to be eina_stringshare, so whenever possible
 *         save yourself some cpu cycles and use
 *         eina_stringshare_ref() instead of eina_stringshare_add() or
 *         strdup().
 */
const char* ewk_history_item_uri_original_get(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    // hide the following optimzation from outside
    Ewk_History_Item* i = (Ewk_History_Item*)item;
    eina_stringshare_replace(&i->original_uri,
                             core->originalURLString().utf8().data());
    return i->original_uri;
}

/**
 * Query last visited time for given history item.
 *
 * @param item history item to query.
 *
 * @return the time in seconds this item was visited.
 */
double ewk_history_item_time_last_visited_get(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0.0);
    return core->lastVisitedTime();
}

/**
 * Get the icon (aka favicon) associated with this history item.
 *
 * @note in order to have this working, one must open icon database
 *       with ewk_settings_icon_database_path_set().
 *
 * @param item history item to query.
 *
 * @return the surface reference or @c NULL on errors. Note that the
 *         reference may be to a standard fallback icon.
 */
cairo_surface_t* ewk_history_item_icon_surface_get(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    
    WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(core->url(), WebCore::IntSize(16, 16));
    if (!icon) {
        ERR("icon is NULL.");
        return 0;
    }
    return icon->nativeImageForCurrentFrame();
}

/**
 * Add an Evas_Object of type 'image' to given canvas with history item icon.
 *
 * This is an utility function that creates an Evas_Object of type
 * image set to have fill always match object size
 * (evas_object_image_filled_add()), saving some code to use it from Evas.
 *
 * @note in order to have this working, one must open icon database
 *       with ewk_settings_icon_database_path_set().
 *
 * @param item history item to query.
 * @param canvas evas instance where to add resulting object.
 *
 * @return newly allocated Evas_Object instance or @c NULL on
 *         errors. Delete the object with evas_object_del().
 */
Evas_Object* ewk_history_item_icon_object_add(const Ewk_History_Item* item, Evas* canvas)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
    WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(core->url(), WebCore::IntSize(16, 16));
    cairo_surface_t* surface;

    if (!icon) {
        ERR("icon is NULL.");
        return 0;
    }

    surface = icon->nativeImageForCurrentFrame();
    return ewk_util_image_from_cairo_surface_add(canvas, surface);
}

/**
 * Query if given item is still in page cache.
 *
 * @param item history item to query.
 *
 * @return @c EINA_TRUE if in cache, @c EINA_FALSE otherwise.
 */
Eina_Bool ewk_history_item_page_cache_exists(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, EINA_FALSE);
    return core->isInPageCache();
}

/**
 * Query number of times item was visited.
 *
 * @param item history item to query.
 *
 * @return number of visits.
 */
int ewk_history_item_visit_count(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
    return core->visitCount();
}

/**
 * Query if last visit to item was failure or not.
 *
 * @param item history item to query.
 *
 * @return @c EINA_TRUE if last visit was failure, @c EINA_FALSE if it
 *         was fine.
 */
Eina_Bool ewk_history_item_visit_last_failed(const Ewk_History_Item* item)
{
    EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, EINA_TRUE);
    return core->lastVisitWasFailure();
}


/* internal methods ****************************************************/
/**
 * @internal
 *
 * Creates history for given view. Called internally by ewk_view and
 * should never be called from outside.
 *
 * @param core WebCore::BackForwardListImpl instance to use internally.
 *
 * @return newly allocated history instance or @c NULL on errors.
 */
Ewk_History* ewk_history_new(WebCore::BackForwardListImpl* core)
{
    Ewk_History* history;
    EINA_SAFETY_ON_NULL_RETURN_VAL(core, 0);
    DBG("core=%p", core);

    history = (Ewk_History*)malloc(sizeof(Ewk_History));
    if (!history) {
        CRITICAL("Could not allocate history memory.");
        return 0;
    }

    core->ref();
    history->core = core;

    return history;
}

/**
 * @internal
 *
 * Destroys previously allocated history instance. This is called
 * automatically by ewk_view and should never be called from outside.
 *
 * @param history instance to free
 */
void ewk_history_free(Ewk_History* history)
{
    DBG("history=%p", history);
    history->core->deref();
    free(history);
}
