/*
 * Copyright (C) 2006, 2007 Apple Inc. 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 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 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 "PluginObject.h"

#include "PluginTest.h"
#include <cstdlib>
#include <cstring>
#include <string>

#if defined(MOZ_X11)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif

using namespace std;

static bool getEntryPointsWasCalled;
static bool initializeWasCalled;

#if defined(XP_WIN)
#define STDCALL __stdcall

static inline int strcasecmp(const char* s1, const char* s2)
{
    return _stricmp(s1, s2);
}

#else
#define STDCALL
#endif

extern "C" {
WTF_EXPORT_DECLARATION
NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
}

// Entry points
extern "C" WTF_EXPORT_DECLARATION
NPError STDCALL NP_Initialize(NPNetscapeFuncs *browserFuncs
#if defined(XP_UNIX)
                              , NPPluginFuncs *pluginFuncs
#endif
                              )
{
    initializeWasCalled = true;

#if defined(XP_WIN)
    // Simulate Flash and QuickTime's behavior of crashing when NP_Initialize is called before NP_GetEntryPoints.
    if (!getEntryPointsWasCalled)
        CRASH();
#endif

    browser = browserFuncs;

#if defined(XP_UNIX)
    return NP_GetEntryPoints(pluginFuncs);
#else
    return NPERR_NO_ERROR;
#endif
}

extern "C"
NPError STDCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs)
{
    getEntryPointsWasCalled = true;

#ifdef XP_MACOSX
    // Simulate Silverlight's behavior of crashing when NP_GetEntryPoints is called before NP_Initialize.
    if (!initializeWasCalled)
        CRASH();
#endif

    pluginFunctions = pluginFuncs;

    pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
    pluginFuncs->size = sizeof(pluginFuncs);
    pluginFuncs->newp = NPP_New;
    pluginFuncs->destroy = NPP_Destroy;
    pluginFuncs->setwindow = NPP_SetWindow;
    pluginFuncs->newstream = NPP_NewStream;
    pluginFuncs->destroystream = NPP_DestroyStream;
    pluginFuncs->asfile = NPP_StreamAsFile;
    pluginFuncs->writeready = NPP_WriteReady;
    pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
    pluginFuncs->print = NPP_Print;
    pluginFuncs->event = NPP_HandleEvent;
    pluginFuncs->urlnotify = NPP_URLNotify;
    pluginFuncs->urlredirectnotify = NPP_URLRedirectNotify;
    pluginFuncs->getvalue = NPP_GetValue;
    pluginFuncs->setvalue = NPP_SetValue;
    
    return NPERR_NO_ERROR;
}

extern "C" WTF_EXPORT_DECLARATION
void STDCALL NP_Shutdown(void)
{
    PluginTest::NP_Shutdown();
}

static void executeScript(const PluginObject* obj, const char* script);

NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved)
{
#ifdef XP_MACOSX
    NPEventModel eventModel;
    
    // Always turn on the CG model
    NPBool supportsCoreGraphics;
    if (browser->getvalue(instance, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) != NPERR_NO_ERROR)
        supportsCoreGraphics = false;
    
    if (!supportsCoreGraphics)
        return NPERR_INCOMPATIBLE_VERSION_ERROR;

    NPDrawingModel drawingModelToUse = NPDrawingModelCoreGraphics;

    NPBool supportsCoreAnimation;
    if (browser->getvalue(instance, NPNVsupportsCoreAnimationBool, &supportsCoreAnimation) != NPERR_NO_ERROR)
        supportsCoreAnimation = false;

    NPBool supportsCocoa = false;

    if (browser->getvalue(instance, NPNVsupportsCocoaBool, &supportsCocoa) != NPERR_NO_ERROR)
        supportsCocoa = false;

    if (supportsCocoa)
        eventModel = NPEventModelCocoa;
    else
        return NPERR_INCOMPATIBLE_VERSION_ERROR;

     browser->setvalue(instance, NPPVpluginEventModel, (void *)eventModel);
#endif // XP_MACOSX

    PluginObject* obj = (PluginObject*)browser->createobject(instance, getPluginClass());
    instance->pdata = obj;

#ifdef XP_MACOSX
    obj->eventModel = eventModel;
    obj->coreAnimationLayer = 0;
#endif // XP_MACOSX

    string testIdentifier;
    const char* onNewScript = 0;
    
    for (int i = 0; i < argc; i++) {
        if (strcasecmp(argn[i], "test") == 0)
            testIdentifier = argv[i];
        if (strcasecmp(argn[i], "onstreamload") == 0 && !obj->onStreamLoad)
            obj->onStreamLoad = strdup(argv[i]);
        else if (strcasecmp(argn[i], "onStreamDestroy") == 0 && !obj->onStreamDestroy)
            obj->onStreamDestroy = strdup(argv[i]);
        else if (strcasecmp(argn[i], "onURLNotify") == 0 && !obj->onURLNotify)
            obj->onURLNotify = strdup(argv[i]);
        else if (strcasecmp(argn[i], "src") == 0 &&
                 strcasecmp(argv[i], "data:application/x-webkit-test-netscape,returnerrorfromnewstream") == 0)
            obj->returnErrorFromNewStream = TRUE;
        else if (strcasecmp(argn[i], "src") == 0 &&
                 strcasecmp(argv[i], "data:application/x-webkit-test-netscape,alertwhenloaded") == 0)
            executeScript(obj, "console.log('Plugin Loaded!')");
        else if (strcasecmp(argn[i], "src") == 0 &&
                 strcasecmp(argv[i], "data:application/x-webkit-test-netscape,logifloaded") == 0) {
            for (int j = 0; j < argc; j++) {
              if (strcasecmp(argn[j], "log") == 0) {
                int length = 26 + strlen(argv[j]) + 1;
                char* buffer = (char*) malloc(length);
                snprintf(buffer, length, "xWebkitTestNetscapeLog('%s')", argv[j]);
                executeScript(obj, buffer);
                free(buffer);
              }
            }
        } else if (strcasecmp(argn[i], "onSetWindow") == 0 && !obj->onSetWindow)
            obj->onSetWindow = strdup(argv[i]);
        else if (strcasecmp(argn[i], "onNew") == 0 && !onNewScript)
            onNewScript = argv[i];
        else if (strcasecmp(argn[i], "onPaintEvent") == 0 && !obj->onPaintEvent)
            obj->onPaintEvent = strdup(argv[i]);
        else if (strcasecmp(argn[i], "logfirstsetwindow") == 0)
            obj->logSetWindow = TRUE;
        else if (strcasecmp(argn[i], "testnpruntime") == 0)
            testNPRuntime(instance);
        else if (strcasecmp(argn[i], "logSrc") == 0) {
            for (int i = 0; i < argc; i++)
                if (strcasecmp(argn[i], "src") == 0)
                    pluginLog(instance, "src: %s", argv[i]);
        } else if (strcasecmp(argn[i], "cleardocumentduringnew") == 0)
            executeScript(obj, "document.body.innerHTML = ''");
        else if (!strcasecmp(argn[i], "ondestroy"))
            obj->onDestroy = strdup(argv[i]);
        else if (strcasecmp(argn[i], "testwindowopen") == 0)
            obj->testWindowOpen = TRUE;
        else if (strcasecmp(argn[i], "drawingmodel") == 0) {
#ifdef XP_MACOSX
            const char* value = argv[i];
            if (strcasecmp(value, "coreanimation") == 0) {
                if (supportsCoreAnimation)
                    drawingModelToUse = NPDrawingModelCoreAnimation;
                else
                    return NPERR_INCOMPATIBLE_VERSION_ERROR;
             } else if (strcasecmp(value, "coregraphics") == 0) {
                if (supportsCoreGraphics)
                    drawingModelToUse = NPDrawingModelCoreGraphics;
                else
                    return NPERR_INCOMPATIBLE_VERSION_ERROR;
             } else
                return NPERR_INCOMPATIBLE_VERSION_ERROR;
#endif
        } else if (strcasecmp(argn[i], "testGetURLOnDestroy") == 0) {
#if defined(XP_WIN)
            // FIXME: When https://bugs.webkit.org/show_bug.cgi?id=41831 is fixed, this #ifdef can be removed.
            obj->testGetURLOnDestroy = TRUE;
#endif
        } else if (!strcasecmp(argn[i], "src") && strstr(argv[i], "plugin-document-has-focus.pl"))
            obj->testKeyboardFocusForPlugins = TRUE;
        else if (!strcasecmp(argn[i], "src") && strstr(argv[i], "plugin-document-alert-and-notify-done.pl"))
            executeScript(obj, "alert('Plugin Loaded!'); testRunner.notifyDone();");
        else if (!strcasecmp(argn[i], "evaluatescript")) {
            char* script = argv[i];
            if (script == strstr(script, "mouse::")) {
                obj->mouseDownForEvaluateScript = true;
                obj->evaluateScriptOnMouseDownOrKeyDown = strdup(script + sizeof("mouse::") - 1);
            } else if (script == strstr(script, "key::")) {
                obj->evaluateScriptOnMouseDownOrKeyDown = strdup(script + sizeof("key::") - 1);
            }
            // When testing evaluate script on mouse-down or key-down, allow event logging to handle events.
            if (obj->evaluateScriptOnMouseDownOrKeyDown)
                obj->eventLogging = true;
        } else if (!strcasecmp(argn[i], "windowedPlugin")) {
            void* windowed = 0;
            if (!strcasecmp(argv[i], "false") || !strcasecmp(argv[i], "0"))
                windowed = 0;
            else if (!strcasecmp(argv[i], "true") || !strcasecmp(argv[i], "1"))
                windowed = reinterpret_cast<void*>(1);
            else
                assert(false);
            browser->setvalue(instance, NPPVpluginWindowBool, windowed);
        }
    }

#ifdef XP_MACOSX
    browser->setvalue(instance, NPPVpluginDrawingModel, (void *)drawingModelToUse);
    if (drawingModelToUse == NPDrawingModelCoreAnimation)
        obj->coreAnimationLayer = createCoreAnimationLayer();
#endif

    obj->pluginTest = PluginTest::create(instance, testIdentifier);

    if (!obj->pluginTest) {
        pluginLog(instance, "NPP_New: Could not find a test named \"%s\", maybe its .cpp file wasn't added to the build system?", testIdentifier.c_str());
        return NPERR_GENERIC_ERROR;
    }

    if (onNewScript)
        executeScript(obj, onNewScript);

    return obj->pluginTest->NPP_New(pluginType, mode, argc, argn, argv, saved);
}

NPError NPP_Destroy(NPP instance, NPSavedData **save)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    if (obj) {
        if (obj->testGetURLOnDestroy)
            browser->geturlnotify(obj->npp, "about:blank", "", 0);

        if (obj->onDestroy) {
            executeScript(obj, obj->onDestroy);
            free(obj->onDestroy);
        }

        if (obj->onStreamLoad)
            free(obj->onStreamLoad);

        if (obj->onStreamDestroy)
            free(obj->onStreamDestroy);

        if (obj->onURLNotify)
            free(obj->onURLNotify);

        if (obj->onSetWindow)
            free(obj->onSetWindow);

        if (obj->onPaintEvent)
            free(obj->onPaintEvent);

        if (obj->evaluateScriptOnMouseDownOrKeyDown)
            free(obj->evaluateScriptOnMouseDownOrKeyDown);

        if (obj->logDestroy)
            pluginLog(instance, "NPP_Destroy");

#ifdef XP_MACOSX
        if (obj->coreAnimationLayer)
            CFRelease(obj->coreAnimationLayer);
#endif

        if (obj->pluginTest)
            obj->pluginTest->NPP_Destroy(save);

        browser->releaseobject(&obj->header);
    }
    return NPERR_NO_ERROR;
}

NPError NPP_SetWindow(NPP instance, NPWindow *window)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);

    if (!obj)
        return NPERR_GENERIC_ERROR;

    obj->lastWindow = *window;

    if (obj->logSetWindow) {
        pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height);
        obj->logSetWindow = FALSE;
        executeScript(obj, "testRunner.notifyDone();");
    }

    if (obj->onSetWindow)
        executeScript(obj, obj->onSetWindow);

    if (obj->testWindowOpen) {
        testWindowOpen(instance);
        obj->testWindowOpen = FALSE;
    }

    if (obj->testKeyboardFocusForPlugins) {
        obj->eventLogging = true;
        executeScript(obj, "eventSender.keyDown('A');");
    }

    return obj->pluginTest->NPP_SetWindow(window);
}

static void executeScript(const PluginObject* obj, const char* script)
{
    NPObject *windowScriptObject;
    browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);

    NPString npScript;
    npScript.UTF8Characters = script;
    npScript.UTF8Length = strlen(script);

    NPVariant browserResult;
    browser->evaluate(obj->npp, windowScriptObject, &npScript, &browserResult);
    browser->releasevariantvalue(&browserResult);
}

NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16_t *stype)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    obj->stream = stream;
    *stype = NP_NORMAL;

    if (obj->returnErrorFromNewStream)
        return NPERR_GENERIC_ERROR;
    
    if (browser->version >= NPVERS_HAS_RESPONSE_HEADERS)
        notifyStream(obj, stream->url, stream->headers);

    if (obj->onStreamLoad)
        executeScript(obj, obj->onStreamLoad);

    return obj->pluginTest->NPP_NewStream(type, stream, seekable, stype);
}

NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason)
{
    PluginObject* obj = (PluginObject*)instance->pdata;

    if (obj->onStreamDestroy) {
        NPObject* windowObject = 0;
        NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
        
        if (error == NPERR_NO_ERROR) {
            NPVariant onStreamDestroyVariant;
            if (browser->getproperty(instance, windowObject, browser->getstringidentifier(obj->onStreamDestroy), &onStreamDestroyVariant)) {
                if (NPVARIANT_IS_OBJECT(onStreamDestroyVariant)) {
                    NPObject* onStreamDestroyFunction = NPVARIANT_TO_OBJECT(onStreamDestroyVariant);

                    NPVariant reasonVariant;
                    INT32_TO_NPVARIANT(reason, reasonVariant);

                    NPVariant result;
                    browser->invokeDefault(instance, onStreamDestroyFunction, &reasonVariant, 1, &result);
                    browser->releasevariantvalue(&result);
                }
                browser->releasevariantvalue(&onStreamDestroyVariant);
            }
            browser->releaseobject(windowObject);
        }
    }

    return obj->pluginTest->NPP_DestroyStream(stream, reason);
}

int32_t NPP_WriteReady(NPP instance, NPStream *stream)
{
    PluginObject* obj = (PluginObject*)instance->pdata;
    return obj->pluginTest->NPP_WriteReady(stream);
}

int32_t NPP_Write(NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer)
{
    PluginObject* obj = (PluginObject*)instance->pdata;

    if (obj->returnNegativeOneFromWrite)
        return -1;

    return obj->pluginTest->NPP_Write(stream, offset, len, buffer);
}

void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname)
{
}

void NPP_Print(NPP instance, NPPrint *platformPrint)
{
}

#ifdef XP_MACOSX
static int16_t handleEventCocoa(NPP instance, PluginObject* obj, NPCocoaEvent* event)
{
    switch (event->type) {
        case NPCocoaEventWindowFocusChanged:
            
        case NPCocoaEventFocusChanged:
            if (obj->eventLogging) {
                if (event->data.focus.hasFocus)
                    pluginLog(instance, "getFocusEvent");
                else
                    pluginLog(instance, "loseFocusEvent");
            }
            return 1;

        case NPCocoaEventDrawRect: {
            if (obj->onPaintEvent)
                executeScript(obj, obj->onPaintEvent);
            return 1;
        }

        case NPCocoaEventKeyDown:
            if (obj->eventLogging && event->data.key.characters)
                pluginLog(instance, "keyDown '%c'", CFStringGetCharacterAtIndex(reinterpret_cast<CFStringRef>(event->data.key.characters), 0));
            if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
                executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
            return 1;

        case NPCocoaEventKeyUp:
            if (obj->eventLogging && event->data.key.characters) {
                pluginLog(instance, "keyUp '%c'", CFStringGetCharacterAtIndex(reinterpret_cast<CFStringRef>(event->data.key.characters), 0));
                if (obj->testKeyboardFocusForPlugins) {
                    obj->eventLogging = false;
                    obj->testKeyboardFocusForPlugins = FALSE;
                    executeScript(obj, "testRunner.notifyDone();");
                }
            }
            return 1;

        case NPCocoaEventFlagsChanged:
            return 1;

        case NPCocoaEventMouseDown:
            if (obj->eventLogging) {
                pluginLog(instance, "mouseDown at (%d, %d)", 
                       (int)event->data.mouse.pluginX,
                       (int)event->data.mouse.pluginY);
            }
            if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
                executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
            return 1;
        case NPCocoaEventMouseUp:
            if (obj->eventLogging) {
                pluginLog(instance, "mouseUp at (%d, %d)", 
                       (int)event->data.mouse.pluginX,
                       (int)event->data.mouse.pluginY);
            }
            return 1;
            
        case NPCocoaEventMouseMoved:
        case NPCocoaEventMouseEntered:
        case NPCocoaEventMouseExited:
        case NPCocoaEventMouseDragged:
        case NPCocoaEventScrollWheel:
        case NPCocoaEventTextInput:
            return 1;
    }
    
    return 0;
}

#endif // XP_MACOSX

#if defined(MOZ_X11)
static char keyEventToChar(XKeyEvent* event)
{
    char c = ' ';
    XLookupString(event, &c, sizeof(c), 0, 0);
    return c;
}

static int16_t handleEventX11(NPP instance, PluginObject* obj, XEvent* event)
{
    switch (event->type) {
    case ButtonPress:
        if (obj->eventLogging)
            pluginLog(instance, "mouseDown at (%d, %d)", event->xbutton.x, event->xbutton.y);
        if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
            executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
        break;
    case ButtonRelease:
        if (obj->eventLogging)
            pluginLog(instance, "mouseUp at (%d, %d)", event->xbutton.x, event->xbutton.y);
        break;
    case KeyPress:
        // FIXME: extract key code
        if (obj->eventLogging)
            pluginLog(instance, "keyDown '%c'", keyEventToChar(&event->xkey));
        if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
            executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
        break;
    case KeyRelease:
        // FIXME: extract key code
        if (obj->eventLogging)
            pluginLog(instance, "keyUp '%c'", keyEventToChar(&event->xkey));
        if (obj->testKeyboardFocusForPlugins) {
            obj->eventLogging = false;
            obj->testKeyboardFocusForPlugins = FALSE;
            executeScript(obj, "testRunner.notifyDone();");
        }
        break;
    case GraphicsExpose:
        if (obj->eventLogging)
            pluginLog(instance, "updateEvt");
        if (obj->onPaintEvent)
            executeScript(obj, obj->onPaintEvent);
        break;
    // NPAPI events
    case FocusIn:
        if (obj->eventLogging)
            pluginLog(instance, "getFocusEvent");
        break;
    case FocusOut:
        if (obj->eventLogging)
            pluginLog(instance, "loseFocusEvent");
        break;
    case EnterNotify:
    case LeaveNotify:
    case MotionNotify:
        break;
    default:
        if (obj->eventLogging)
            pluginLog(instance, "event %d", event->type);
    }

    fflush(stdout);
    return 0;
}
#endif // MOZ_X11

#ifdef XP_WIN
static int16_t handleEventWin(NPP instance, PluginObject* obj, NPEvent* event)
{
    switch (event->event) {
    case WM_PAINT:
        if (obj->onPaintEvent)
            executeScript(obj, obj->onPaintEvent);
        break;
    case WM_KEYDOWN:
        if (obj->eventLogging)
            pluginLog(instance, "keyDown '%c'", event->wParam);
        if (obj->evaluateScriptOnMouseDownOrKeyDown && !obj->mouseDownForEvaluateScript)
            executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
        break;
    case WM_CHAR:
        break;
    case WM_KEYUP:
        if (obj->eventLogging)
            pluginLog(instance, "keyUp '%c'", event->wParam);
        if (obj->testKeyboardFocusForPlugins) {
            obj->eventLogging = false;
            obj->testKeyboardFocusForPlugins = FALSE;
            executeScript(obj, "testRunner.notifyDone();");
        }
        break;
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
        if (obj->eventLogging)
            pluginLog(instance, "mouseDown at (%d, %d)", LOWORD(event->lParam), HIWORD(event->lParam));
        if (obj->evaluateScriptOnMouseDownOrKeyDown && obj->mouseDownForEvaluateScript)
            executeScript(obj, obj->evaluateScriptOnMouseDownOrKeyDown);
        break;
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
        if (obj->eventLogging)
            pluginLog(instance, "mouseUp at (%d, %d)", LOWORD(event->lParam), HIWORD(event->lParam));
        break;
    case WM_SETFOCUS:
        if (obj->eventLogging)
            pluginLog(instance, "getFocusEvent");
        break;
    case WM_KILLFOCUS:
        if (obj->eventLogging)
            pluginLog(instance, "loseFocusEvent");
        break;
    }
    return 0;
}
#endif // XP_WIN

int16_t NPP_HandleEvent(NPP instance, void *event)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);

    if (obj->pluginTest->NPP_HandleEvent(event) == 1)
        return 1;

#ifdef XP_MACOSX
    assert(obj->eventModel == NPEventModelCocoa);
    return handleEventCocoa(instance, obj, static_cast<NPCocoaEvent*>(event));
#elif defined(MOZ_X11)
    return handleEventX11(instance, obj, static_cast<XEvent*>(event));
#elif defined(XP_WIN)
    return handleEventWin(instance, obj, static_cast<NPEvent*>(event));
#else
    // FIXME: Implement for other platforms.
    return 0;
#endif // XP_MACOSX
}

void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    if (obj->pluginTest->NPP_URLNotify(url, reason, notifyData))
        return;

    if (obj->onURLNotify)
         executeScript(obj, obj->onURLNotify);

    handleCallback(obj, url, reason, notifyData);
}

void NPP_URLRedirectNotify(NPP instance, const char *url, int32_t status, void *notifyData)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    obj->pluginTest->NPP_URLRedirectNotify(url, status, notifyData);
}

NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
#if defined(XP_UNIX)
    if (variable == NPPVpluginNameString) {
        *((char **)value) = const_cast<char*>("WebKit Test PlugIn");
        return NPERR_NO_ERROR;
    }
    if (variable == NPPVpluginDescriptionString) {
        *((char **)value) = const_cast<char*>("Simple Netscape® plug-in that handles test content for WebKit");
        return NPERR_NO_ERROR;
    }
#endif

#if defined(MOZ_X11)
    if (variable == NPPVpluginNeedsXEmbed) {
        *((NPBool *)value) = TRUE;
        return NPERR_NO_ERROR;
    }
#endif

    if (!instance)
        return NPERR_GENERIC_ERROR;
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);

    // First, check if the PluginTest object supports getting this value.
    if (obj->pluginTest->NPP_GetValue(variable, value) == NPERR_NO_ERROR)
        return NPERR_NO_ERROR;

    if (variable == NPPVpluginScriptableNPObject) {
        void **v = (void **)value;
        // Return value is expected to be retained
        browser->retainobject((NPObject *)obj);
        *v = obj;
        return NPERR_NO_ERROR;
    }
    
#ifdef XP_MACOSX
    if (variable == NPPVpluginCoreAnimationLayer) {
        if (!obj->coreAnimationLayer)
            return NPERR_GENERIC_ERROR;
        
        void **v = (void **)value;
        *v = (void*)CFRetain(obj->coreAnimationLayer);
        return NPERR_NO_ERROR;
    }
#endif

    return NPERR_GENERIC_ERROR;
}

NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
{
    PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
    return obj->pluginTest->NPP_SetValue(variable, value);
}

#if defined(XP_UNIX)
extern "C" WTF_EXPORT_DECLARATION
const char* NP_GetMIMEDescription(void)
{
    return "application/x-webkit-test-netscape:testnetscape:test netscape content;image/png:png:PNG image";
}

extern "C" WTF_EXPORT_DECLARATION
NPError NP_GetValue(NPP instance, NPPVariable variable, void* value)
{
    return NPP_GetValue(instance, variable, value);
}
#endif
