
/*
 * weinre is available under *either* the terms of the modified BSD license *or* the
 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
 * 
 * Copyright (c) 2010, 2011 IBM Corporation
 */

requireClass ../common/Native

requireClass ../common/IDLTools
requireClass ../common/Callback
requireClass ../common/Weinre
requireClass ../common/MessageDispatcher
requireClass ../common/Binding
requireClass ../common/IDGenerator

requireClass ./InspectorBackendImpl
requireClass ./InspectorFrontendHostImpl
requireClass ./WeinreClientEventsImpl
requireClass ./RemotePanel

//-----------------------------------------------------------------------------
class Client

//-----------------------------------------------------------------------------
init
    var AutoConnect = true
    
    Weinre.showNotImplemented()

//-----------------------------------------------------------------------------
method initialize

    // validate InspectorFrontendHost against IDL
    // IDLTools.validateAgainstIDL(InspectorFrontendHostImpl, 'InspectorFrontendHost')

    // add a load handler for the window
    window.addEventListener("load", Binding(this, "onLoaded"), false)

    // create the socket
    var messageDispatcher = new MessageDispatcher("../ws/client", this._getId())
    Weinre.messageDispatcher = messageDispatcher

    // finish setting up InspectorBackend
    InspectorBackendImpl.setupProxies()

    // create the client commands proxy
    Weinre.WeinreClientCommands = messageDispatcher.createProxy("WeinreClientCommands")

    // register WebInspector interface
    messageDispatcher.registerInterface("WebInspector", WebInspector, false)
    
    // hack
    WebInspector.mainResource = {}
    WebInspector.mainResource.url = location.href

//-----------------------------------------------------------------------------
method _getId
    var hash = location.href.split("#")[1]
    if (hash) return hash
    return "anonymous"

//-----------------------------------------------------------------------------
method uiAvailable
    return WebInspector.panels && WebInspector.panels.remote
    
//-----------------------------------------------------------------------------
method autoConnect(value)
    if (arguments.length >= 1) {
        AutoConnect = !!value
    }

    return AutoConnect

//-----------------------------------------------------------------------------
method _installRemotePanel
    WebInspector.panels.remote = new RemotePanel();
    
    var panel   = WebInspector.panels.remote;
    
    var toolbar = document.getElementById("toolbar")
    WebInspector.addPanelToolbarIcon(toolbar, panel, toolbar.childNodes[1])
    WebInspector.panelOrder.unshift(WebInspector.panelOrder.pop())
    
    WebInspector.currentPanel = panel
    
    var toolButtonsToHide = ["scripts"]
    toolButtonsToHide.forEach(function(toolButtonToHide){
        if (!WebInspector.panels[toolButtonToHide]) return
        if (!WebInspector.panels[toolButtonToHide].toolbarItem) return
        WebInspector.panels[toolButtonToHide].toolbarItem.style.display = "none"
    })
    
    var button = document.getElementById("dock-status-bar-item")
    if (button) button.style.display = "none"

//-----------------------------------------------------------------------------
method onLoaded

    Weinre.WeinreClientCommands.registerClient(Binding(this, this.cb_registerClient))

    this._installRemotePanel()

    var messageDispatcher = Weinre.messageDispatcher
    
//  Weinre.Socket.verbose(true)
    
    messageDispatcher.registerInterface("WeinreClientEvents",    new WeinreClientEventsImpl(this), false)
    messageDispatcher.registerInterface("InspectorFrontendHost", InspectorFrontendHost, false)

//-----------------------------------------------------------------------------
method cb_registerClient(clientDescription)
    Weinre.clientDescription = clientDescription
    
    if (this.uiAvailable()) {
        WebInspector.panels.remote.setCurrentClient(clientDescription.channel)
        WebInspector.panels.remote.afterInitialConnection()
    }
    
    Weinre.messageDispatcher.getWebSocket().addEventListener("close", Binding(this, this.cb_webSocketClosed))

//-----------------------------------------------------------------------------
method cb_webSocketClosed
    
    // use a delay, otherwise reloading will cause this stuff to flash
    // before page is actually reloaded
    Native.setTimeout(function() {
        WebInspector.panels.remote.connectionClosed()
        WebInspector.currentPanel = WebInspector.panels.remote 
    }, 1000)

//-----------------------------------------------------------------------------
function installWebInspectorAPIsource

    if ("webInspector" in window) return
    
    var extensionAPI = window.parent.InspectorFrontendHost.getExtensionAPI()
    extensionAPI = extensionAPI.replace("location.hostname + location.port", "location.hostname + ':' + location.port")
    
    // parms are: InjectedScriptHost, inspectedWindow, injectedScriptId
    // InjectedScriptHost is not directly referenced
    // inspectedWindow is not directly referenced
    // injectedScriptId is used to scope object references, appears that
    //     each extension should have a unique value for this
    
    var id = IDGenerator.next()
    console.log("installing webInspector with injectedScriptId: " + id)
    extensionAPI += "(null,null," + id + ")"
    return extensionAPI

//-----------------------------------------------------------------------------
static method main
    Weinre.client = new Client()
    Weinre.client.initialize()

    window.installWebInspectorAPIsource = installWebInspectorAPIsource