/*
 * Copyright 2007, The Android Open Source Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_TAG "webviewglue"

#include "config.h"

#include "AndroidAnimation.h"
#include "AndroidLog.h"
#include "BaseLayerAndroid.h"
#include "BaseRenderer.h"
#include "DrawExtra.h"
#include "DumpLayer.h"
#include "Frame.h"
#include "GLWebViewState.h"
#include "GraphicsJNI.h"
#include "HTMLInputElement.h"
#include "IntPoint.h"
#include "IntRect.h"
#include "LayerAndroid.h"
#include "LayerContent.h"
#include "Node.h"
#include "utils/Functor.h"
#include "private/hwui/DrawGlInfo.h"
#include "PlatformGraphicsContext.h"
#include "PlatformString.h"
#include "ScrollableLayerAndroid.h"
#include "SelectText.h"
#include "SkCanvas.h"
#include "SkDumpCanvas.h"
#include "SkPicture.h"
#include "SkRect.h"
#include "SkTime.h"
#include "TilesManager.h"
#include "TransferQueue.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "WebViewCore.h"

#ifdef GET_NATIVE_VIEW
#undef GET_NATIVE_VIEW
#endif

#define GET_NATIVE_VIEW(env, obj) ((WebView*)env->GetIntField(obj, gWebViewField))

#include <JNIUtility.h>
#include <JNIHelp.h>
#include <jni.h>
#include <androidfw/KeycodeLabels.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>

// Free as much as we possible can
#define TRIM_MEMORY_COMPLETE 80
// Free a lot (all textures gone)
#define TRIM_MEMORY_MODERATE 60
// More moderate free (keep bare minimum to restore quickly-ish - possibly clear all textures)
#define TRIM_MEMORY_BACKGROUND 40
// Moderate free (clear cached tiles, keep visible ones)
#define TRIM_MEMORY_UI_HIDDEN 20
// Duration to show the pressed cursor ring
#define PRESSED_STATE_DURATION 400

namespace android {

static jfieldID gWebViewField;

//-------------------------------------

static jmethodID GetJMethod(JNIEnv* env, jclass clazz, const char name[], const char signature[])
{
    jmethodID m = env->GetMethodID(clazz, name, signature);
    ALOG_ASSERT(m, "Could not find method %s", name);
    return m;
}

//-------------------------------------
// This class provides JNI for making calls into native code from the UI side
// of the multi-threaded WebView.
class WebView
{
public:
enum FrameCachePermission {
    DontAllowNewer,
    AllowNewer
};

#define DRAW_EXTRAS_SIZE 2
enum DrawExtras { // keep this in sync with WebView.java
    DrawExtrasNone = 0,
    DrawExtrasSelection = 1,
    DrawExtrasCursorRing = 2
};

struct JavaGlue {
    jweak       m_obj;
    jmethodID   m_scrollBy;
    jmethodID   m_getScaledMaxXScroll;
    jmethodID   m_getScaledMaxYScroll;
    jmethodID   m_updateRectsForGL;
    jmethodID   m_viewInvalidate;
    jmethodID   m_viewInvalidateRect;
    jmethodID   m_postInvalidateDelayed;
    jmethodID   m_pageSwapCallback;
    jfieldID    m_rectLeft;
    jfieldID    m_rectTop;
    jmethodID   m_rectWidth;
    jmethodID   m_rectHeight;
    jfieldID    m_quadFP1;
    jfieldID    m_quadFP2;
    jfieldID    m_quadFP3;
    jfieldID    m_quadFP4;
    AutoJObject object(JNIEnv* env) {
        return getRealObject(env, m_obj);
    }
} m_javaGlue;

WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir,
        bool isHighEndGfx)
    : m_isHighEndGfx(isHighEndGfx)
{
    memset(m_extras, 0, DRAW_EXTRAS_SIZE * sizeof(DrawExtra*));
    jclass clazz = env->FindClass("android/webkit/WebViewClassic");
    m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView);
    m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z");
    m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I");
    m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I");
    m_javaGlue.m_updateRectsForGL = GetJMethod(env, clazz, "updateRectsForGL", "()V");
    m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V");
    m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V");
    m_javaGlue.m_postInvalidateDelayed = GetJMethod(env, clazz,
        "viewInvalidateDelayed", "(JIIII)V");
    m_javaGlue.m_pageSwapCallback = GetJMethod(env, clazz, "pageSwapCallback", "(Z)V");
    env->DeleteLocalRef(clazz);

    jclass rectClass = env->FindClass("android/graphics/Rect");
    ALOG_ASSERT(rectClass, "Could not find Rect class");
    m_javaGlue.m_rectLeft = env->GetFieldID(rectClass, "left", "I");
    m_javaGlue.m_rectTop = env->GetFieldID(rectClass, "top", "I");
    m_javaGlue.m_rectWidth = GetJMethod(env, rectClass, "width", "()I");
    m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I");
    env->DeleteLocalRef(rectClass);

    jclass quadFClass = env->FindClass("android/webkit/QuadF");
    ALOG_ASSERT(quadFClass, "Could not find QuadF class");
    m_javaGlue.m_quadFP1 = env->GetFieldID(quadFClass, "p1", "Landroid/graphics/PointF;");
    m_javaGlue.m_quadFP2 = env->GetFieldID(quadFClass, "p2", "Landroid/graphics/PointF;");
    m_javaGlue.m_quadFP3 = env->GetFieldID(quadFClass, "p3", "Landroid/graphics/PointF;");
    m_javaGlue.m_quadFP4 = env->GetFieldID(quadFClass, "p4", "Landroid/graphics/PointF;");
    env->DeleteLocalRef(quadFClass);

    env->SetIntField(javaWebView, gWebViewField, (jint)this);
    m_viewImpl = (WebViewCore*) viewImpl;
    m_generation = 0;
    m_heightCanMeasure = false;
    m_lastDx = 0;
    m_lastDxTime = 0;
    m_baseLayer = 0;
    m_glDrawFunctor = 0;
    m_isDrawingPaused = false;
#if USE(ACCELERATED_COMPOSITING)
    m_glWebViewState = 0;
#endif
}

~WebView()
{
    if (m_javaGlue.m_obj)
    {
        JNIEnv* env = JSC::Bindings::getJNIEnv();
        env->DeleteWeakGlobalRef(m_javaGlue.m_obj);
        m_javaGlue.m_obj = 0;
    }
#if USE(ACCELERATED_COMPOSITING)
    // We must remove the m_glWebViewState prior to deleting m_baseLayer. If we
    // do not remove it here, we risk having BaseTiles trying to paint using a
    // deallocated base layer.
    stopGL();
#endif
    SkSafeUnref(m_baseLayer);
    delete m_glDrawFunctor;
    for (int i = 0; i < DRAW_EXTRAS_SIZE; i++)
        delete m_extras[i];
}

DrawExtra* getDrawExtra(DrawExtras extras)
{
    if (extras == DrawExtrasNone)
        return 0;
    return m_extras[extras - 1];
}

void stopGL()
{
#if USE(ACCELERATED_COMPOSITING)
    delete m_glWebViewState;
    m_glWebViewState = 0;
#endif
}

WebViewCore* getWebViewCore() const {
    return m_viewImpl;
}

void scrollRectOnScreen(const IntRect& rect)
{
    if (rect.isEmpty())
        return;
    int dx = 0;
    int left = rect.x();
    int right = rect.maxX();
    if (left < m_visibleContentRect.fLeft)
        dx = left - m_visibleContentRect.fLeft;
    // Only scroll right if the entire width can fit on screen.
    else if (right > m_visibleContentRect.fRight
            && right - left < m_visibleContentRect.width())
        dx = right - m_visibleContentRect.fRight;
    int dy = 0;
    int top = rect.y();
    int bottom = rect.maxY();
    if (top < m_visibleContentRect.fTop)
        dy = top - m_visibleContentRect.fTop;
    // Only scroll down if the entire height can fit on screen
    else if (bottom > m_visibleContentRect.fBottom
            && bottom - top < m_visibleContentRect.height())
        dy = bottom - m_visibleContentRect.fBottom;
    if ((dx|dy) == 0 || !scrollBy(dx, dy))
        return;
    viewInvalidate();
}

int drawGL(WebCore::IntRect& invScreenRect, WebCore::IntRect* invalRect,
        WebCore::IntRect& screenRect, int titleBarHeight,
        WebCore::IntRect& screenClip, float scale, int extras, bool shouldDraw)
{
#if USE(ACCELERATED_COMPOSITING)
    if (!m_baseLayer)
        return 0;

    if (m_viewImpl)
        m_viewImpl->setPrerenderingEnabled(!m_isDrawingPaused);

    if (!m_glWebViewState) {
        TilesManager::instance()->setHighEndGfx(m_isHighEndGfx);
        m_glWebViewState = new GLWebViewState();
        m_glWebViewState->setBaseLayer(m_baseLayer, false, true);
    }

    DrawExtra* extra = getDrawExtra((DrawExtras) extras);

    m_glWebViewState->glExtras()->setDrawExtra(extra);

    // Make sure we have valid coordinates. We might not have valid coords
    // if the zoom manager is still initializing. We will be redrawn
    // once the correct scale is set
    if (!m_visibleContentRect.isFinite())
        return 0;
    bool treesSwapped = false;
    bool newTreeHasAnim = false;
    int ret = m_glWebViewState->drawGL(invScreenRect, m_visibleContentRect, invalRect,
                                        screenRect, titleBarHeight, screenClip, scale,
                                        &treesSwapped, &newTreeHasAnim, shouldDraw);
    if (treesSwapped) {
        ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
        JNIEnv* env = JSC::Bindings::getJNIEnv();
        AutoJObject javaObject = m_javaGlue.object(env);
        if (javaObject.get()) {
            env->CallVoidMethod(javaObject.get(), m_javaGlue.m_pageSwapCallback, newTreeHasAnim);
            checkException(env);
        }
    }
    return m_isDrawingPaused ? 0 : ret;
#endif
    return 0;
}

void draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras)
{
    if (!m_baseLayer) {
        canvas->drawColor(bgColor);
        return;
    }

    // draw the content of the base layer first
    LayerContent* content = m_baseLayer->content();
    int sc = canvas->save(SkCanvas::kClip_SaveFlag);
    if (content) {
        canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), content->height()),
                         SkRegion::kDifference_Op);
    }
    Color c = m_baseLayer->getBackgroundColor();
    canvas->drawColor(SkColorSetARGBInline(c.alpha(), c.red(), c.green(), c.blue()));
    canvas->restoreToCount(sc);

    // call this to be sure we've adjusted for any scrolling or animations
    // before we actually draw
    m_baseLayer->updatePositionsRecursive(m_visibleContentRect);
    m_baseLayer->updatePositions();

    // We have to set the canvas' matrix on the base layer
    // (to have fixed layers work as intended)
    SkAutoCanvasRestore restore(canvas, true);
    m_baseLayer->setMatrix(canvas->getTotalMatrix());
    canvas->resetMatrix();
    m_baseLayer->draw(canvas, getDrawExtra(extras));
}

int getScaledMaxXScroll()
{
    ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return 0;
    int result = env->CallIntMethod(javaObject.get(), m_javaGlue.m_getScaledMaxXScroll);
    checkException(env);
    return result;
}

int getScaledMaxYScroll()
{
    ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return 0;
    int result = env->CallIntMethod(javaObject.get(), m_javaGlue.m_getScaledMaxYScroll);
    checkException(env);
    return result;
}

// Call through JNI to ask Java side to update the rectangles for GL functor.
// This is called at every draw when it is not in process mode, so we should
// keep this route as efficient as possible. Currently, its average cost on Xoom
// is about 0.1ms - 0.2ms.
// Alternatively, this can be achieved by adding more listener on Java side, but
// that will be more likely causing jank when triggering GC.
void updateRectsForGL()
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return;
    env->CallVoidMethod(javaObject.get(), m_javaGlue.m_updateRectsForGL);
    checkException(env);
}

#if USE(ACCELERATED_COMPOSITING)
static const ScrollableLayerAndroid* findScrollableLayer(
    const LayerAndroid* parent, int x, int y, SkIRect* foundBounds) {
    IntRect bounds = enclosingIntRect(parent->fullContentAreaMapped());

    // Check the parent bounds first; this will clip to within a masking layer's
    // bounds.
    if (parent->masksToBounds() && !bounds.contains(x, y))
        return 0;

    int count = parent->countChildren();
    while (count--) {
        const LayerAndroid* child = parent->getChild(count);
        const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y, foundBounds);
        if (result) {
            if (parent->masksToBounds()) {
                if (bounds.width() < foundBounds->width())
                    foundBounds->fRight = foundBounds->fLeft + bounds.width();
                if (bounds.height() < foundBounds->height())
                    foundBounds->fBottom = foundBounds->fTop + bounds.height();
            }
            return result;
        }
    }
    if (parent->contentIsScrollable()) {
        foundBounds->set(bounds.x(), bounds.y(), bounds.width(), bounds.height());
        return static_cast<const ScrollableLayerAndroid*>(parent);
    }
    return 0;
}
#endif

int scrollableLayer(int x, int y, SkIRect* layerRect, SkIRect* bounds)
{
#if USE(ACCELERATED_COMPOSITING)
    if (!m_baseLayer)
        return 0;
    const ScrollableLayerAndroid* result = findScrollableLayer(m_baseLayer, x, y, bounds);
    if (result) {
        result->getScrollRect(layerRect);
        return result->uniqueId();
    }
#endif
    return 0;
}

void scrollLayer(int layerId, int x, int y)
{
    if (m_glWebViewState)
        m_glWebViewState->scrollLayer(layerId, x, y);
}

void setHeightCanMeasure(bool measure)
{
    m_heightCanMeasure = measure;
}

String getSelection()
{
    SelectText* select = static_cast<SelectText*>(
            getDrawExtra(WebView::DrawExtrasSelection));
    if (select)
        return select->getText();
    return String();
}

bool scrollBy(int dx, int dy)
{
    ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");

    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return false;
    bool result = env->CallBooleanMethod(javaObject.get(), m_javaGlue.m_scrollBy, dx, dy, true);
    checkException(env);
    return result;
}

void setIsScrolling(bool isScrolling)
{
#if USE(ACCELERATED_COMPOSITING)
    if (m_glWebViewState)
        m_glWebViewState->setIsScrolling(isScrolling);
#endif
}

void viewInvalidate()
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return;
    env->CallVoidMethod(javaObject.get(), m_javaGlue.m_viewInvalidate);
    checkException(env);
}

void viewInvalidateRect(int l, int t, int r, int b)
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return;
    env->CallVoidMethod(javaObject.get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b);
    checkException(env);
}

void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds)
{
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    AutoJObject javaObject = m_javaGlue.object(env);
    if (!javaObject.get())
        return;
    env->CallVoidMethod(javaObject.get(), m_javaGlue.m_postInvalidateDelayed,
        delay, bounds.x(), bounds.y(), bounds.maxX(), bounds.maxY());
    checkException(env);
}

#if ENABLE(ANDROID_OVERFLOW_SCROLL)
static void copyScrollPosition(const LayerAndroid* fromRoot,
                               LayerAndroid* toRoot, int layerId)
{
    if (!fromRoot || !toRoot)
        return;
    const LayerAndroid* from = fromRoot->findById(layerId);
    LayerAndroid* to = toRoot->findById(layerId);
    if (!from || !to || !from->contentIsScrollable() || !to->contentIsScrollable())
        return;
    // TODO: Support this for iframes.
    if (to->isIFrameContent() || from->isIFrameContent())
        return;
    to->setScrollOffset(from->getScrollOffset());
}
#endif

BaseLayerAndroid* getBaseLayer() const { return m_baseLayer; }

bool setBaseLayer(BaseLayerAndroid* newBaseLayer, bool showVisualIndicator,
                  bool isPictureAfterFirstLayout, int scrollingLayer)
{
    bool queueFull = false;
#if USE(ACCELERATED_COMPOSITING)
    if (m_glWebViewState)
        queueFull = m_glWebViewState->setBaseLayer(newBaseLayer, showVisualIndicator,
                                                   isPictureAfterFirstLayout);
#endif

#if ENABLE(ANDROID_OVERFLOW_SCROLL)
    copyScrollPosition(m_baseLayer, newBaseLayer, scrollingLayer);
#endif
    SkSafeUnref(m_baseLayer);
    m_baseLayer = newBaseLayer;

    return queueFull;
}

void copyBaseContentToPicture(SkPicture* picture)
{
    if (!m_baseLayer || !m_baseLayer->content())
        return;
    LayerContent* content = m_baseLayer->content();
    SkCanvas* canvas = picture->beginRecording(content->width(), content->height(),
                                              SkPicture::kUsePathBoundsForClip_RecordingFlag);

    // clear the BaseLayerAndroid's previous matrix (set at each draw)
    SkMatrix baseMatrix;
    baseMatrix.reset();
    m_baseLayer->setMatrix(baseMatrix);

    m_baseLayer->draw(canvas, 0);

    picture->endRecording();
}

bool hasContent() {
    if (!m_baseLayer || !m_baseLayer->content())
        return false;
    return !m_baseLayer->content()->isEmpty();
}

void setFunctor(Functor* functor) {
    delete m_glDrawFunctor;
    m_glDrawFunctor = functor;
}

Functor* getFunctor() {
    return m_glDrawFunctor;
}

void setVisibleContentRect(SkRect& visibleContentRect) {
    m_visibleContentRect = visibleContentRect;
}

void setDrawExtra(DrawExtra *extra, DrawExtras type)
{
    if (type == DrawExtrasNone)
        return;
    DrawExtra* old = m_extras[type - 1];
    m_extras[type - 1] = extra;
    if (old != extra) {
        delete old;
    }
}

void setTextSelection(SelectText *selection) {
    setDrawExtra(selection, DrawExtrasSelection);
}

const TransformationMatrix* getLayerTransform(int layerId) {
    if (layerId != -1 && m_baseLayer) {
        LayerAndroid* layer = m_baseLayer->findById(layerId);
        // We need to make sure the drawTransform is up to date as this is
        // called before a draw() or drawGL()
        if (layer) {
            m_baseLayer->updatePositionsRecursive(m_visibleContentRect);
            return layer->drawTransform();
        }
    }
    return 0;
}

int getHandleLayerId(SelectText::HandleId handleId, SkIPoint& cursorPoint,
        FloatQuad& textBounds) {
    SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection));
    if (!selectText || !m_baseLayer)
        return -1;
    int layerId = selectText->caretLayerId(handleId);
    IntRect cursorRect = selectText->caretRect(handleId);
    IntRect textRect = selectText->textRect(handleId);
    // Rects exclude the last pixel on right/bottom. We want only included pixels.
    cursorPoint.set(cursorRect.x(), cursorRect.maxY() - 1);
    textRect.setHeight(std::max(1, textRect.height() - 1));
    textRect.setWidth(std::max(1, textRect.width() - 1));
    textBounds = FloatQuad(textRect);

    const TransformationMatrix* transform = getLayerTransform(layerId);
    if (transform) {
        // We're overloading the concept of Rect to be just the two
        // points (bottom-left and top-right.
        cursorPoint = transform->mapPoint(cursorPoint);
        textBounds = transform->mapQuad(textBounds);
    }
    return layerId;
}

void mapLayerRect(int layerId, SkIRect& rect) {
    const TransformationMatrix* transform = getLayerTransform(layerId);
    if (transform)
        rect = transform->mapRect(rect);
}

void floatQuadToQuadF(JNIEnv* env, const FloatQuad& nativeTextQuad,
        jobject textQuad)
{
    jobject p1 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP1);
    jobject p2 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP2);
    jobject p3 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP3);
    jobject p4 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP4);
    GraphicsJNI::point_to_jpointf(nativeTextQuad.p1(), env, p1);
    GraphicsJNI::point_to_jpointf(nativeTextQuad.p2(), env, p2);
    GraphicsJNI::point_to_jpointf(nativeTextQuad.p3(), env, p3);
    GraphicsJNI::point_to_jpointf(nativeTextQuad.p4(), env, p4);
    env->DeleteLocalRef(p1);
    env->DeleteLocalRef(p2);
    env->DeleteLocalRef(p3);
    env->DeleteLocalRef(p4);
}

// This is called when WebView switches rendering modes in a more permanent fashion
// such as when the layer type is set or the view is attached/detached from the window
int setHwAccelerated(bool hwAccelerated) {
    if (!m_glWebViewState)
        return 0;
    LayerAndroid* root = m_baseLayer;
    if (root)
        return root->setHwAccelerated(hwAccelerated);
    return 0;
}

void setDrawingPaused(bool isPaused)
{
    m_isDrawingPaused = isPaused;
    if (m_viewImpl)
        m_viewImpl->setPrerenderingEnabled(!isPaused);
}

// Finds the rectangles within world to the left, right, top, and bottom
// of rect and adds them to rects. If no intersection exists, false is returned.
static bool findMaskedRects(const FloatRect& world,
        const FloatRect& rect, Vector<FloatRect>& rects) {
    if (!world.intersects(rect))
        return false; // nothing to subtract

    // left rectangle
    if (rect.x() > world.x())
        rects.append(FloatRect(world.x(), world.y(),
                rect.x() - world.x(), world.height()));
    // top rectangle
    if (rect.y() > world.y())
        rects.append(FloatRect(world.x(), world.y(),
                world.width(), rect.y() - world.y()));
    // right rectangle
    if (rect.maxX() < world.maxX())
        rects.append(FloatRect(rect.maxX(), world.y(),
                world.maxX() - rect.maxX(), world.height()));
    // bottom rectangle
    if (rect.maxY() < world.maxY())
        rects.append(FloatRect(world.x(), rect.maxY(),
                world.width(), world.maxY() - rect.maxY()));
    return true;
}

// Returns false if layerId is a fixed position layer, otherwise
// all fixed position layer rectangles are subtracted from those within
// rects. Rects will be modified to contain rectangles that don't include
// the fixed position layer rectangles.
static bool findMaskedRectsForLayer(LayerAndroid* layer,
        Vector<FloatRect>& rects, int layerId)
{
    if (layer->isPositionFixed()) {
        if (layerId == layer->uniqueId())
            return false;
        FloatRect layerRect = layer->fullContentAreaMapped();
        for (int i = rects.size() - 1; i >= 0; i--)
            if (findMaskedRects(rects[i], layerRect, rects))
                rects.remove(i);
    }

    int childIndex = 0;
    while (LayerAndroid* child = layer->getChild(childIndex++))
        if (!findMaskedRectsForLayer(child, rects, layerId))
            return false;

    return true;
}

// Finds the largest rectangle not masked by any fixed layer.
void findMaxVisibleRect(int movingLayerId, SkIRect& visibleContentRect)
{
    if (!m_baseLayer)
        return;

    FloatRect visibleContentFloatRect(visibleContentRect);
    m_baseLayer->updatePositionsRecursive(visibleContentFloatRect);
    Vector<FloatRect> rects;
    rects.append(visibleContentFloatRect);
    if (findMaskedRectsForLayer(m_baseLayer, rects, movingLayerId)) {
        float maxSize = 0.0;
        const FloatRect* largest = 0;
        for (unsigned int i = 0; i < rects.size(); i++) {
            const FloatRect& rect = rects[i];
            float size = rect.width() * rect.height();
            if (size > maxSize) {
                maxSize = size;
                largest = &rect;
            }
        }
        if (largest) {
            SkRect largeRect = *largest;
            largeRect.round(&visibleContentRect);
        }
    }
}

bool isHandleLeft(SelectText::HandleId handleId)
{
    SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection));
    if (!selectText)
        return (handleId == SelectText::BaseHandle);

    return (selectText->getHandleType(handleId) == SelectText::LeftHandle);
}

bool isPointVisible(int layerId, int contentX, int contentY)
{
    bool isVisible = true;
    const TransformationMatrix* transform = getLayerTransform(layerId);
    if (transform) {
        // layer is guaranteed to be non-NULL because of getLayerTransform
        LayerAndroid* layer = m_baseLayer->findById(layerId);
        IntRect rect = layer->visibleContentArea();
        rect = transform->mapRect(rect);
        isVisible = rect.contains(contentX, contentY);
    }
    return isVisible;
}

private: // local state for WebView
    bool m_isDrawingPaused;
    // private to getFrameCache(); other functions operate in a different thread
    WebViewCore* m_viewImpl;
    int m_generation; // associate unique ID with sent kit focus to match with ui
    // Corresponds to the same-named boolean on the java side.
    bool m_heightCanMeasure;
    int m_lastDx;
    SkMSec m_lastDxTime;
    DrawExtra* m_extras[DRAW_EXTRAS_SIZE];
    BaseLayerAndroid* m_baseLayer;
    Functor* m_glDrawFunctor;
#if USE(ACCELERATED_COMPOSITING)
    GLWebViewState* m_glWebViewState;
#endif
    SkRect m_visibleContentRect;
    bool m_isHighEndGfx;
}; // end of WebView class


/**
 * This class holds a function pointer and parameters for calling drawGL into a specific
 * viewport. The pointer to the Functor will be put on a framework display list to be called
 * when the display list is replayed.
 */
class GLDrawFunctor : Functor {
    public:
    GLDrawFunctor(WebView* _wvInstance,
            int (WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
                    WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint, bool),
            WebCore::IntRect _invScreenRect, float _scale, int _extras) {
        wvInstance = _wvInstance;
        funcPtr = _funcPtr;
        invScreenRect = _invScreenRect;
        scale = _scale;
        extras = _extras;
    };

    status_t operator()(int messageId, void* data) {
        TRACE_METHOD();
        bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw);
        if (shouldDraw)
            wvInstance->updateRectsForGL();

        if (invScreenRect.isEmpty()) {
            // NOOP operation if viewport is empty
            return 0;
        }

        WebCore::IntRect inval;
        int titlebarHeight = screenRect.height() - invScreenRect.height();

        uirenderer::DrawGlInfo* info = reinterpret_cast<uirenderer::DrawGlInfo*>(data);
        WebCore::IntRect screenClip(info->clipLeft, info->clipTop,
                                    info->clipRight - info->clipLeft,
                                    info->clipBottom - info->clipTop);

        WebCore::IntRect localInvScreenRect = invScreenRect;
        if (info->isLayer) {
            // When webview is on a layer, we need to use the viewport relative
            // to the FBO, rather than the screen(which will use invScreenRect).
            localInvScreenRect.setX(screenClip.x());
            localInvScreenRect.setY(info->height - screenClip.y() - screenClip.height());
        }
        // Send the necessary info to the shader.
        TilesManager::instance()->shader()->setGLDrawInfo(info);

        int returnFlags = (*wvInstance.*funcPtr)(localInvScreenRect, &inval, screenRect,
                titlebarHeight, screenClip, scale, extras, shouldDraw);
        if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) {
            IntRect finalInval;
            if (inval.isEmpty())
                finalInval = screenRect;
            else {
                finalInval.setX(screenRect.x() + inval.x());
                finalInval.setY(screenRect.y() + titlebarHeight + inval.y());
                finalInval.setWidth(inval.width());
                finalInval.setHeight(inval.height());
            }
            info->dirtyLeft = finalInval.x();
            info->dirtyTop = finalInval.y();
            info->dirtyRight = finalInval.maxX();
            info->dirtyBottom = finalInval.maxY();
        }
        // return 1 if invalidation needed, 2 to request non-drawing functor callback, 0 otherwise
        ALOGV("returnFlags are %d, shouldDraw %d", returnFlags, shouldDraw);
        return returnFlags;
    }
    void updateScreenRect(WebCore::IntRect& _screenRect) {
        screenRect = _screenRect;
    }
    void updateInvScreenRect(WebCore::IntRect& _invScreenRect) {
        invScreenRect = _invScreenRect;
    }
    void updateScale(float _scale) {
        scale = _scale;
    }
    void updateExtras(jint _extras) {
        extras = _extras;
    }
    private:
    WebView* wvInstance;
    int (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*,
            WebCore::IntRect&, int, WebCore::IntRect&, float, int, bool);
    WebCore::IntRect invScreenRect;
    WebCore::IntRect screenRect;
    jfloat scale;
    jint extras;
};

/*
 * Native JNI methods
 */

static void nativeCreate(JNIEnv *env, jobject obj, int viewImpl,
                         jstring drawableDir, jboolean isHighEndGfx)
{
    WTF::String dir = jstringToWtfString(env, drawableDir);
    new WebView(env, obj, viewImpl, dir, isHighEndGfx);
    // NEED THIS OR SOMETHING LIKE IT!
    //Release(obj);
}

static WebCore::IntRect jrect_to_webrect(JNIEnv* env, jobject obj)
{
    if (obj) {
        int L, T, R, B;
        GraphicsJNI::get_jrect(env, obj, &L, &T, &R, &B);
        return WebCore::IntRect(L, T, R - L, B - T);
    } else
        return WebCore::IntRect();
}

static SkRect jrectf_to_rect(JNIEnv* env, jobject obj)
{
    SkRect rect = SkRect::MakeEmpty();
    if (obj)
        GraphicsJNI::jrectf_to_rect(env, obj, &rect);
    return rect;
}

static void nativeDraw(JNIEnv *env, jobject obj, jobject canv,
        jobject visible, jint color,
        jint extras) {
    SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
    WebView* webView = GET_NATIVE_VIEW(env, obj);
    SkRect visibleContentRect = jrectf_to_rect(env, visible);
    webView->setVisibleContentRect(visibleContentRect);
    webView->draw(canvas, color, static_cast<WebView::DrawExtras>(extras));
}

static jint nativeCreateDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView,
                                       jobject jinvscreenrect, jobject jscreenrect,
                                       jobject jvisiblecontentrect,
                                       jfloat scale, jint extras) {
    WebCore::IntRect invScreenRect = jrect_to_webrect(env, jinvscreenrect);
    WebView *wvInstance = reinterpret_cast<WebView*>(nativeView);
    SkRect visibleContentRect = jrectf_to_rect(env, jvisiblecontentrect);
    wvInstance->setVisibleContentRect(visibleContentRect);

    GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor();
    if (!functor) {
        functor = new GLDrawFunctor(wvInstance, &android::WebView::drawGL,
                                    invScreenRect, scale, extras);
        wvInstance->setFunctor((Functor*) functor);
    } else {
        functor->updateInvScreenRect(invScreenRect);
        functor->updateScale(scale);
        functor->updateExtras(extras);
    }

    WebCore::IntRect rect = jrect_to_webrect(env, jscreenrect);
    functor->updateScreenRect(rect);

    return (jint)functor;
}

static jint nativeGetDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView) {
    WebView *wvInstance = reinterpret_cast<WebView*>(nativeView);
    if (!wvInstance)
        return 0;

    return (jint) wvInstance->getFunctor();
}

static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jint nativeView,
                                       jobject jinvscreenrect, jobject jscreenrect,
                                       jobject jvisiblecontentrect, jfloat scale) {
    WebView *wvInstance = reinterpret_cast<WebView*>(nativeView);
    if (wvInstance) {
        GLDrawFunctor* functor = (GLDrawFunctor*) wvInstance->getFunctor();
        if (functor) {
            WebCore::IntRect invScreenRect = jrect_to_webrect(env, jinvscreenrect);
            functor->updateInvScreenRect(invScreenRect);

            SkRect visibleContentRect = jrectf_to_rect(env, jvisiblecontentrect);
            wvInstance->setVisibleContentRect(visibleContentRect);

            WebCore::IntRect screenRect = jrect_to_webrect(env, jscreenrect);
            functor->updateScreenRect(screenRect);

            functor->updateScale(scale);
        }
    }
}

static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint nativeView)
{
    // only call in software rendering, initialize and evaluate animations
#if USE(ACCELERATED_COMPOSITING)
    BaseLayerAndroid* baseLayer = reinterpret_cast<WebView*>(nativeView)->getBaseLayer();
    if (baseLayer) {
        baseLayer->initAnimations();
        return baseLayer->evaluateAnimations();
    }
#endif
    return false;
}

static bool nativeSetBaseLayer(JNIEnv *env, jobject obj, jint nativeView, jint layer,
                               jboolean showVisualIndicator,
                               jboolean isPictureAfterFirstLayout,
                               jint scrollingLayer)
{
    BaseLayerAndroid* layerImpl = reinterpret_cast<BaseLayerAndroid*>(layer);
    return reinterpret_cast<WebView*>(nativeView)->setBaseLayer(layerImpl, showVisualIndicator,
                                                                isPictureAfterFirstLayout,
                                                                scrollingLayer);
}

static BaseLayerAndroid* nativeGetBaseLayer(JNIEnv *env, jobject obj, jint nativeView)
{
    return reinterpret_cast<WebView*>(nativeView)->getBaseLayer();
}

static void nativeCopyBaseContentToPicture(JNIEnv *env, jobject obj, jobject pict)
{
    SkPicture* picture = GraphicsJNI::getNativePicture(env, pict);
    GET_NATIVE_VIEW(env, obj)->copyBaseContentToPicture(picture);
}

static jboolean nativeDumpLayerContentToPicture(JNIEnv *env, jobject obj, jint instance,
                                                jstring jclassName, jint layerId, jobject pict)
{
    bool success = false;
    SkPicture* picture = GraphicsJNI::getNativePicture(env, pict);
    std::string classname = jstringToStdString(env, jclassName);
    BaseLayerAndroid* baseLayer = reinterpret_cast<WebView*>(instance)->getBaseLayer();
    LayerAndroid* layer = baseLayer->findById(layerId);
    SkSafeRef(layer);
    if (layer && layer->subclassName() == classname) {
        LayerContent* content = layer->content();
        if (content) {
            SkCanvas* canvas = picture->beginRecording(content->width(), content->height());
            content->draw(canvas);
            picture->endRecording();
            success = true;
        }
    }
    SkSafeUnref(layer);
    return success;
}

static bool nativeHasContent(JNIEnv *env, jobject obj)
{
    return GET_NATIVE_VIEW(env, obj)->hasContent();
}

static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure)
{
    WebView* view = GET_NATIVE_VIEW(env, obj);
    ALOG_ASSERT(view, "view not set in nativeSetHeightCanMeasure");
    view->setHeightCanMeasure(measure);
}

static void nativeDestroy(JNIEnv *env, jobject obj, jint ptr)
{
    WebView* view = reinterpret_cast<WebView*>(ptr);
    ALOGD("nativeDestroy view: %p", view);
    ALOG_ASSERT(view, "view not set in nativeDestroy");
    delete view;
}

static void nativeStopGL(JNIEnv *env, jobject obj, jint ptr)
{
    if (ptr)
        reinterpret_cast<WebView*>(ptr)->stopGL();
}

static jobject nativeGetSelection(JNIEnv *env, jobject obj)
{
    WebView* view = GET_NATIVE_VIEW(env, obj);
    ALOG_ASSERT(view, "view not set in %s", __FUNCTION__);
    String selection = view->getSelection();
    return wtfStringToJstring(env, selection);
}

static void nativeDiscardAllTextures(JNIEnv *env, jobject obj)
{
    //discard all textures for debugging/test purposes, but not gl backing memory
    bool allTextures = true, deleteGLTextures = false;
    TilesManager::instance()->discardTextures(allTextures, deleteGLTextures);
}

static void nativeTileProfilingStart(JNIEnv *env, jobject obj)
{
    TilesManager::instance()->getProfiler()->start();
}

static float nativeTileProfilingStop(JNIEnv *env, jobject obj)
{
    return TilesManager::instance()->getProfiler()->stop();
}

static void nativeTileProfilingClear(JNIEnv *env, jobject obj)
{
    TilesManager::instance()->getProfiler()->clear();
}

static int nativeTileProfilingNumFrames(JNIEnv *env, jobject obj)
{
    return TilesManager::instance()->getProfiler()->numFrames();
}

static int nativeTileProfilingNumTilesInFrame(JNIEnv *env, jobject obj, int frame)
{
    return TilesManager::instance()->getProfiler()->numTilesInFrame(frame);
}

static int nativeTileProfilingGetInt(JNIEnv *env, jobject obj, int frame, int tile, jstring jkey)
{
    WTF::String key = jstringToWtfString(env, jkey);
    TileProfileRecord* record = TilesManager::instance()->getProfiler()->getTile(frame, tile);

    if (key == "left")
        return record->left;
    if (key == "top")
        return record->top;
    if (key == "right")
        return record->right;
    if (key == "bottom")
        return record->bottom;
    if (key == "level")
        return record->level;
    if (key == "isReady")
        return record->isReady ? 1 : 0;
    return -1;
}

static float nativeTileProfilingGetFloat(JNIEnv *env, jobject obj, int frame, int tile, jstring jkey)
{
    TileProfileRecord* record = TilesManager::instance()->getProfiler()->getTile(frame, tile);
    return record->scale;
}

#ifdef ANDROID_DUMP_DISPLAY_TREE
static void dumpToFile(const char text[], void* file) {
    fwrite(text, 1, strlen(text), reinterpret_cast<FILE*>(file));
    fwrite("\n", 1, 1, reinterpret_cast<FILE*>(file));
}
#endif

// Return true to view invalidate WebView
static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jvalue)
{
    WTF::String key = jstringToWtfString(env, jkey);
    WTF::String value = jstringToWtfString(env, jvalue);
    if (key == "inverted") {
        bool shouldInvert = (value == "true");
        TilesManager::instance()->setInvertedScreen(shouldInvert);
        return true;
    }
    else if (key == "inverted_contrast") {
        float contrast = value.toFloat();
        TilesManager::instance()->setInvertedScreenContrast(contrast);
        return true;
    }
    else if (key == "enable_cpu_upload_path") {
        TilesManager::instance()->transferQueue()->setTextureUploadType(
            value == "true" ? CpuUpload : GpuUpload);
    }
    else if (key == "use_minimal_memory") {
        TilesManager::instance()->setUseMinimalMemory(value == "true");
    }
    else if (key == "use_double_buffering") {
        TilesManager::instance()->setUseDoubleBuffering(value == "true");
    }
    else if (key == "tree_updates") {
        TilesManager::instance()->clearContentUpdates();
    }
    return false;
}

static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring jkey)
{
    WTF::String key = jstringToWtfString(env, jkey);
    if (key == "tree_updates") {
        int updates = TilesManager::instance()->getContentUpdates();
        WTF::String wtfUpdates = WTF::String::number(updates);
        return wtfStringToJstring(env, wtfUpdates);
    }
    return 0;
}

static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level)
{
    if (TilesManager::hardwareAccelerationEnabled()) {
        // When we got TRIM_MEMORY_MODERATE or TRIM_MEMORY_COMPLETE, we should
        // make sure the transfer queue is empty and then abandon the Surface
        // Texture to avoid ANR b/c framework may destroy the EGL context.
        // Refer to WindowManagerImpl.java for conditions we followed.
        TilesManager* tilesManager = TilesManager::instance();
        if ((level >= TRIM_MEMORY_MODERATE
            && !tilesManager->highEndGfx())
            || level >= TRIM_MEMORY_COMPLETE) {
            ALOGD("OnTrimMemory with EGL Context %p", eglGetCurrentContext());
            tilesManager->cleanupGLResources();
        }

        bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN), glTextures = true;
        tilesManager->discardTextures(freeAllTextures, glTextures);
    }
}

static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
{
#if defined(ANDROID_DUMP_DISPLAY_TREE) && defined(SK_DEVELOPER)
    WebView* view = GET_NATIVE_VIEW(env, jwebview);
    ALOG_ASSERT(view, "view not set in %s", __FUNCTION__);

    if (view && view->getWebViewCore()) {
        FILE* file = fopen(DISPLAY_TREE_LOG_FILE, "w");
        if (file) {
            SkFormatDumper dumper(dumpToFile, file);
            // dump the URL
            if (jurl) {
                const char* str = env->GetStringUTFChars(jurl, 0);
                SkDebugf("Dumping %s to %s\n", str, DISPLAY_TREE_LOG_FILE);
                dumpToFile(str, file);
                env->ReleaseStringUTFChars(jurl, str);
            }
            // now dump the display tree
            SkDumpCanvas canvas(&dumper);
            // this will playback the picture into the canvas, which will
            // spew its contents to the dumper
            view->draw(&canvas, 0, WebView::DrawExtrasNone);
            // we're done with the file now
            fwrite("\n", 1, 1, file);
            fclose(file);
        }
#if USE(ACCELERATED_COMPOSITING)
        const LayerAndroid* baseLayer = view->getBaseLayer();
        if (baseLayer) {
          FILE* file = fopen(LAYERS_TREE_LOG_FILE,"w");
          if (file) {
              WebCore::FileLayerDumper dumper(file);
              baseLayer->dumpLayers(&dumper);
              fclose(file);
          }
        }
#endif
    }
#endif
}

static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint nativeView,
    jint x, jint y, jobject rect, jobject bounds)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    ALOG_ASSERT(webview, "webview not set in %s", __FUNCTION__);
    SkIRect nativeRect, nativeBounds;
    int id = webview->scrollableLayer(x, y, &nativeRect, &nativeBounds);
    if (rect)
        GraphicsJNI::irect_to_jrect(nativeRect, env, rect);
    if (bounds)
        GraphicsJNI::irect_to_jrect(nativeBounds, env, bounds);
    return id;
}

static bool nativeScrollLayer(JNIEnv* env, jobject obj,
    jint nativeView, jint layerId, jint x, jint y)
{
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    webview->scrollLayer(layerId, x, y);

    //TODO: the below only needed for the SW rendering path
    LayerAndroid* baseLayer = webview->getBaseLayer();
    if (!baseLayer)
        return false;
    LayerAndroid* layer = baseLayer->findById(layerId);
    if (!layer || !layer->contentIsScrollable())
        return false;
    return static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
#endif
    return false;
}

static void nativeSetIsScrolling(JNIEnv* env, jobject jwebview, jboolean isScrolling)
{
    // TODO: Pass in the native pointer instead
    WebView* view = GET_NATIVE_VIEW(env, jwebview);
    if (view)
        view->setIsScrolling(isScrolling);
}

static void nativeUseHardwareAccelSkia(JNIEnv*, jobject, jboolean enabled)
{
    BaseRenderer::setCurrentRendererType(enabled ? BaseRenderer::Ganesh : BaseRenderer::Raster);
}

static int nativeGetBackgroundColor(JNIEnv* env, jobject obj, jint nativeView)
{
    WebView* view = reinterpret_cast<WebView*>(nativeView);
    BaseLayerAndroid* baseLayer = view->getBaseLayer();
    if (baseLayer) {
        WebCore::Color color = baseLayer->getBackgroundColor();
        if (color.isValid())
            return SkColorSetARGB(color.alpha(), color.red(),
                                  color.green(), color.blue());
    }
    return SK_ColorWHITE;
}

static void nativeSetPauseDrawing(JNIEnv *env, jobject obj, jint nativeView,
                                      jboolean pause)
{
    reinterpret_cast<WebView*>(nativeView)->setDrawingPaused(pause);
}

static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView,
                                   jint selectionPtr)
{
    SelectText* selection = reinterpret_cast<SelectText*>(selectionPtr);
    reinterpret_cast<WebView*>(nativeView)->setTextSelection(selection);
}

static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView,
                                     jint handleIndex, jobject cursorPoint,
                                     jobject textQuad)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    SkIPoint nativePoint;
    FloatQuad nativeTextQuad;
    int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex,
            nativePoint, nativeTextQuad);
    if (cursorPoint)
        GraphicsJNI::ipoint_to_jpoint(nativePoint, env, cursorPoint);
    if (textQuad)
        webview->floatQuadToQuadF(env, nativeTextQuad, textQuad);
    return layerId;
}

static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView,
        jint layerId, jobject rect)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    SkIRect nativeRect;
    GraphicsJNI::jrect_to_irect(env, rect, &nativeRect);
    webview->mapLayerRect(layerId, nativeRect);
    GraphicsJNI::irect_to_jrect(nativeRect, env, rect);
}

static jint nativeSetHwAccelerated(JNIEnv *env, jobject obj, jint nativeView,
        jboolean hwAccelerated)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    return webview->setHwAccelerated(hwAccelerated);
}

static void nativeFindMaxVisibleRect(JNIEnv *env, jobject obj, jint nativeView,
        jint movingLayerId, jobject visibleContentRect)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    SkIRect nativeRect;
    GraphicsJNI::jrect_to_irect(env, visibleContentRect, &nativeRect);
    webview->findMaxVisibleRect(movingLayerId, nativeRect);
    GraphicsJNI::irect_to_jrect(nativeRect, env, visibleContentRect);
}

static bool nativeIsHandleLeft(JNIEnv *env, jobject obj, jint nativeView,
        jint handleId)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    return webview->isHandleLeft(static_cast<SelectText::HandleId>(handleId));
}

static bool nativeIsPointVisible(JNIEnv *env, jobject obj, jint nativeView,
        jint layerId, jint contentX, jint contentY)
{
    WebView* webview = reinterpret_cast<WebView*>(nativeView);
    return webview->isPointVisible(layerId, contentX, contentY);
}

/*
 * JNI registration
 */
static JNINativeMethod gJavaWebViewMethods[] = {
    { "nativeCreate", "(ILjava/lang/String;Z)V",
        (void*) nativeCreate },
    { "nativeDestroy", "(I)V",
        (void*) nativeDestroy },
    { "nativeDraw", "(Landroid/graphics/Canvas;Landroid/graphics/RectF;II)V",
        (void*) nativeDraw },
    { "nativeCreateDrawGLFunction", "(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;FI)I",
        (void*) nativeCreateDrawGLFunction },
    { "nativeGetDrawGLFunction", "(I)I",
        (void*) nativeGetDrawGLFunction },
    { "nativeUpdateDrawGLFunction", "(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/RectF;F)V",
        (void*) nativeUpdateDrawGLFunction },
    { "nativeDumpDisplayTree", "(Ljava/lang/String;)V",
        (void*) nativeDumpDisplayTree },
    { "nativeEvaluateLayersAnimations", "(I)Z",
        (void*) nativeEvaluateLayersAnimations },
    { "nativeGetSelection", "()Ljava/lang/String;",
        (void*) nativeGetSelection },
    { "nativeSetHeightCanMeasure", "(Z)V",
        (void*) nativeSetHeightCanMeasure },
    { "nativeSetBaseLayer", "(IIZZI)Z",
        (void*) nativeSetBaseLayer },
    { "nativeGetBaseLayer", "(I)I",
        (void*) nativeGetBaseLayer },
    { "nativeCopyBaseContentToPicture", "(Landroid/graphics/Picture;)V",
        (void*) nativeCopyBaseContentToPicture },
    { "nativeDumpLayerContentToPicture", "(ILjava/lang/String;ILandroid/graphics/Picture;)Z",
        (void*) nativeDumpLayerContentToPicture },
    { "nativeHasContent", "()Z",
        (void*) nativeHasContent },
    { "nativeDiscardAllTextures", "()V",
        (void*) nativeDiscardAllTextures },
    { "nativeTileProfilingStart", "()V",
        (void*) nativeTileProfilingStart },
    { "nativeTileProfilingStop", "()F",
        (void*) nativeTileProfilingStop },
    { "nativeTileProfilingClear", "()V",
        (void*) nativeTileProfilingClear },
    { "nativeTileProfilingNumFrames", "()I",
        (void*) nativeTileProfilingNumFrames },
    { "nativeTileProfilingNumTilesInFrame", "(I)I",
        (void*) nativeTileProfilingNumTilesInFrame },
    { "nativeTileProfilingGetInt", "(IILjava/lang/String;)I",
        (void*) nativeTileProfilingGetInt },
    { "nativeTileProfilingGetFloat", "(IILjava/lang/String;)F",
        (void*) nativeTileProfilingGetFloat },
    { "nativeStopGL", "(I)V",
        (void*) nativeStopGL },
    { "nativeScrollableLayer", "(IIILandroid/graphics/Rect;Landroid/graphics/Rect;)I",
        (void*) nativeScrollableLayer },
    { "nativeScrollLayer", "(IIII)Z",
        (void*) nativeScrollLayer },
    { "nativeSetIsScrolling", "(Z)V",
        (void*) nativeSetIsScrolling },
    { "nativeUseHardwareAccelSkia", "(Z)V",
        (void*) nativeUseHardwareAccelSkia },
    { "nativeGetBackgroundColor", "(I)I",
        (void*) nativeGetBackgroundColor },
    { "nativeSetProperty", "(Ljava/lang/String;Ljava/lang/String;)Z",
        (void*) nativeSetProperty },
    { "nativeGetProperty", "(Ljava/lang/String;)Ljava/lang/String;",
        (void*) nativeGetProperty },
    { "nativeOnTrimMemory", "(I)V",
        (void*) nativeOnTrimMemory },
    { "nativeSetPauseDrawing", "(IZ)V",
        (void*) nativeSetPauseDrawing },
    { "nativeSetTextSelection", "(II)V",
        (void*) nativeSetTextSelection },
    { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I",
        (void*) nativeGetHandleLayerId },
    { "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V",
        (void*) nativeMapLayerRect },
    { "nativeSetHwAccelerated", "(IZ)I",
        (void*) nativeSetHwAccelerated },
    { "nativeFindMaxVisibleRect", "(IILandroid/graphics/Rect;)V",
        (void*) nativeFindMaxVisibleRect },
    { "nativeIsHandleLeft", "(II)Z",
        (void*) nativeIsHandleLeft },
    { "nativeIsPointVisible", "(IIII)Z",
        (void*) nativeIsPointVisible },
};

int registerWebView(JNIEnv* env)
{
    jclass clazz = env->FindClass("android/webkit/WebViewClassic");
    ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebViewClassic");
    gWebViewField = env->GetFieldID(clazz, "mNativeClass", "I");
    ALOG_ASSERT(gWebViewField, "Unable to find android/webkit/WebViewClassic.mNativeClass");
    env->DeleteLocalRef(clazz);

    return jniRegisterNativeMethods(env, "android/webkit/WebViewClassic", gJavaWebViewMethods, NELEM(gJavaWebViewMethods));
}

} // namespace android
