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

    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_view.h"

#include "ewk_private.h"
#include "ewk_tiled_backing_store_private.h"
#include "ewk_view_private.h"
#include <Evas.h>
#include <eina_safety_checks.h>

static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL;

static bool _ewk_view_tiled_render_cb(void* data, Ewk_Tile* tile, const Eina_Rectangle* area)
{
    Ewk_View_Private_Data* priv = static_cast<Ewk_View_Private_Data*>(data);
    Eina_Rectangle rect = {area->x + tile->x, area->y + tile->y, area->w, area->h};

    uint8_t* pixels = static_cast<uint8_t*>(evas_object_image_data_get(tile->image, true));
    Ewk_Paint_Context* context = ewk_paint_context_from_image_data_new(pixels, tile->width, tile->height, tile->cspace);

    ewk_paint_context_translate(context, -tile->x, -tile->y);
    bool result = ewk_view_paint_contents(priv, context, &rect);
    ewk_paint_context_free(context);

    evas_object_image_data_set(tile->image, pixels);

    return result;
}

static void* _ewk_view_tiled_updates_process_pre(void* data, Evas_Object*)
{
    Ewk_View_Private_Data* priv = static_cast<Ewk_View_Private_Data*>(data);
    ewk_view_layout_if_needed_recursive(priv);
    return 0;
}

static Evas_Object* _ewk_view_tiled_smart_backing_store_add(Ewk_View_Smart_Data* smartData)
{
    Evas_Object* backingStore = ewk_tiled_backing_store_add(smartData->base.evas);
    ewk_tiled_backing_store_render_cb_set(backingStore, _ewk_view_tiled_render_cb, smartData->_priv);
    ewk_tiled_backing_store_updates_process_pre_set
        (backingStore, _ewk_view_tiled_updates_process_pre, smartData->_priv);
    return backingStore;
}

static void
_ewk_view_tiled_contents_size_changed_cb(void* data, Evas_Object*, void* eventInfo)
{
    Evas_Coord* size = static_cast<Evas_Coord*>(eventInfo);
    Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);

    ewk_tiled_backing_store_contents_resize
        (smartData->backing_store, size[0], size[1]);
}

static void _ewk_view_tiled_smart_add(Evas_Object* ewkView)
{
    Ewk_View_Smart_Data* smartData;

    _parent_sc.sc.add(ewkView);

    smartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(ewkView));
    if (!smartData)
        return;

    evas_object_smart_callback_add(
        smartData->main_frame, "contents,size,changed",
        _ewk_view_tiled_contents_size_changed_cb, smartData);
}

static Eina_Bool _ewk_view_tiled_smart_scrolls_process(Ewk_View_Smart_Data* smartData)
{
    const Ewk_Scroll_Request* scrollRequest;
    const Ewk_Scroll_Request* endOfScrollRequest;
    size_t count;
    Evas_Coord contentsWidth, contentsHeight;

    ewk_frame_contents_size_get(smartData->main_frame, &contentsWidth, &contentsHeight);

    scrollRequest = ewk_view_scroll_requests_get(smartData->_priv, &count);
    endOfScrollRequest = scrollRequest + count;
    for (; scrollRequest < endOfScrollRequest; scrollRequest++)
        ewk_tiled_backing_store_scroll_full_offset_add(smartData->backing_store, scrollRequest->dx, scrollRequest->dy);

    return true;
}

static Eina_Bool _ewk_view_tiled_smart_repaints_process(Ewk_View_Smart_Data* smartData)
{
    const Eina_Rectangle* paintRect, * endOfpaintRect;
    size_t count;
    int scrollX, scrollY;

    ewk_frame_scroll_pos_get(smartData->main_frame, &scrollX, &scrollY);

    paintRect = ewk_view_repaints_pop(smartData->_priv, &count);
    endOfpaintRect = paintRect + count;
    for (; paintRect < endOfpaintRect; paintRect++) {
        Eina_Rectangle rect;
        rect.x = paintRect->x + scrollX;
        rect.y = paintRect->y + scrollY;
        rect.w = paintRect->w;
        rect.h = paintRect->h;
        ewk_tiled_backing_store_update(smartData->backing_store, &rect);
    }
    ewk_tiled_backing_store_updates_process(smartData->backing_store);

    return true;
}

static Eina_Bool _ewk_view_tiled_smart_contents_resize(Ewk_View_Smart_Data* smartData, int width, int height)
{
    ewk_tiled_backing_store_contents_resize(smartData->backing_store, width, height);
    return true;
}

static Eina_Bool _ewk_view_tiled_smart_zoom_set(Ewk_View_Smart_Data* smartData, float zoom, Evas_Coord centerX, Evas_Coord centerY)
{
    Evas_Coord x, y, width, height;
    Eina_Bool result;
    result = ewk_tiled_backing_store_zoom_set(smartData->backing_store,
                                         &zoom, centerX, centerY, &x, &y);
    if (!result)
        return result;
    ewk_tiled_backing_store_disabled_update_set(smartData->backing_store, true);
    result = _parent_sc.zoom_set(smartData, zoom, centerX, centerY);
    ewk_frame_scroll_set(smartData->main_frame, -x, -y);
    ewk_frame_scroll_size_get(smartData->main_frame, &width, &height);
    ewk_tiled_backing_store_fix_offsets(smartData->backing_store, width, height);
    ewk_view_scrolls_process(smartData);
    evas_object_smart_calculate(smartData->backing_store);
    evas_object_smart_calculate(smartData->self);
    ewk_tiled_backing_store_disabled_update_set(smartData->backing_store, false);
    return result;
}

static Eina_Bool _ewk_view_tiled_smart_zoom_weak_set(Ewk_View_Smart_Data* smartData, float zoom, Evas_Coord centerX, Evas_Coord centerY)
{
    return ewk_tiled_backing_store_zoom_weak_set(smartData->backing_store, zoom, centerX, centerY);
}

static void _ewk_view_tiled_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data* smartData, Eina_Bool smoothScale)
{
    ewk_tiled_backing_store_zoom_weak_smooth_scale_set(smartData->backing_store, smoothScale);
}

static void _ewk_view_tiled_smart_bg_color_set(Ewk_View_Smart_Data* smartData, unsigned char /*red*/, unsigned char /*green*/, unsigned char /*blue*/, unsigned char alpha)
{
    ewk_tiled_backing_store_alpha_set(smartData->backing_store, alpha < 255);
}

static void _ewk_view_tiled_smart_flush(Ewk_View_Smart_Data* smartData)
{
    ewk_tiled_backing_store_flush(smartData->backing_store);
    _parent_sc.flush(smartData);
}

static Eina_Bool _ewk_view_tiled_smart_pre_render_region(Ewk_View_Smart_Data* smartData, Evas_Coord x, Evas_Coord y, Evas_Coord width, Evas_Coord height, float zoom)
{
    return ewk_tiled_backing_store_pre_render_region
               (smartData->backing_store, x, y, width, height, zoom);
}

static Eina_Bool _ewk_view_tiled_smart_pre_render_relative_radius(Ewk_View_Smart_Data* smartData, unsigned int n, float zoom)
{
    return ewk_tiled_backing_store_pre_render_relative_radius
               (smartData->backing_store, n, zoom);
}

static inline int _ewk_view_tiled_rect_collision_check(Eina_Rectangle destination, Eina_Rectangle source)
{
    int direction = 0;
    if (destination.x < source.x)
        direction = direction | (1 << 0); // 0 bit shift, left
    if (destination.y < source.y)
        direction = direction | (1 << 1); // 1 bit shift, top
    if (destination.x + destination.w > source.x + source.w)
        direction = direction | (1 << 2); // 2 bit shift, right
    if (destination.y + destination.h > source.y + source.h)
        direction = direction | (1 << 3); // 3 bit shift, bottom
    DBG("check collision %d\r\n", direction);
    return direction;
}

static inline void _ewk_view_tiled_rect_collision_resolve(int direction, Eina_Rectangle* destination, Eina_Rectangle source)
{
    if (direction & (1 << 0)) // 0 bit shift, left
        destination->x = source.x;
    if (direction & (1 << 1)) // 1 bit shift, top
        destination->y = source.y;
    if (direction & (1 << 2)) // 2 bit shift, right
        destination->x = destination->x - ((destination->x + destination->w) - (source.x + source.w));
    if (direction & (1 << 3)) // 3 bit shift, bottom
        destination->y = destination->y - ((destination->y + destination->h) - (source.y + source.h));
}

static Eina_Bool _ewk_view_tiled_smart_pre_render_start(Ewk_View_Smart_Data* smartData)
{
    int contentWidth, contentHeight;
    ewk_frame_contents_size_get(smartData->main_frame, &contentWidth, &contentHeight);

    int viewX, viewY, viewWidth, viewHeight;
    ewk_frame_visible_content_geometry_get(smartData->main_frame, false, &viewX, &viewY, &viewWidth, &viewHeight);

    if (viewWidth <= 0 || viewHeight <= 0 || contentWidth <= 0 || contentHeight <= 0)
        return false;

    if (viewWidth >= contentWidth && viewHeight >= contentHeight)
        return false;

    int previousViewX, previousViewY;
    previousViewX = smartData->previousView.x;
    previousViewY = smartData->previousView.y;

    if (previousViewX < 0 || previousViewX > contentWidth || previousViewY < 0 || previousViewY > contentHeight)
        previousViewX = previousViewY = 0;

    float currentViewZoom = ewk_view_zoom_get(smartData->self);

    // pre-render works when two conditions are met.
    // zoom has been changed.
    // and the view has been moved more than tile size.
    if (abs(previousViewX - viewX) < defaultTileWidth
        && abs(previousViewY - viewY) < defaultTileHeigth
        && smartData->previousView.zoom == currentViewZoom) {
        return false;
    }

    // store previous view position and zoom.
    smartData->previousView.x = viewX;
    smartData->previousView.y = viewY;
    smartData->previousView.zoom = currentViewZoom;

    // cancelling previous pre-rendering list if exists.
    ewk_view_pre_render_cancel(smartData->self);

    Ewk_Tile_Unused_Cache* tileUnusedCache = ewk_view_tiled_unused_cache_get(smartData->self);
    int maxMemory = ewk_tile_unused_cache_max_get(tileUnusedCache);
    if (maxMemory <= viewWidth * viewHeight * EWK_ARGB_BYTES_SIZE)
        return false;

    Eina_Rectangle viewRect = {viewX, viewY, viewWidth, viewHeight};
    Eina_Rectangle contentRect = {0, 0, contentWidth, contentHeight};

    // get a base render rect.
    const int contentMemory = contentWidth * contentHeight * EWK_ARGB_BYTES_SIZE;

    // get render rect's width and height.
    Eina_Rectangle renderRect;
    if (maxMemory > contentMemory)
        renderRect = contentRect;
    else {
        // Make a base rectangle as big as possible with using maxMemory.
        // and then reshape the base rectangle to fit to contents.
        const int baseSize = static_cast<int>(sqrt(maxMemory / 4.0f));
        const float widthRate = (viewRect.w + (defaultTileWidth * 2)) / static_cast<float>(baseSize);
        const float heightRate = baseSize / static_cast<float>(contentHeight);
        const float rectRate = std::max(widthRate, heightRate);

        renderRect.w = static_cast<int>(baseSize * rectRate);
        renderRect.h = static_cast<int>(baseSize / rectRate);
        renderRect.x = viewRect.x + (viewRect.w / 2) - (renderRect.w / 2);
        renderRect.y = viewRect.y + (viewRect.h / 2) - (renderRect.h / 2);

        // reposition of renderRect, if the renderRect overlapped the content rect, this code moves the renderRect inside the content rect.
        int collisionSide = _ewk_view_tiled_rect_collision_check(renderRect, contentRect);
        if (collisionSide > 0)
            _ewk_view_tiled_rect_collision_resolve(collisionSide, &renderRect, contentRect);

        // check abnormal render rect
        if (renderRect.x < 0)
            renderRect.x = 0;
        if (renderRect.y < 0)
            renderRect.y = 0;
        if (renderRect.w > contentWidth)
            renderRect.w = contentWidth;
        if (renderRect.h > contentHeight)
            renderRect.h = contentHeight;
    }

    // enqueue tiles into tiled backing store in spiral order.
    ewk_tiled_backing_store_pre_render_spiral_queue(smartData->backing_store, &viewRect, &renderRect, maxMemory, currentViewZoom);

    return true;
}

static void _ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data* smartData)
{
    ewk_tiled_backing_store_pre_render_cancel(smartData->backing_store);
}

static Eina_Bool _ewk_view_tiled_smart_disable_render(Ewk_View_Smart_Data* smartData)
{
    return ewk_tiled_backing_store_disable_render(smartData->backing_store);
}

static Eina_Bool _ewk_view_tiled_smart_enable_render(Ewk_View_Smart_Data* smartData)
{
    return ewk_tiled_backing_store_enable_render(smartData->backing_store);
}

Eina_Bool ewk_view_tiled_smart_set(Ewk_View_Smart_Class* api)
{
    if (!ewk_view_base_smart_set(api))
        return false;

    if (EINA_UNLIKELY(!_parent_sc.sc.add)) {
        _parent_sc.sc.name = ewkViewTiledName;
        ewk_view_base_smart_set(&_parent_sc);
        api->sc.parent = reinterpret_cast<Evas_Smart_Class*>(&_parent_sc);
    }

    api->sc.add = _ewk_view_tiled_smart_add;

    api->backing_store_add = _ewk_view_tiled_smart_backing_store_add;
    api->scrolls_process = _ewk_view_tiled_smart_scrolls_process;
    api->repaints_process = _ewk_view_tiled_smart_repaints_process;
    api->contents_resize = _ewk_view_tiled_smart_contents_resize;
    api->zoom_set = _ewk_view_tiled_smart_zoom_set;
    api->zoom_weak_set = _ewk_view_tiled_smart_zoom_weak_set;
    api->zoom_weak_smooth_scale_set = _ewk_view_tiled_smart_zoom_weak_smooth_scale_set;
    api->bg_color_set = _ewk_view_tiled_smart_bg_color_set;
    api->flush = _ewk_view_tiled_smart_flush;
    api->pre_render_region = _ewk_view_tiled_smart_pre_render_region;
    api->pre_render_relative_radius = _ewk_view_tiled_smart_pre_render_relative_radius;
    api->pre_render_start = _ewk_view_tiled_smart_pre_render_start;
    api->pre_render_cancel = _ewk_view_tiled_smart_pre_render_cancel;
    api->disable_render = _ewk_view_tiled_smart_disable_render;
    api->enable_render = _ewk_view_tiled_smart_enable_render;
    return true;
}

static inline Evas_Smart* _ewk_view_tiled_smart_class_new(void)
{
    static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(ewkViewTiledName);
    static Evas_Smart* smart = 0;

    if (EINA_UNLIKELY(!smart)) {
        ewk_view_tiled_smart_set(&api);
        smart = evas_smart_class_new(&api.sc);
    }

    return smart;
}

Evas_Object* ewk_view_tiled_add(Evas* canvas)
{
    return evas_object_smart_add(canvas, _ewk_view_tiled_smart_class_new());
}

Ewk_Tile_Unused_Cache* ewk_view_tiled_unused_cache_get(const Evas_Object* ewkView)
{
    EWK_VIEW_TYPE_CHECK_OR_RETURN(ewkView, ewkViewTiledName, 0);
    Ewk_View_Smart_Data* smartData = ewk_view_smart_data_get(ewkView);
    EINA_SAFETY_ON_NULL_RETURN_VAL(smartData, 0);
    return ewk_tiled_backing_store_tile_unused_cache_get(smartData->backing_store);
}

void ewk_view_tiled_unused_cache_set(Evas_Object* ewkView, Ewk_Tile_Unused_Cache* cache)
{
    EWK_VIEW_TYPE_CHECK_OR_RETURN(ewkView, ewkViewTiledName);
    Ewk_View_Smart_Data* smartData = ewk_view_smart_data_get(ewkView);
    EINA_SAFETY_ON_NULL_RETURN(smartData);
    ewk_tiled_backing_store_tile_unused_cache_set(smartData->backing_store, cache);
}
