
/*
 * 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/IDLTools
requireClass ../common/Callback
requireClass ../common/Weinre
requireClass ../common/MessageDispatcher
requireClass ../common/Binding

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

//-----------------------------------------------------------------------------
class Client
    this.initialize()

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

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

    return AutoConnect

//-----------------------------------------------------------------------------
method autoConnect(value)
    if (arguments.length >= 1) {
        return Client.autoConnect(value)
    }
    else {
        return Client.autoConnect()
    }

//-----------------------------------------------------------------------------
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")
    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)

//-----------------------------------------------------------------------------
method uiAvailable
    return WebInspector.panels && WebInspector.panels.remote
    
//-----------------------------------------------------------------------------
method _installRemotePanelEventually
    var self = this
    
    setTimeout(function() {
        var wait = false
        if (!WebInspector.applicationSettings) wait = true
        
        if (wait) {
            self._installRemotePanelEventually()
            return
        }
        
        self._installRemotePanel()
    }, 10)


//-----------------------------------------------------------------------------
method _installRemotePanel

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

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

    this._installRemotePanel()

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

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

//-----------------------------------------------------------------------------
method cb_registerClient(clientId)
    Weinre.clientId = clientId
    Weinre.connectorId = clientId
    Callback.setConnectorId(clientId)
    
    if (this.uiAvailable()) {
        WebInspector.panels.remote.setCurrentClient(clientId)
        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
    setTimeout(function() {
        WebInspector.panels.remote.connectionClosed()
        WebInspector.currentPanel = WebInspector.panels.remote 
    }, 1000)

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