/*
 * 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

}
