/*
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
 * Copyright (C) 2008 Collabora Ltd. All rights reserved.
 * Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
 * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. 
 */

#include "config.h"
#include "PluginView.h"

#include "DocumentLoader.h"
#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameView.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
#include "HostWindow.h"
#include "JSDOMBinding.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
#include "NPCallbacksBlackBerry.h"
#include "NotImplemented.h"
#include "Page.h"
#include "PlatformContextSkia.h"
#include "PlatformKeyboardEvent.h"
#include "PluginDebug.h"
#include "PluginMainThreadScheduler.h"
#include "PluginPackage.h"
#include "PluginViewPrivateBlackBerry.h"
#include "RenderLayer.h"
#include "Settings.h"
#include "TouchEvent.h"
#include "TouchList.h"
#include "WheelEvent.h"
#include "npruntime_impl.h"
#include "runtime_root.h"

#if USE(ACCELERATED_COMPOSITING)
#include "Chrome.h"
#include "ChromeClient.h"
#include "PluginLayerWebKitThread.h"
#endif

#include <BlackBerryPlatformGraphics.h>
#include <BlackBerryPlatformIntRectRegion.h>
#include <BlackBerryPlatformWindow.h>

#include <runtime/JSLock.h>
#include <runtime/JSValue.h>
#include <sys/keycodes.h>
#include <vector>

const unsigned UninitializedCoordinate = 0xffffffff;

namespace WebCore {

template<class T> static NPRect toNPRect(const T& rect)
{
    NPRect npRect;
    npRect.top = rect.y();
    npRect.left = rect.x();
    npRect.bottom = rect.y() + rect.height();
    npRect.right = rect.x() + rect.width();
    return npRect;
}

using JSC::ExecState;
using JSC::Interpreter;
using JSC::JSLock;
using JSC::JSObject;

using namespace std;
using namespace WTF;
using namespace HTMLNames;

void PluginView::updatePluginWidget()
{
    if (!parent() || !m_private)
        return;

    ASSERT(parent()->isFrameView());
    FrameView* frameView = static_cast<FrameView*>(parent());

    IntRect oldWindowRect = m_windowRect;
    IntRect oldClipRect = m_clipRect;

    m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());

    // Map rect to content coordinate space of main frame.
    m_windowRect.move(root()->scrollOffset());

    m_clipRect = calculateClipRect();

    // Notify the plugin if it may or may not be on/offscreen.
    handleScrollEvent();

    bool zoomFactorChanged = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->zoomFactor
        != frameView->hostWindow()->platformPageClient()->currentZoomFactor();

    if (!zoomFactorChanged && m_windowRect == oldWindowRect && m_clipRect == oldClipRect)
        return;

    // Do not call setNPWindowIfNeeded immediately, will be called on paint().
    m_private->m_hasPendingGeometryChange = true;

    // (i) In order to move/resize the plugin window at the same time as the
    // rest of frame during e.g. scrolling, we set the window geometry
    // in the paint() function, but as paint() isn't called when the
    // plugin window is outside the frame which can be caused by a
    // scroll, we need to move/resize immediately.
    // (ii) If we are running layout tests from DRT, paint() won't ever get called
    // so we need to call setNPWindowIfNeeded() if window geometry has changed.
    if (m_clipRect.isEmpty() || (platformPluginWidget() && (m_windowRect != oldWindowRect || m_clipRect != oldClipRect || zoomFactorChanged)))
        setNPWindowIfNeeded();

    // Make sure we get repainted afterwards. This is necessary for downward
    // scrolling to move the plugin widget properly.
    invalidate();
}

void PluginView::setFocus(bool focused)
{
    if (!m_private || m_private->m_isFocused == focused)
        return;

    ASSERT(platformPluginWidget() == platformWidget());
    Widget::setFocus(focused);

    if (focused)
        handleFocusInEvent();
    else
        handleFocusOutEvent();
}

void PluginView::show()
{
    setSelfVisible(true);
    Widget::show();
    updatePluginWidget();
}

void PluginView::hide()
{
    setSelfVisible(false);
    Widget::hide();
    updatePluginWidget();
}

void PluginView::updateBuffer(const IntRect& bufferRect)
{
    if (!m_private)
        return;

    // Update the zoom factor here, it happens right before setNPWindowIfNeeded
    // ensuring that the plugin has every opportunity to get the zoom factor before
    // it paints anything.
    if (FrameView* frameView = static_cast<FrameView*>(parent()))
        m_private->setZoomFactor(frameView->hostWindow()->platformPageClient()->currentZoomFactor());

    setNPWindowIfNeeded();

    // Build and dispatch an event to the plugin to notify it we are about to draw whatever
    // is in the front buffer. This is it's opportunity to do a swap.
    IntRect exposedRect(bufferRect);
    exposedRect.intersect(IntRect(IntPoint(0, 0), frameRect().size()));

    // Only ask the plugin to draw if the exposed rect was explicitly invalidated
    // by the plugin.
    BlackBerry::Platform::IntRectRegion exposedRegion = BlackBerry::Platform::IntRectRegion::intersectRegions(m_private->m_invalidateRegion, BlackBerry::Platform::IntRect(exposedRect));
    if (!exposedRegion.isEmpty()) {
        m_private->m_invalidateRegion = BlackBerry::Platform::IntRectRegion::subtractRegions(m_private->m_invalidateRegion, exposedRegion);
        std::vector<BlackBerry::Platform::IntRect> exposedRects = exposedRegion.rects();
        for (unsigned i = 0; i < exposedRects.size(); ++i) {
            NPDrawEvent draw;
            draw.pluginRect = toNPRect(m_windowRect);
            draw.clipRect = toNPRect(m_clipRect);
            draw.drawRect = (NPRect*)alloca(sizeof(NPRect));
            draw.drawRectCount = 1;
            *draw.drawRect = toNPRect(exposedRects.at(i));
            draw.zoomFactor = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->zoomFactor;

            NPEvent npEvent;
            npEvent.type = NP_DrawEvent;
            npEvent.data = &draw;

            // FIXME: Return early if this fails? Or just repaint?
            dispatchNPEvent(npEvent);
        }
    }
}

void PluginView::paint(GraphicsContext* context, const IntRect& rect)
{
    if (!m_private || !m_isStarted) {
        paintMissingPluginIcon(context, rect);
        return;
    }

    // Update the zoom factor here, it happens right before setNPWindowIfNeeded
    // ensuring that the plugin has every opportunity to get the zoom factor before
    // it paints anything.
    if (FrameView* frameView = static_cast<FrameView*>(parent()))
        m_private->setZoomFactor(frameView->hostWindow()->platformPageClient()->currentZoomFactor());

    if (context->paintingDisabled())
        return;

    setNPWindowIfNeeded();

#if USE(ACCELERATED_COMPOSITING)
    if (m_private->m_platformLayer)
        return;
#endif

    // Build and dispatch an event to the plugin to notify it we are about to draw whatever
    // is in the front buffer. This is it's opportunity to do a swap.
    IntRect rectClip(rect);
    rectClip.intersect(frameRect());

    IntRect exposedRect(rectClip);
    exposedRect.move(-frameRect().x(), -frameRect().y());

    updateBuffer(exposedRect);

    PthreadReadLocker frontLock(&m_private->m_frontBufferRwLock);

    BlackBerry::Platform::Graphics::Buffer* frontBuffer =
        m_private->m_pluginBuffers[m_private->m_pluginFrontBuffer];

    // Don't paint anything if there is no buffer.
    if (!frontBuffer)
        return;

    const BlackBerry::Platform::Graphics::BackingImage* backingImage =
        BlackBerry::Platform::Graphics::lockBufferBackingImage(frontBuffer,
                                                            BlackBerry::Platform::Graphics::ReadAccess);
    if (!backingImage)
        return;

    // Draw the changed buffer contents to the screen.
    context->save();

    const SkBitmap& pluginImage = *backingImage;
    PlatformGraphicsContext* graphics = context->platformContext();
    ASSERT(graphics);
    SkCanvas* canvas = graphics->canvas();

    // Source rectangle we will draw to the screen.
    SkIRect skSrcRect;
    skSrcRect.set(exposedRect.x(), exposedRect.y(),
                  exposedRect.x() + exposedRect.width(),
                  exposedRect.y() + exposedRect.height());

    // Prepare the hole punch rectangle.
    SkIRect unclippedHolePunchRect;
    unclippedHolePunchRect.set(m_private->m_holePunchRect.x(),
                               m_private->m_holePunchRect.y(),
                               m_private->m_holePunchRect.x() + m_private->m_holePunchRect.width(),
                               m_private->m_holePunchRect.y() + m_private->m_holePunchRect.height());

    // holePunchRect is clipped.
    SkIRect holePunchRect;

    // All source rectangles are scaled by the zoom factor because the source bitmap may be a
    // higher resolution than the 1:1 page. This allows the flash player to scale the content
    // it is drawing to match the scale of the page.
    double zoomFactorH = static_cast<double>(m_private->m_pluginBufferSize.width()) / static_cast<double>(frameRect().width());
    double zoomFactorW = static_cast<double>(m_private->m_pluginBufferSize.height()) / static_cast<double>(frameRect().height());
    double zoomFactor = (zoomFactorH + zoomFactorW) / 2.0;

    // This method draws a hole if specified.
    if (!m_private->m_holePunchRect.isEmpty()
        && holePunchRect.intersect(unclippedHolePunchRect, skSrcRect)) {

        // Draw the top chunk if needed.
        if (holePunchRect.fTop > skSrcRect.fTop) {
            SkIRect srcRect;
            srcRect.set(skSrcRect.fLeft * zoomFactor, skSrcRect.fTop * zoomFactor,
                        skSrcRect.fRight * zoomFactor, holePunchRect.fTop * zoomFactor);

            SkRect dstRect;
            dstRect.set(skSrcRect.fLeft, skSrcRect.fTop,
                        skSrcRect.fRight, holePunchRect.fTop);
            dstRect.offset(frameRect().x(), frameRect().y());

            canvas->drawBitmapRect(pluginImage, &srcRect, dstRect);
        }

        // Draw the left chunk if needed.
        if (holePunchRect.fLeft > skSrcRect.fLeft) {
            SkIRect srcRect;
            srcRect.set(skSrcRect.fLeft * zoomFactor, holePunchRect.fTop * zoomFactor,
                        holePunchRect.fLeft * zoomFactor, holePunchRect.fBottom * zoomFactor);

            SkRect dstRect;
            dstRect.set(skSrcRect.fLeft, holePunchRect.fTop,
                        holePunchRect.fLeft, holePunchRect.fBottom);
            dstRect.offset(frameRect().x(), frameRect().y());

            canvas->drawBitmapRect(pluginImage, &srcRect, dstRect);
        }

        // Draw the hole chunk.
        {
            SkPaint paint;
            paint.setXfermodeMode(SkXfermode::kSrc_Mode);

            SkIRect srcRect;
            srcRect.set(holePunchRect.fLeft * zoomFactor, holePunchRect.fTop * zoomFactor,
                        holePunchRect.fRight * zoomFactor, holePunchRect.fBottom * zoomFactor);

            SkRect dstRect;
            dstRect.set(holePunchRect.fLeft, holePunchRect.fTop,
                        holePunchRect.fRight, holePunchRect.fBottom);
            dstRect.offset(frameRect().x(), frameRect().y());

            canvas->drawBitmapRect(pluginImage, &srcRect, dstRect, &paint);
        }

        // Draw the right chunk if needed.
        if (holePunchRect.fRight < skSrcRect.fRight) {
            SkIRect srcRect;
            srcRect.set(holePunchRect.fRight * zoomFactor, holePunchRect.fTop * zoomFactor,
                        skSrcRect.fRight * zoomFactor, holePunchRect.fBottom * zoomFactor);

            SkRect dstRect;
            dstRect.set(holePunchRect.fRight, holePunchRect.fTop, skSrcRect.fRight, holePunchRect.fBottom);
            dstRect.offset(frameRect().x(), frameRect().y());

            canvas->drawBitmapRect(pluginImage, &srcRect, dstRect);
        }

        // Draw the bottom chunk if needed.
        if (holePunchRect.fBottom < skSrcRect.fBottom) {
            SkIRect srcRect;
            srcRect.set(skSrcRect.fLeft * zoomFactor, holePunchRect.fBottom * zoomFactor,
                        skSrcRect.fRight * zoomFactor, skSrcRect.fBottom * zoomFactor);

            SkRect dstRect;
            dstRect.set(skSrcRect.fLeft, holePunchRect.fBottom,
                        skSrcRect.fRight, skSrcRect.fBottom);
            dstRect.offset(frameRect().x(), frameRect().y());

            canvas->drawBitmapRect(pluginImage, &srcRect, dstRect);
        }
    } else {
        SkIRect srcRect;
        srcRect.set(skSrcRect.fLeft * zoomFactor, skSrcRect.fTop * zoomFactor,
                    skSrcRect.fRight * zoomFactor, skSrcRect.fBottom * zoomFactor);

        // Calculate the destination rectangle.
        SkRect dstRect;
        dstRect.set(rectClip.x(), rectClip.y(),
                    rectClip.x() + rectClip.width(),
                    rectClip.y() + rectClip.height());

        // Don't punch a hole.
        canvas->drawBitmapRect(pluginImage, &srcRect, dstRect);
    }

    context->restore();

    BlackBerry::Platform::Graphics::releaseBufferBackingImage(frontBuffer);
}


bool PluginView::dispatchFullScreenNPEvent(NPEvent& event)
{
    if (!m_private)
        return false;

    ASSERT(m_private->m_isFullScreen);
    return dispatchNPEvent(event);
}

// FIXME: Unify across ports.
bool PluginView::dispatchNPEvent(NPEvent& event)
{
    if (!m_plugin || !m_plugin->pluginFuncs()->event)
        return false;

    PluginView::setCurrentPluginView(this);
    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
    setCallingPlugin(true);

    bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event);

    setCallingPlugin(false);
    PluginView::setCurrentPluginView(0);

    return accepted;
}

void PluginView::handleKeyboardEvent(KeyboardEvent* event)
{
    NPEvent npEvent;
    NPKeyboardEvent keyEvent;
    const PlatformKeyboardEvent *platformKeyEvent = event->keyEvent();

    keyEvent.modifiers = 0;

    if (platformKeyEvent->shiftKey())
        keyEvent.modifiers |= KEYMOD_SHIFT;

    if (platformKeyEvent->ctrlKey())
        keyEvent.modifiers |= KEYMOD_CTRL;

    if (platformKeyEvent->altKey())
        keyEvent.modifiers |= KEYMOD_ALT;

    if (platformKeyEvent->metaKey())
        keyEvent.modifiers |= KEYMOD_ALTGR;

    keyEvent.cap = platformKeyEvent->unmodifiedCharacter();
    keyEvent.sym = keyEvent.cap;
    keyEvent.scan = 0;
    keyEvent.flags = 0;

    if (platformKeyEvent->type() == PlatformKeyboardEvent::RawKeyDown
        || platformKeyEvent->type() == PlatformKeyboardEvent::KeyDown) {
        keyEvent.flags = KEY_DOWN | KEY_SYM_VALID | KEY_CAP_VALID;
    } else if (platformKeyEvent->type() == PlatformKeyboardEvent::KeyUp)
        keyEvent.flags = KEY_SYM_VALID | KEY_CAP_VALID;

    npEvent.type = NP_KeyEvent;
    npEvent.data = &keyEvent;
    if (dispatchNPEvent(npEvent))
        event->setDefaultHandled();
}

void PluginView::handleWheelEvent(WheelEvent* event)
{
    if (!m_private)
        return;

    if (!m_private->m_isFocused)
        focusPluginElement();

    NPEvent npEvent;
    NPWheelEvent wheelEvent;

    wheelEvent.x = event->offsetX();
    wheelEvent.y = event->offsetY();

    wheelEvent.flags = 0;

    wheelEvent.xDelta = event->rawDeltaX();
    wheelEvent.yDelta = event->rawDeltaY();

    npEvent.type = NP_WheelEvent;
    npEvent.data = &wheelEvent;

    if (dispatchNPEvent(npEvent))
        event->setDefaultHandled();
}

void PluginView::handleTouchEvent(TouchEvent* event)
{
    if (!m_private)
        return;

    if (!m_private->m_isFocused)
        focusPluginElement();

    NPTouchEvent npTouchEvent;

    if (event->isDoubleTap())
        npTouchEvent.type = TOUCH_EVENT_DOUBLETAP;
    else if (event->isTouchHold())
        npTouchEvent.type = TOUCH_EVENT_TOUCHHOLD;
    else if (event->type() == eventNames().touchstartEvent)
        npTouchEvent.type = TOUCH_EVENT_START;
    else if (event->type() == eventNames().touchendEvent)
        npTouchEvent.type = TOUCH_EVENT_END;
    else if (event->type() == eventNames().touchmoveEvent)
        npTouchEvent.type = TOUCH_EVENT_MOVE;
    else if (event->type() == eventNames().touchcancelEvent)
        npTouchEvent.type = TOUCH_EVENT_CANCEL;
    else {
        ASSERT_NOT_REACHED();
        return;
    }

    TouchList* touchList;
    // The touches list is empty if in a touch end event. Use changedTouches instead.
    if (npTouchEvent.type == TOUCH_EVENT_DOUBLETAP || npTouchEvent.type == TOUCH_EVENT_END)
        touchList = event->changedTouches();
    else
        touchList = event->touches();

    npTouchEvent.points = 0;
    npTouchEvent.size = touchList->length();

    OwnArrayPtr<NPTouchPoint> touchPoints;
    if (touchList->length()) {
        touchPoints = adoptArrayPtr(new NPTouchPoint[touchList->length()]);
        npTouchEvent.points = touchPoints.get();
        for (unsigned i = 0; i < touchList->length(); i++) {
            Touch* touchItem = touchList->item(i);
            touchPoints[i].touchId = touchItem->identifier();
            touchPoints[i].clientX = touchItem->pageX() - frameRect().x();
            touchPoints[i].clientY = touchItem->pageY() - frameRect().y();
            touchPoints[i].screenX = touchItem->screenX();
            touchPoints[i].screenY = touchItem->screenY();
            touchPoints[i].pageX = touchItem->pageX();
            touchPoints[i].pageY = touchItem->pageY();

        }
    }

    NPEvent npEvent;
    npEvent.type = NP_TouchEvent;
    npEvent.data = &npTouchEvent;

    if (dispatchNPEvent(npEvent))
        event->setDefaultHandled();
    else if (npTouchEvent.type == TOUCH_EVENT_DOUBLETAP) {
        // Send Touch Up if double tap not consumed
        npTouchEvent.type = TOUCH_EVENT_END;
        npEvent.data = &npTouchEvent;
        if (dispatchNPEvent(npEvent))
            event->setDefaultHandled();
    }
}

void PluginView::handleMouseEvent(MouseEvent* event)
{
    if (!m_private)
        return;

    if (!m_private->m_isFocused)
        focusPluginElement();

    NPEvent npEvent;
    NPMouseEvent mouseEvent;

    mouseEvent.x = event->offsetX();
    mouseEvent.y = event->offsetY();

    if (event->type() == eventNames().mousedownEvent) {
        mouseEvent.type = MOUSE_BUTTON_DOWN;
        parentFrame()->eventHandler()->setCapturingMouseEventsNode(node());
    } else if (event->type() == eventNames().mousemoveEvent)
        mouseEvent.type = MOUSE_MOTION;
    else if (event->type() == eventNames().mouseoutEvent)
        mouseEvent.type = MOUSE_OUTBOUND;
    else if (event->type() == eventNames().mouseoverEvent)
        mouseEvent.type = MOUSE_OVER;
    else if (event->type() == eventNames().mouseupEvent) {
        mouseEvent.type = MOUSE_BUTTON_UP;
        parentFrame()->eventHandler()->setCapturingMouseEventsNode(0);
    } else
        return;

    mouseEvent.button = event->button();
    mouseEvent.flags = 0;

    npEvent.type = NP_MouseEvent;
    npEvent.data = &mouseEvent;

    if (dispatchNPEvent(npEvent))
        event->setDefaultHandled();
}

void PluginView::handleFocusInEvent()
{
    if (!m_private)
        return;

    if (m_private->m_isFocused)
        return;

    m_private->m_isFocused = true;

    NPEvent npEvent;
    npEvent.type = NP_FocusGainedEvent;
    npEvent.data = 0;
    dispatchNPEvent(npEvent);
}

void PluginView::handleFocusOutEvent()
{
    if (!m_private)
        return;

    if (!m_private->m_isFocused)
        return;

    m_private->m_isFocused = false;

    NPEvent npEvent;
    npEvent.type = NP_FocusLostEvent;
    npEvent.data = 0;
    dispatchNPEvent(npEvent);
}

void PluginView::handlePauseEvent()
{
    NPEvent npEvent;
    npEvent.type = NP_PauseEvent;
    npEvent.data = 0;
    dispatchNPEvent(npEvent);
}

void PluginView::handleResumeEvent()
{
    NPEvent npEvent;
    npEvent.type = NP_ResumeEvent;
    npEvent.data = 0;
    dispatchNPEvent(npEvent);
}

void PluginView::handleScrollEvent()
{
    FrameView* frameView = static_cast<FrameView*>(parent());

    // As a special case, if the frameView extent in either dimension is
    // empty, then send an on screen event. This is important for sites like
    // picnik.com which use a hidden iframe (read: width = 0 and height = 0)
    // with an embedded swf to execute some javascript. Unless we send an
    // on screen event the swf will not execute the javascript and the real
    // site will never load.
    bool onScreenEvent = frameView && (!frameView->width() || !frameView->height());

    NPEvent npEvent;
    npEvent.type = m_clipRect.isEmpty() && !onScreenEvent ? NP_OffScreenEvent : NP_OnScreenEvent;
    npEvent.data = 0;
    dispatchNPEvent(npEvent);
}

IntRect PluginView::calculateClipRect() const
{
    FrameView* frameView = static_cast<FrameView*>(parent());
    bool visible = frameView && isVisible();

    if (visible && frameView->width() && frameView->height()) {
        IntSize windowSize = frameView->hostWindow()->platformPageClient()->viewportSize();

        // Get the clipped rectangle for this player within the current frame.
        IntRect visibleContentRect;
        IntRect contentRect = m_element->renderer()->absoluteClippedOverflowRect();
        FloatPoint contentLocal = m_element->renderer()->absoluteToLocal(FloatPoint(contentRect.location()));

        contentRect.setLocation(roundedIntPoint(contentLocal));
        contentRect.move(frameRect().x(), frameRect().y());

        // Clip against any frames that the widget is inside. Note that if the frames are also clipped
        // by a div, that will not be included in this calculation. That is an improvement that still
        // needs to be made.
        const Widget* current = this;
        while (current->parent() && visible) {
            // Determine if it is visible in this scrollview.
            visibleContentRect = current->parent()->visibleContentRect();

            // Special case for the root ScrollView. Its size does not match the actual window size.
            if (current->parent() == root())
                visibleContentRect.setSize(windowSize);

            contentRect.intersect(visibleContentRect);
            visible = !contentRect.isEmpty();

            // Offset to visible coordinates in scrollview widget's coordinate system (except in the case of
            // the top scroll view).
            if (current->parent()->parent())
                contentRect.move(-visibleContentRect.x(), -visibleContentRect.y());

            current = current->parent();

            // Don't include the offset for the root window or we get the wrong coordinates.
            if (current->parent()) {
                // Move content rect into the parent scrollview's coordinates.
                IntRect curFrameRect = current->frameRect();
                contentRect.move(curFrameRect.x(), curFrameRect.y());
            }
        }

        return contentRect;
    }

    return IntRect();
}

void PluginView::handleOnLoadEvent()
{
    if (!m_private)
        return;

    if (m_private->m_sentOnLoad)
        return;

    m_private->m_sentOnLoad = true;

    NPEvent npEvent;
    npEvent.type = NP_OnLoadEvent;
    npEvent.data = 0;

    dispatchNPEvent(npEvent);

    // Send an initial OnScreen/OffScreen event. It must always come after onLoad is sent.
    handleScrollEvent();
}

void PluginView::handleFreeMemoryEvent()
{
    NPEvent npEvent;
    npEvent.type = NP_FreeMemoryEvent;
    npEvent.data = 0;

    dispatchNPEvent(npEvent);
}

void PluginView::handleBackgroundEvent()
{
    NPEvent npEvent;
    npEvent.type = NP_BackgroundEvent;
    npEvent.data = 0;

    dispatchNPEvent(npEvent);
}

void PluginView::handleForegroundEvent()
{
    setNPWindowIfNeeded();

    NPEvent npEvent;
    npEvent.type = NP_ForegroundEvent;
    npEvent.data = 0;

    dispatchNPEvent(npEvent);
}

void PluginView::handleFullScreenAllowedEvent()
{
    if (!m_private)
        return;

    NPEvent npEvent;
    npEvent.type = NP_FullScreenReadyEvent;
    npEvent.data = 0;

    if (FrameView* frameView = static_cast<FrameView*>(parent())) {
        frameView->hostWindow()->platformPageClient()->didPluginEnterFullScreen(this, m_private->m_pluginUniquePrefix.c_str());

        if (!dispatchNPEvent(npEvent))
            frameView->hostWindow()->platformPageClient()->didPluginExitFullScreen(this, m_private->m_pluginUniquePrefix.c_str());
        else
            m_private->m_isFullScreen = true;
    }
}

void PluginView::handleFullScreenExitEvent()
{
    if (!m_private)
        return;

    NPEvent npEvent;
    npEvent.type = NP_FullScreenExitEvent;
    npEvent.data = 0;

    dispatchNPEvent(npEvent);

    if (FrameView* frameView = static_cast<FrameView*>(parent()))
        frameView->hostWindow()->platformPageClient()->didPluginExitFullScreen(this, m_private->m_pluginUniquePrefix.c_str());

    m_private->m_isFullScreen = false;
    invalidate();
}

void PluginView::handleIdleEvent(bool enterIdle)
{
    NPEvent npEvent;
    npEvent.data = 0;

    if (enterIdle)
        npEvent.type = NP_EnterIdleEvent;
    else
        npEvent.type = NP_ExitIdleEvent;

    dispatchNPEvent(npEvent);
}


void PluginView::handleAppActivatedEvent()
{
    NPEvent npEvent;
    npEvent.data = 0;
    npEvent.type = NP_AppActivatedEvent;

    dispatchNPEvent(npEvent);
}

void PluginView::handleAppDeactivatedEvent()
{
    if (!m_private)
        return;

    // Plugin wants to know that it has to exit fullscreen on deactivation.
    if (m_private->m_isFullScreen)
        handleFullScreenExitEvent();

    NPEvent npEvent;
    npEvent.data = 0;
    npEvent.type = NP_AppDeactivatedEvent;

    dispatchNPEvent(npEvent);
}

void PluginView::handleAppStandbyEvent()
{
    // FIXME: This should send an QNP_AppStandbyEvent
    NPEvent npEvent;
    npEvent.data = 0;
    npEvent.type = NP_AppStandByEvent;

    dispatchNPEvent(npEvent);
}

void PluginView::handleOrientationEvent(int angle)
{
    NPEvent npEvent;
    npEvent.type = NP_OrientationEvent;
    npEvent.data = (void*)angle;

    dispatchNPEvent(npEvent);
}

void PluginView::handleSwipeEvent()
{
    if (!m_private)
        return;

    // Plugin only wants to know that it has to exit fullscreen.
    if (m_private->m_isFullScreen)
        handleFullScreenExitEvent();
}

void PluginView::handleScreenPowerEvent(bool powered)
{
    NPEvent npEvent;
    npEvent.data = 0;

    if (powered)
        npEvent.type = NP_ScreenPowerUpEvent;
    else
        npEvent.type = NP_ScreenPowerDownEvent;

    dispatchNPEvent(npEvent);
}

void PluginView::setParent(ScrollView* parentWidget)
{
    // If parentWidget is 0, lets unregister the plugin with the current parent.
    if (m_private && (!parentWidget || parentWidget != parent())) {
        if (FrameView* frameView = static_cast<FrameView*>(parent())) {
            if (m_private->m_isBackgroundPlaying)
                frameView->hostWindow()->platformPageClient()->onPluginStopBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str());

            if (m_private->m_isFullScreen)
                handleFullScreenExitEvent();

            // This will unlock the idle (if we have locked it).
            m_private->preventIdle(false);

            // This will release any keepVisibleRects if they were set.
            m_private->clearVisibleRects();

#if USE(ACCELERATED_COMPOSITING)
            // If we had a hole punch rect set, clear it.
            if (m_private->m_platformLayer && !m_private->m_holePunchRect.isEmpty())
                m_private->m_platformLayer->setHolePunchRect(IntRect());
#endif
            frameView->hostWindow()->platformPageClient()->registerPlugin(this, false /*shouldRegister*/);
        }
    }

    Widget::setParent(parentWidget);

    if (parentWidget) {
        init();

        FrameView* frameView = static_cast<FrameView*>(parentWidget);

        if (frameView && m_private) {
            frameView->hostWindow()->platformPageClient()->registerPlugin(this, true /*shouldRegister*/);
            if (frameView->frame()
               && frameView->frame()->loader()
               && frameView->frame()->loader()->frameHasLoaded())
                handleOnLoadEvent();

            if (m_private->m_isBackgroundPlaying)
                frameView->hostWindow()->platformPageClient()->onPluginStartBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str());
        }
    }
}

void PluginView::setNPWindowRect(const IntRect&)
{
    setNPWindowIfNeeded();
}

void PluginView::setNPWindowIfNeeded()
{
    if (!m_private || !m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow)
        return;

    FrameView* frameView = static_cast<FrameView*>(parent());
    if (!frameView->hostWindow()->platformPageClient()->isActive())
        return;

    // If the plugin didn't load sucessfully, no point in calling setwindow
    if (m_status != PluginStatusLoadedSuccessfully)
        return;

    if (m_private->m_isFullScreen)
        return;

    if (!m_private->m_hasPendingGeometryChange)
        return;

    m_private->m_hasPendingGeometryChange = false;

    m_npWindow.x = m_windowRect.x();
    m_npWindow.y = m_windowRect.y();

    m_npWindow.clipRect.left = max(0, m_clipRect.x());
    m_npWindow.clipRect.top = max(0, m_clipRect.y());
    m_npWindow.clipRect.right = max(0, m_clipRect.maxX());
    m_npWindow.clipRect.bottom = max(0, m_clipRect.maxY());

    if (m_plugin->quirks().contains(PluginQuirkDontCallSetWindowMoreThanOnce)) {
        // Only set the width and height of the plugin content the first time setNPWindow() is called
        // so as to workaround an issue in Flash where multiple calls to setNPWindow() cause the plugin
        // to crash in windowed mode.
        if (!m_isWindowed || m_npWindow.width == UninitializedCoordinate || m_npWindow.height == UninitializedCoordinate) {
            m_npWindow.width = m_windowRect.width();
            m_npWindow.height = m_windowRect.height();
        }
    } else {
        m_npWindow.width = m_windowRect.width();
        m_npWindow.height = m_windowRect.height();
    }

    m_npWindow.type = NPWindowTypeDrawable;

    BlackBerry::Platform::Graphics::Window* window = frameView->hostWindow()->platformPageClient()->platformWindow();
    if (window)
        ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->windowGroup = window->windowGroup();

    PluginView::setCurrentPluginView(this);
    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
    setCallingPlugin(true);

    // FIXME: Passing zoomFactor to setwindow make windowed plugin scale incorrectly.
    // Handling the zoom factor properly in the plugin side may be a better solution.
    double oldZoomFactor = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->zoomFactor;
    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->zoomFactor = 1.;
    m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->zoomFactor = oldZoomFactor;

    setCallingPlugin(false);
    PluginView::setCurrentPluginView(0);
}

void PluginView::setParentVisible(bool visible)
{
    if (isParentVisible() == visible)
        return;

    Widget::setParentVisible(visible);

    // FIXME: We might want to tell the plugin to hide it's window here, but it doesn't matter
    // since the window manager should take care of that for us.
}

NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf)
{
    String filename(buf, len);

    if (filename.startsWith("file:///"))
        filename = filename.substring(8);

    long long size;
    if (!getFileSize(filename, size))
        return NPERR_FILE_NOT_FOUND;

    FILE* fileHandle = fopen(filename.utf8().data(), "r");
    if (!fileHandle)
        return NPERR_FILE_NOT_FOUND;

    buffer.resize(size);
    int bytesRead = fread(buffer.data(), 1, size, fileHandle);

    fclose(fileHandle);

    if (bytesRead <= 0)
        return NPERR_FILE_NOT_FOUND;

    return NPERR_NO_ERROR;
}

bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPError* result)
{
    switch (variable) {
    case NPNVToolkit:
        *static_cast<uint32_t*>(value) = 0;
        *result = NPERR_NO_ERROR;
        return true;

    case NPNVSupportsXEmbedBool:
        *static_cast<NPBool*>(value) = true;
        *result = NPERR_NO_ERROR;
        return true;

    case NPNVjavascriptEnabledBool:
        *static_cast<NPBool*>(value) = true;
        *result = NPERR_NO_ERROR;
        return true;

    case NPNVSupportsWindowless:
        *static_cast<NPBool*>(value) = true;
        *result = NPERR_NO_ERROR;
        return true;

    case NPNVNPCallbacksPtr:
        *((void **) value) = (void*)&s_NpCallbacks;
        *result = NPERR_NO_ERROR;
        return true;

    case NPNVxDisplay:
    case NPNVxtAppContext:
    case NPNVnetscapeWindow:
    case NPNVasdEnabledBool:
    case NPNVisOfflineBool:
    case NPNVserviceManager:
    case NPNVDOMElement:
    case NPNVDOMWindow:
    case NPNVWindowNPObject:
    case NPNVPluginElementNPObject:
    case NPNVprivateModeBool:
    case NPNVZoomFactor:
    case NPNVRootWindowGroup:
    case NPNVBrowserWindowGroup:
    case NPNVBrowserDisplayContext:
    case NPNVPluginWindowPrefix:
        return false;

    default:
        ASSERT_NOT_REACHED();
        return false;
    }
}

bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* result)
{
    switch (variable) {
    case NPNVZoomFactor:
        *(static_cast<void**>(value)) = static_cast<void*>(&((static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info)))->zoomFactor);
        *result = NPERR_NO_ERROR;
        return true;

    case NPNVRootWindowGroup: {
        FrameView* frameView = static_cast<FrameView*>(parent());
        if (frameView) {
            BlackBerry::Platform::Graphics::Window *window = frameView->hostWindow()->platformPageClient()->platformWindow();
            if (window) {
                void** tempValue = static_cast<void**>(value);
                *tempValue = (void*)window->rootGroup();

                if (*tempValue) {
                    *result = NPERR_NO_ERROR;
                    return true;
                }
            }
        }
        *result = NPERR_GENERIC_ERROR;
        return false;
    }

    case NPNVBrowserWindowGroup: {
        FrameView* frameView = static_cast<FrameView*>(parent());
        if (frameView) {
            BlackBerry::Platform::Graphics::Window* window = frameView->hostWindow()->platformPageClient()->platformWindow();
            if (window) {
                void** tempValue = static_cast<void**>(value);
                *tempValue = reinterpret_cast<void*>(const_cast<char*>(window->windowGroup()));

                if (*tempValue) {
                    *result = NPERR_NO_ERROR;
                    return true;
                }
            }
        }
        *result = NPERR_GENERIC_ERROR;
        return false;
    }

    case NPNVBrowserDisplayContext: {
        FrameView* frameView = static_cast<FrameView*>(parent());
        if (frameView) {
            BlackBerry::Platform::Graphics::PlatformDisplayContextHandle context = BlackBerry::Platform::Graphics::platformDisplayContext();
            if (context) {
                void** tempValue = static_cast<void**>(value);
                *tempValue = static_cast<void*>(context);

                if (*tempValue) {
                    *result = NPERR_NO_ERROR;
                    return true;
                }
            }
        }
        *result = NPERR_GENERIC_ERROR;
        return false;
    }

    case NPNVPluginWindowPrefix: {
        void** tempValue = static_cast<void**>(value);
        *tempValue = static_cast<void*>(const_cast<char*>(m_private->m_pluginUniquePrefix.c_str()));

        if (*tempValue) {
            *result = NPERR_NO_ERROR;
            return true;
        }
        *result = NPERR_GENERIC_ERROR;
        return false;
    }

    case NPNVxDisplay:
    case NPNVxtAppContext:
    case NPNVnetscapeWindow:
    case NPNVjavascriptEnabledBool:
    case NPNVasdEnabledBool:
    case NPNVisOfflineBool:
    case NPNVserviceManager:
    case NPNVDOMElement:
    case NPNVDOMWindow:
    case NPNVToolkit:
    case NPNVSupportsXEmbedBool:
    case NPNVWindowNPObject:
    case NPNVPluginElementNPObject:
    case NPNVSupportsWindowless:
    case NPNVprivateModeBool:
    case NPNVNPCallbacksPtr:
        return platformGetValueStatic(variable, value, result);

    default:
        ASSERT_NOT_REACHED();
        return false;
    }
}

// This is a pure virtual inherited from Widget class and all invalidates
// are funneled through this method. We forward them on to either the
// compositing layer or the PluginView::invalidateWindowlessPluginRect method.
void PluginView::invalidateRect(const IntRect& rect)
{
    if (!m_private)
        return;

    // Record the region that we've been asked to invalidate
    m_private->m_invalidateRegion = BlackBerry::Platform::IntRectRegion::unionRegions(BlackBerry::Platform::IntRect(rect), m_private->m_invalidateRegion);

#if USE(ACCELERATED_COMPOSITING)
    if (m_private->m_platformLayer) {
        m_private->m_platformLayer->setNeedsDisplay();
        return;
    }
#endif

    invalidateWindowlessPluginRect(rect);
}

void PluginView::invalidateRect(NPRect* rect)
{
    if (!rect) {
        invalidate();
        return;
    }
    invalidateRect(IntRect(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top));
}

void PluginView::invalidateRegion(NPRegion region)
{
    invalidate();
}

void PluginView::forceRedraw()
{
    invalidate();
}

bool PluginView::platformStart()
{
    ASSERT(m_isStarted);
    ASSERT(m_status == PluginStatusLoadedSuccessfully);

    m_private = new PluginViewPrivate(this);

    if (m_plugin->pluginFuncs()->getvalue) {
        PluginView::setCurrentPluginView(this);
        JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
        setCallingPlugin(true);
        m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginNeedsXEmbed, &m_needsXEmbed);
        setCallingPlugin(false);
        PluginView::setCurrentPluginView(0);
    }

#if USE(ACCELERATED_COMPOSITING)
    if (m_parentFrame->page()->chrome()->client()->allowsAcceleratedCompositing()
        && m_parentFrame->page()->settings()
        && m_parentFrame->page()->settings()->acceleratedCompositingEnabled()) {
        m_private->m_platformLayer = PluginLayerWebKitThread::create(this);
        // Trigger layer computation in RenderLayerCompositor
        m_element->setNeedsStyleRecalc(SyntheticStyleChange);
    }
#endif

    m_npWindow.type = NPWindowTypeDrawable;
    m_npWindow.window = 0; // Not used?
    m_npWindow.x = 0;
    m_npWindow.y = 0;
    m_npWindow.width = UninitializedCoordinate;
    m_npWindow.height = UninitializedCoordinate;
    m_npWindow.ws_info = new NPSetWindowCallbackStruct;
    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->zoomFactor = 1.;
    ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->windowGroup = 0;

    show();

    if (FrameView* frameView = static_cast<FrameView*>(parent()))
        handleOrientationEvent(frameView->hostWindow()->platformPageClient()->orientation());

    if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall))) {
        updatePluginWidget();
        setNPWindowIfNeeded();
    }

    return true;
}

void PluginView::platformDestroy()
{
    if (!m_private)
        return;

    // This will unlock the idle (if we have locked it).
    m_private->preventIdle(false);

    // This will release any keepVisibleRects if they were set.
    m_private->clearVisibleRects();

    // This will ensure that we unregistered the plugin.
    if (FrameView* frameView = static_cast<FrameView*>(parent())) {
        if (m_private->m_isBackgroundPlaying)
            frameView->hostWindow()->platformPageClient()->onPluginStopBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str());

        // If we were still fullscreen, ensure we notify everyone we're not.
        if (m_private->m_isFullScreen)
            frameView->hostWindow()->platformPageClient()->didPluginExitFullScreen(this, m_private->m_pluginUniquePrefix.c_str());

        if (m_private->m_orientationLocked)
            frameView->hostWindow()->platformPageClient()->unlockOrientation();

        frameView->hostWindow()->platformPageClient()->registerPlugin(this, false /*shouldRegister*/);
    }

    m_private->m_isBackgroundPlaying = false;
    m_private->m_isFullScreen = false;

    delete m_private;
    m_private = 0;
}

void PluginView::getWindowInfo(Vector<PluginWindowInfo>& windowList)
{
    if (!m_plugin->pluginFuncs()->getvalue)
        return;

    void* valPtr = 0;

    PluginView::setCurrentPluginView(this);
    JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData());
    setCallingPlugin(true);
    m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginScreenWindow, &valPtr);
    setCallingPlugin(false);
    PluginView::setCurrentPluginView(0);

    if (!valPtr)
        return;

    NPScreenWindowHandles* screenWinHandles = static_cast<NPScreenWindowHandles*>(valPtr);

    for (int i = 0; i < screenWinHandles->numOfWindows; i++) {
        PluginWindowInfo info;
        info.windowPtr = screenWinHandles->windowHandles[i];

        NPRect* rc = screenWinHandles->windowRects[i];
        info.windowRect = IntRect(rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top);

        windowList.append(info);
    }
}

BlackBerry::Platform::Graphics::Buffer* PluginView::lockFrontBufferForRead() const
{
    if (!m_private)
        return 0;

    BlackBerry::Platform::Graphics::Buffer* buffer = m_private->lockReadFrontBufferInternal();

    if (!buffer)
        m_private->unlockReadFrontBuffer();

    return buffer;
}

void PluginView::unlockFrontBuffer() const
{
    if (!m_private)
        return;
    m_private->unlockReadFrontBuffer();
}

#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* PluginView::platformLayer() const
{
    if (!m_private)
        return 0;
    return m_private->m_platformLayer.get();
}
#endif

IntRect PluginView::ensureVisibleRect()
{
    if (!m_private)
        return IntRect();
    return m_private->m_keepVisibleRect;
}

void PluginView::setBackgroundPlay(bool value)
{
    if (!m_private || m_private->m_isBackgroundPlaying == value)
        return;

    FrameView* frameView = static_cast<FrameView*>(m_private->m_view->parent());
    m_private->m_isBackgroundPlaying = value;
    if (m_private->m_isBackgroundPlaying)
        frameView->hostWindow()->platformPageClient()->onPluginStartBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str());
    else
        frameView->hostWindow()->platformPageClient()->onPluginStopBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str());
}

} // namespace WebCore


