/*
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
 *
 * 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. 
 */

#import "config.h"
#import "ScriptController.h"

#import "Bridge.h"
#import "DOMAbstractViewFrame.h"
#import "DOMWindow.h"
#import "Frame.h"
#import "FrameLoader.h"
#import "FrameLoaderClient.h"
#import "JSDOMWindow.h"
#import "WebScriptObjectPrivate.h"
#import "Widget.h"
#import "objc_instance.h"
#import "runtime_root.h"
#import <JavaScriptCore/APICast.h>
#import <runtime/JSLock.h>

#if ENABLE(NETSCAPE_PLUGIN_API)
#import "c_instance.h"
#import "NP_jsobject.h"
#import "npruntime_impl.h"
#endif

#if ENABLE(MAC_JAVA_BRIDGE)
#import "JavaInstanceJSC.h"
#endif

@interface NSObject (WebPlugin)
- (id)objectForWebScript;
- (NPObject *)createPluginScriptableObject;
- (PassRefPtr<JSC::Bindings::Instance>)createPluginBindingsInstance:(PassRefPtr<JSC::Bindings::RootObject>)rootObject;
@end

using namespace JSC::Bindings;

namespace WebCore {

PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
{
    NSView* widgetView = widget->platformWidget();
    if (!widgetView)
        return 0;

    RefPtr<RootObject> rootObject = createRootObject(widgetView);

    if ([widgetView respondsToSelector:@selector(createPluginBindingsInstance:)])
        return [widgetView createPluginBindingsInstance:rootObject.release()];
        
    if ([widgetView respondsToSelector:@selector(objectForWebScript)]) {
        id objectForWebScript = [widgetView objectForWebScript];
        if (!objectForWebScript)
            return 0;
        return JSC::Bindings::ObjcInstance::create(objectForWebScript, rootObject.release());
    }

    if ([widgetView respondsToSelector:@selector(createPluginScriptableObject)]) {
#if !ENABLE(NETSCAPE_PLUGIN_API)
        return 0;
#else
        NPObject* npObject = [widgetView createPluginScriptableObject];
        if (!npObject)
            return 0;
        RefPtr<Instance> instance = JSC::Bindings::CInstance::create(npObject, rootObject.release());
        // -createPluginScriptableObject returns a retained NPObject.  The caller is expected to release it.
        _NPN_ReleaseObject(npObject);
        return instance.release();
#endif
    }

#if ENABLE(MAC_JAVA_BRIDGE)
    jobject applet = m_frame->loader()->client()->javaApplet(widgetView);
    if (!applet)
        return 0;
    return JSC::Bindings::JavaInstance::create(applet, rootObject.release());
#else
    return 0;
#endif
}

WebScriptObject* ScriptController::windowScriptObject()
{
    if (!canExecuteScripts(NotAboutToExecuteScript))
        return 0;

    if (!m_windowScriptObject) {
        JSC::JSLock lock(JSC::SilenceAssertionsOnly);
        JSC::Bindings::RootObject* root = bindingRootObject();
        m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell(pluginWorld())) originRootObject:root rootObject:root];
    }

    ASSERT([m_windowScriptObject.get() isKindOfClass:[DOMAbstractView class]]);
    return m_windowScriptObject.get();
}

void ScriptController::updatePlatformScriptObjects()
{
    if (m_windowScriptObject) {
        JSC::Bindings::RootObject* root = bindingRootObject();
        [m_windowScriptObject.get() _setOriginRootObject:root andRootObject:root];
    }
}

void ScriptController::disconnectPlatformScriptObjects()
{
    if (m_windowScriptObject) {
        ASSERT([m_windowScriptObject.get() isKindOfClass:[DOMAbstractView class]]);
        [(DOMAbstractView *)m_windowScriptObject.get() _disconnectFrame];
    }
}

#if ENABLE(MAC_JAVA_BRIDGE)

static pthread_t mainThread;

static void updateStyleIfNeededForBindings(JSC::ExecState*, JSC::JSObject* rootObject)
{
    if (pthread_self() != mainThread)
        return;

    if (!rootObject)
        return;

    JSDOMWindow* window = static_cast<JSDOMWindow*>(rootObject);
    if (!window)
        return;

    Frame* frame = window->impl()->frame();
    if (!frame)
        return;

    frame->document()->updateStyleIfNeeded();
}

void ScriptController::initJavaJSBindings()
{
    mainThread = pthread_self();
    JSC::Bindings::JavaJSObject::initializeJNIThreading();
    JSC::Bindings::Instance::setDidExecuteFunction(updateStyleIfNeededForBindings);
}

#endif

}
