/*
 * Copyright 2008, 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.
 */

#include "config.h"
#include "PluginWidgetAndroid.h"

#if ENABLE(TOUCH_EVENTS)
#include "ChromeClient.h"
#endif
#include "Document.h"
#include "Element.h"
#include "Frame.h"
#include "Page.h"
#include "PluginPackage.h"
#include "PluginView.h"
#include "PluginWidgetAndroid.h"
#include "ScrollView.h"
#include "SkANP.h"
#include "SkFlipPixelRef.h"
#include "SkString.h"
#include "SkTime.h"
#include "WebViewCore.h"
#include <JNIUtility.h>

//#define PLUGIN_DEBUG_LOCAL // controls the printing of log messages
#define DEBUG_EVENTS 0 // logs event contents, return value, and processing time
#define DEBUG_VISIBLE_RECTS 0 // temporary debug printfs and fixes

#define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )

// this include statement must follow the declaration of PLUGIN_DEBUG_LOCAL
#include "PluginDebugAndroid.h"

PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view)
        : m_pluginView(view) {
    m_flipPixelRef = NULL;
    m_core = NULL;
    m_drawingModel = kBitmap_ANPDrawingModel;
    m_eventFlags = 0;
    m_pluginWindow = NULL;
    m_requestedVisibleRectCount = 0;
    m_requestedVisibleRect.setEmpty();
    m_visibleDocRect.setEmpty();
    m_pluginBounds.setEmpty();
    m_hasFocus = false;
    m_isFullScreen = false;
    m_visible = false;
    m_cachedZoomLevel = 0;
    m_embeddedView = NULL;
    m_embeddedViewAttached = false;
    m_acceptEvents = false;
    m_isSurfaceClippedOut = false;
    m_layer = 0;
    m_powerState = kDefault_ANPPowerState;
    m_fullScreenOrientation = -1;
    m_drawEventDelayed = false;
}

PluginWidgetAndroid::~PluginWidgetAndroid() {
    PLUGIN_LOG("%p Deleting Plugin", m_pluginView->instance());
    m_acceptEvents = false;
    if (m_core) {
        setPowerState(kDefault_ANPPowerState);
        m_core->removePlugin(this);
        if (m_isFullScreen) {
            exitFullScreen(true);
        }
        if (m_embeddedView) {
            m_core->destroySurface(m_embeddedView);
        }
    }

    // cleanup any remaining JNI References
    JNIEnv* env = JSC::Bindings::getJNIEnv();
    if (m_embeddedView) {
        env->DeleteGlobalRef(m_embeddedView);
    }

    SkSafeUnref(m_flipPixelRef);
    SkSafeUnref(m_layer);
}

void PluginWidgetAndroid::init(android::WebViewCore* core) {
    m_core = core;
    m_core->addPlugin(this);
    m_acceptEvents = true;
    PLUGIN_LOG("%p Initialized Plugin", m_pluginView->instance());
}

static SkBitmap::Config computeConfig(bool isTransparent) {
    return isTransparent ? SkBitmap::kARGB_8888_Config
                         : SkBitmap::kRGB_565_Config;
}

void PluginWidgetAndroid::setWindow(NPWindow* window, bool isTransparent) {

    // store the reference locally for easy lookup
    m_pluginWindow = window;

    // make a copy of the previous bounds
    SkIRect oldPluginBounds = m_pluginBounds;

    // keep a local copy of the plugin bounds because the m_pluginWindow pointer
    // gets updated values prior to this method being called
    m_pluginBounds.set(m_pluginWindow->x, m_pluginWindow->y,
                       m_pluginWindow->x + m_pluginWindow->width,
                       m_pluginWindow->y + m_pluginWindow->height);

    PLUGIN_LOG("%p PluginBounds (%d,%d,%d,%d)", m_pluginView->instance(),
               m_pluginBounds.fLeft, m_pluginBounds.fTop,
               m_pluginBounds.fRight, m_pluginBounds.fBottom);

    const bool boundsChanged = m_pluginBounds != oldPluginBounds;

    //TODO hack to ensure that we grab the most recent screen dimensions and scale
    ANPRectI screenCoords;
    m_core->getVisibleScreen(screenCoords);
    float scale = m_core->scale();
    bool scaleChanged = m_cachedZoomLevel != scale;
    setVisibleScreen(screenCoords, scale);

    // if the scale changed then setVisibleScreen will call this function and
    // this call will potentially fire a duplicate draw event
    if (!scaleChanged) {
        sendSizeAndVisibilityEvents(boundsChanged);
    }
    layoutSurface(boundsChanged);

    if (m_drawingModel != kSurface_ANPDrawingModel) {
        SkSafeUnref(m_flipPixelRef);
        m_flipPixelRef = new SkFlipPixelRef(computeConfig(isTransparent),
                                            window->width, window->height);
    }
}

bool PluginWidgetAndroid::setDrawingModel(ANPDrawingModel model) {

    if (model == kOpenGL_ANPDrawingModel && m_layer == 0) {
        jobject webview = m_core->getWebViewJavaObject();
        AutoJObject webViewCore = m_core->getJavaObject();
        m_layer = new WebCore::MediaLayer(webview, webViewCore.get());
    }
    else if (model != kOpenGL_ANPDrawingModel && m_layer != 0) {
        m_layer->unref();
        m_layer = 0;
    }

    if (m_drawingModel != model) {
        // Trigger layer computation in RenderLayerCompositor
        m_pluginView->getElement()->setNeedsStyleRecalc(SyntheticStyleChange);
    }

    m_drawingModel = model;
    return true;
}

void PluginWidgetAndroid::checkSurfaceReady() {
    if(!m_drawEventDelayed)
        return;

    m_drawEventDelayed = false;
    sendSizeAndVisibilityEvents(true);
}

// returned rect is in the page coordinate
bool PluginWidgetAndroid::isDirty(SkIRect* rect) const {
    // nothing to report if we haven't had setWindow() called yet
    if (NULL == m_flipPixelRef) {
        return false;
    }

    const SkRegion& dirty = m_flipPixelRef->dirtyRgn();
    if (dirty.isEmpty()) {
        return false;
    } else {
        if (rect) {
            *rect = dirty.getBounds();
            rect->offset(m_pluginWindow->x, m_pluginWindow->y);
        }
        return true;
    }
}

void PluginWidgetAndroid::inval(const WebCore::IntRect& rect,
                                bool signalRedraw) {
    // nothing to do if we haven't had setWindow() called yet. m_flipPixelRef
    // will also be null if this is a Surface model.
    if (NULL == m_flipPixelRef) {
        return;
    }

    m_flipPixelRef->inval(rect);

    if (signalRedraw && m_flipPixelRef->isDirty()) {
        m_core->invalPlugin(this);
    }
}

void PluginWidgetAndroid::viewInvalidate() {
    WebCore::IntRect rect(m_pluginBounds.fLeft, m_pluginBounds.fTop,
            m_pluginBounds.width(), m_pluginBounds.height());
    m_core->viewInvalidate(rect);
}

void PluginWidgetAndroid::draw(PlatformGraphicsContext* context) {
    if (NULL == m_flipPixelRef || !m_flipPixelRef->isDirty()) {
        return;
    }

    SkAutoFlipUpdate update(m_flipPixelRef);
    const SkBitmap& bitmap = update.bitmap();
    const SkRegion& dirty = update.dirty();

    ANPEvent    event;
    SkANP::InitEvent(&event, kDraw_ANPEventType);

    event.data.draw.model = m_drawingModel;
    SkANP::SetRect(&event.data.draw.clip, dirty.getBounds());

    switch (m_drawingModel) {
        case kBitmap_ANPDrawingModel: {
            WebCore::PluginPackage* pkg = m_pluginView->plugin();
            NPP instance = m_pluginView->instance();

            if (SkANP::SetBitmap(&event.data.draw.data.bitmap,
                                 bitmap) &&
                    pkg->pluginFuncs()->event(instance, &event)) {

                if (context && m_pluginWindow) {
                    SkBitmap bm(bitmap);
                    bm.setPixelRef(m_flipPixelRef);
                    IntRect dst(0, 0, bm.width(), bm.height());
                    context->drawBitmapRect(bm, 0, dst);
                }
            }
            break;
        }
        default:
            break;
    }
}

void PluginWidgetAndroid::setSurfaceClip(const SkIRect& clip) {

    if (m_drawingModel != kSurface_ANPDrawingModel)
        return;

    /* don't display surfaces that are either entirely clipped or only 1x1 in
       size. It appears that when an element is absolutely positioned and has
       been completely clipped in CSS that webkit still sends a clip of 1x1.
     */
    bool clippedOut = (clip.width() <= 1 && clip.height() <= 1);
    if(clippedOut != m_isSurfaceClippedOut) {
        m_isSurfaceClippedOut = clippedOut;
        layoutSurface();
    }
}

void PluginWidgetAndroid::layoutSurface(bool pluginBoundsChanged) {

    if (m_drawingModel != kSurface_ANPDrawingModel)
        return;
    if (!m_pluginWindow)
        return;


    bool displayPlugin = m_pluginView->isVisible() && !m_isSurfaceClippedOut;
    PLUGIN_LOG("%p DisplayPlugin[%d] visible=[%d] clipped=[%d]",
            m_pluginView->instance(), displayPlugin,
            m_pluginView->isVisible(), m_isSurfaceClippedOut);

    // if the surface does not exist then create a new surface
    if (!m_embeddedView && displayPlugin) {

        WebCore::PluginPackage* pkg = m_pluginView->plugin();
        NPP instance = m_pluginView->instance();

        jobject pluginSurface;
        pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue,
                                     static_cast<void*>(&pluginSurface));

        jobject tempObj = m_core->addSurface(pluginSurface,
                m_pluginWindow->x, m_pluginWindow->y,
                m_pluginWindow->width, m_pluginWindow->height);

        if (tempObj) {
            JNIEnv* env = JSC::Bindings::getJNIEnv();
            m_embeddedView = env->NewGlobalRef(tempObj);
            m_embeddedViewAttached = true;
        }
    // if the view is unattached but visible then attach it
    } else if (m_embeddedView && !m_embeddedViewAttached && displayPlugin && !m_isFullScreen) {
        m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y,
                              m_pluginWindow->width, m_pluginWindow->height);
        m_embeddedViewAttached = true;
    // if the view is attached but invisible then remove it
    } else if (m_embeddedView && m_embeddedViewAttached && !displayPlugin) {
        m_core->destroySurface(m_embeddedView);
        m_embeddedViewAttached = false;
    // if the plugin's bounds have changed and it's visible then update it
    } else if (pluginBoundsChanged && displayPlugin && !m_isFullScreen) {
        m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y,
                              m_pluginWindow->width, m_pluginWindow->height);

    }
}

int16_t PluginWidgetAndroid::sendEvent(const ANPEvent& evt) {
    if (!m_acceptEvents)
        return 0;
    WebCore::PluginPackage* pkg = m_pluginView->plugin();
    NPP instance = m_pluginView->instance();
    // "missing" plugins won't have these
    if (pkg && instance) {

        // if the plugin is gaining focus then update our state now to allow
        // the plugin's event handler to perform actions that require focus
        if (evt.eventType == kLifecycle_ANPEventType &&
                evt.data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
            m_hasFocus = true;
        }

#if DEBUG_EVENTS
        SkMSec startTime = SkTime::GetMSecs();
#endif

        // make a localCopy since the actual plugin may not respect its constness,
        // and so we don't want our caller to have its param modified
        ANPEvent localCopy = evt;
        int16_t result = pkg->pluginFuncs()->event(instance, &localCopy);

#if DEBUG_EVENTS
        SkMSec endTime = SkTime::GetMSecs();
        PLUGIN_LOG_EVENT(instance, &evt, result, endTime - startTime);
#endif

        // if the plugin is losing focus then delay the update of our state
        // until after we notify the plugin and allow them to perform actions
        // that may require focus
        if (evt.eventType == kLifecycle_ANPEventType &&
                evt.data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
            m_hasFocus = false;
        }

        return result;
    }
    return 0;
}

void PluginWidgetAndroid::updateEventFlags(ANPEventFlags flags) {

    // if there are no differences then immediately return
    if (m_eventFlags == flags) {
        return;
    }

    Document* doc = m_pluginView->parentFrame()->document();
#if ENABLE(TOUCH_EVENTS)
    if((m_eventFlags ^ flags) & kTouch_ANPEventFlag) {
        if (flags & kTouch_ANPEventFlag)
           doc->addListenerTypeIfNeeded(eventNames().touchstartEvent);
    }
#endif

    m_eventFlags = flags;
}

bool PluginWidgetAndroid::isAcceptingEvent(ANPEventFlag flag) {
    return m_eventFlags & flag;
}

void PluginWidgetAndroid::sendSizeAndVisibilityEvents(const bool updateDimensions) {

    if (m_drawingModel == kOpenGL_ANPDrawingModel &&
            !m_layer->acquireNativeWindowForContent()) {
        m_drawEventDelayed = true;
        return;
    }

    // TODO update the bitmap size based on the zoom? (for kBitmap_ANPDrawingModel)
    const float zoomLevel = m_core->scale();

    // notify the plugin of the new size
    if (m_drawingModel == kOpenGL_ANPDrawingModel && updateDimensions && m_pluginWindow) {
        PLUGIN_LOG("%s (%d,%d)[%f]", __FUNCTION__, m_pluginWindow->width,
                m_pluginWindow->height, zoomLevel);
        ANPEvent event;
        SkANP::InitEvent(&event, kDraw_ANPEventType);
        event.data.draw.model = kOpenGL_ANPDrawingModel;
        event.data.draw.data.surface.width = m_pluginWindow->width * zoomLevel;
        event.data.draw.data.surface.height = m_pluginWindow->height * zoomLevel;
        sendEvent(event);
    }

    bool visible = SkIRect::Intersects(m_visibleDocRect, m_pluginBounds);
    if(m_visible != visible) {

#if DEBUG_VISIBLE_RECTS
        PLUGIN_LOG("%p changeVisiblity[%d] pluginBounds(%d,%d,%d,%d)",
                   m_pluginView->instance(), visible,
                   m_pluginBounds.fLeft, m_pluginBounds.fTop,
                   m_pluginBounds.fRight, m_pluginBounds.fBottom);
#endif

        // change the visibility
        m_visible = visible;
        // send the event
        ANPEvent event;
        SkANP::InitEvent(&event, kLifecycle_ANPEventType);
        event.data.lifecycle.action = visible ? kOnScreen_ANPLifecycleAction
                                              : kOffScreen_ANPLifecycleAction;
        sendEvent(event);
    }
}

void PluginWidgetAndroid::setVisibleScreen(const ANPRectI& visibleDocRect, float zoom) {
#if DEBUG_VISIBLE_RECTS
    PLUGIN_LOG("%s (%d,%d,%d,%d)[%f]", __FUNCTION__, visibleDocRect.left,
            visibleDocRect.top, visibleDocRect.right,
            visibleDocRect.bottom, zoom);
#endif
    int oldScreenW = m_visibleDocRect.width();
    int oldScreenH = m_visibleDocRect.height();

    const bool zoomChanged = m_cachedZoomLevel != zoom;

    // make local copies of the parameters
    m_cachedZoomLevel = zoom;
    m_visibleDocRect.set(visibleDocRect.left,
                         visibleDocRect.top,
                         visibleDocRect.right,
                         visibleDocRect.bottom);

    int newScreenW = m_visibleDocRect.width();
    int newScreenH = m_visibleDocRect.height();

    // if the screen dimensions have changed by more than 5 pixels in either
    // direction then recompute the plugin's visible rectangle
    if (abs(oldScreenW - newScreenW) > 5 || abs(oldScreenH - newScreenH) > 5) {
        PLUGIN_LOG("%s VisibleDoc old=[%d,%d] new=[%d,%d] ", __FUNCTION__,
                   oldScreenW, oldScreenH, newScreenW, newScreenH);
        computeVisiblePluginRect();
    }

    sendSizeAndVisibilityEvents(zoomChanged);
}

ANPRectI PluginWidgetAndroid::visibleRect() {

    SkIRect visibleRect;
    visibleRect.setEmpty();

    // compute the interesection of the visible screen and the plugin
    bool visible = visibleRect.intersect(m_visibleDocRect, m_pluginBounds);
    if (visible) {
        // convert from absolute coordinates to the plugin's relative coordinates
        visibleRect.offset(-m_pluginBounds.fLeft, -m_pluginBounds.fTop);
    }

    // convert from SkRect to ANPRect
    ANPRectI result;
    memcpy(&result, &visibleRect, sizeof(ANPRectI));
    return result;
}

void PluginWidgetAndroid::setVisibleRects(const ANPRectI rects[], int32_t count) {
#if DEBUG_VISIBLE_RECTS
    PLUGIN_LOG("%s count=%d", __FUNCTION__, count);
#endif
    // ensure the count does not exceed our allocated space
    if (count > MAX_REQUESTED_RECTS)
        count = MAX_REQUESTED_RECTS;

    // store the values in member variables
    m_requestedVisibleRectCount = count;
    memcpy(m_requestedVisibleRects, rects, count * sizeof(rects[0]));

#if DEBUG_VISIBLE_RECTS // FIXME: this fixes bad data from the plugin
    // take it out once plugin supplies better data
    for (int index = 0; index < count; index++) {
        PLUGIN_LOG("%s [%d](%d,%d,%d,%d)", __FUNCTION__, index,
            m_requestedVisibleRects[index].left,
            m_requestedVisibleRects[index].top,
            m_requestedVisibleRects[index].right,
            m_requestedVisibleRects[index].bottom);
        if (m_requestedVisibleRects[index].left ==
                m_requestedVisibleRects[index].right) {
            m_requestedVisibleRects[index].right += 1;
        }
        if (m_requestedVisibleRects[index].top ==
                m_requestedVisibleRects[index].bottom) {
            m_requestedVisibleRects[index].bottom += 1;
        }
    }
#endif
    computeVisiblePluginRect();
}

void PluginWidgetAndroid::computeVisiblePluginRect() {

    // ensure the visibleDocRect has been set (i.e. not equal to zero)
    if (m_visibleDocRect.isEmpty() || !m_pluginWindow || m_requestedVisibleRectCount < 1)
        return;

    // create a rect that will contain as many of the rects that will fit on screen
    SkIRect visibleRect;
    visibleRect.setEmpty();

    for (int counter = 0; counter < m_requestedVisibleRectCount; counter++) {

        ANPRectI* rect = &m_requestedVisibleRects[counter];

        // create skia rect for easier manipulation and convert it to page coordinates
        SkIRect pluginRect;
        pluginRect.set(rect->left, rect->top, rect->right, rect->bottom);
        pluginRect.offset(m_pluginWindow->x, m_pluginWindow->y);

        // ensure the rect falls within the plugin's bounds
        if (!m_pluginBounds.contains(pluginRect)) {
#if DEBUG_VISIBLE_RECTS
            PLUGIN_LOG("%s (%d,%d,%d,%d) !contain (%d,%d,%d,%d)", __FUNCTION__,
                       m_pluginBounds.fLeft, m_pluginBounds.fTop,
                       m_pluginBounds.fRight, m_pluginBounds.fBottom,
                       pluginRect.fLeft, pluginRect.fTop,
                       pluginRect.fRight, pluginRect.fBottom);
            // assume that the desired outcome is to clamp to the container
            if (pluginRect.intersect(m_pluginBounds)) {
                visibleRect = pluginRect;
            }
#endif
            continue;
        }

        // combine this new rect with the higher priority rects
        pluginRect.join(visibleRect);

        // check to see if the new rect could be made to fit within the screen
        // bounds. If this is the highest priority rect then attempt to center
        // even if it doesn't fit on the screen.
        if (counter > 0 && (m_visibleDocRect.width() < pluginRect.width() ||
                            m_visibleDocRect.height() < pluginRect.height()))
          break;

        // set the new visible rect
        visibleRect = pluginRect;
    }

    m_requestedVisibleRect = visibleRect;
    scrollToVisiblePluginRect();
}

void PluginWidgetAndroid::scrollToVisiblePluginRect() {

    if (!m_hasFocus || m_requestedVisibleRect.isEmpty() || m_visibleDocRect.isEmpty()) {
#if DEBUG_VISIBLE_RECTS
        PLUGIN_LOG("%s call m_hasFocus=%d m_requestedVisibleRect.isEmpty()=%d"
                " m_visibleDocRect.isEmpty()=%d", __FUNCTION__, m_hasFocus,
                m_requestedVisibleRect.isEmpty(), m_visibleDocRect.isEmpty());
#endif
        return;
    }
    // if the entire rect is already visible then we don't need to scroll
    if (m_visibleDocRect.contains(m_requestedVisibleRect))
        return;

    // find the center of the visibleRect in document coordinates
    int rectCenterX = m_requestedVisibleRect.fLeft + m_requestedVisibleRect.width()/2;
    int rectCenterY = m_requestedVisibleRect.fTop + m_requestedVisibleRect.height()/2;

    // position the corner of the visible doc to center the requested rect
    int scrollDocX = MAX(0, rectCenterX - (m_visibleDocRect.width()/2));
    int scrollDocY = MAX(0, rectCenterY - (m_visibleDocRect.height()/2));

    ScrollView* scrollView = m_pluginView->parent();
    android::WebViewCore* core = android::WebViewCore::getWebViewCore(scrollView);
#if DEBUG_VISIBLE_RECTS
    PLUGIN_LOG("%s call scrollTo (%d,%d) to center (%d,%d)", __FUNCTION__,
            scrollDocX, scrollDocY, rectCenterX, rectCenterY);
#endif
    core->scrollTo(scrollDocX, scrollDocY, true);
}

void PluginWidgetAndroid::requestFullScreen() {
    if (m_isFullScreen) {
        return;
    }

    if (!m_embeddedView && m_drawingModel == kOpenGL_ANPDrawingModel) {
        WebCore::PluginPackage* pkg = m_pluginView->plugin();
        NPP instance = m_pluginView->instance();

        jobject pluginSurface;
        pkg->pluginFuncs()->getvalue(instance, kJavaSurface_ANPGetValue,
                                     static_cast<void*>(&pluginSurface));

        // create the surface, but do not add it to the view hierarchy
        jobject tempObj = m_core->createSurface(pluginSurface);

        if (tempObj) {
            JNIEnv* env = JSC::Bindings::getJNIEnv();
            m_embeddedView = env->NewGlobalRef(tempObj);
            m_embeddedViewAttached = false;
        }
    }

    if (!m_embeddedView) {
        return;
    }

    // send event to notify plugin of full screen change
    ANPEvent event;
    SkANP::InitEvent(&event, kLifecycle_ANPEventType);
    event.data.lifecycle.action = kEnterFullScreen_ANPLifecycleAction;
    sendEvent(event);

    // remove the embedded surface from the view hierarchy
    if (m_drawingModel != kOpenGL_ANPDrawingModel)
        m_core->destroySurface(m_embeddedView);

    // add the full screen view
    m_core->showFullScreenPlugin(m_embeddedView, m_fullScreenOrientation,
                                 m_pluginView->instance());
    m_isFullScreen = true;
}

void PluginWidgetAndroid::exitFullScreen(bool pluginInitiated) {
    if (!m_isFullScreen || !m_embeddedView) {
        return;
    }

    // remove the full screen surface from the view hierarchy
    if (pluginInitiated) {
        m_core->hideFullScreenPlugin();
    }

    // add the embedded view back
    if (m_drawingModel != kOpenGL_ANPDrawingModel)
        m_core->updateSurface(m_embeddedView, m_pluginWindow->x, m_pluginWindow->y,
                m_pluginWindow->width, m_pluginWindow->height);

    // send event to notify plugin of full screen change
    ANPEvent event;
    SkANP::InitEvent(&event, kLifecycle_ANPEventType);
    event.data.lifecycle.action = kExitFullScreen_ANPLifecycleAction;
    sendEvent(event);

    m_isFullScreen = false;
}

void PluginWidgetAndroid::setFullScreenOrientation(ANPScreenOrientation orientation) {

    int internalOrienationId;
    /* We need to validate that the input is legitimate and then convert the
     * value from the plugin enum to the enum used by the android view system.
     * The view system values correspond to those values for the
     * screenOrientation attribute in R.java (see also ActivityInfo.java).
     */
    switch (orientation) {
        case kFixedLandscape_ANPScreenOrientation:
            internalOrienationId = 0;
            break;
        case kFixedPortrait_ANPScreenOrientation:
            internalOrienationId = 1;
            break;
        case kLandscape_ANPScreenOrientation:
            internalOrienationId = 6;
            break;
        case kPortrait_ANPScreenOrientation:
            internalOrienationId = 7;
            break;
        default:
            internalOrienationId = -1;
    }

    PLUGIN_LOG("%s orientation (%d)", __FUNCTION__, internalOrienationId);
    m_fullScreenOrientation = internalOrienationId;
}

void PluginWidgetAndroid::requestCenterFitZoom() {
    m_core->centerFitRect(m_pluginWindow->x, m_pluginWindow->y,
            m_pluginWindow->width, m_pluginWindow->height);
}

void PluginWidgetAndroid::setPowerState(ANPPowerState powerState) {
    if(m_powerState == powerState)
        return;

    // cleanup the old power state
    switch (m_powerState) {
        case kDefault_ANPPowerState:
            break;
        case kScreenOn_ANPPowerState:
            m_core->keepScreenOn(false);
            break;
    }

    // setup the new power state
    switch (powerState) {
        case kDefault_ANPPowerState:
            break;
        case kScreenOn_ANPPowerState:
            m_core->keepScreenOn(true);
            break;
    }

    m_powerState = powerState;
}

