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

//-----------------------------------------------------------------------------
class WeinreClientEventsImpl(client)
    this.client = client

//-----------------------------------------------------------------------------
method clientRegistered(clientDescription)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.addClient(clientDescription)
    }

//-----------------------------------------------------------------------------
method targetRegistered(targetDescription)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.addTarget(targetDescription)
    }
    
    if (!Weinre.client.autoConnect()) return
    
    Weinre.WeinreClientCommands.connectTarget(Weinre.clientId, targetDescription.id)

//-----------------------------------------------------------------------------
method clientUnregistered(/*int*/ clientId)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.removeClient(clientId)
    }

//-----------------------------------------------------------------------------
method targetUnregistered(/*int*/ targetId)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.removeTarget(targetId)
    }

//-----------------------------------------------------------------------------
method connectionCreated(/*int*/ clientId, /*int*/ targetId)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.setClientState(clientId, "connected") 
        WebInspector.panels.remote.setTargetState(targetId, "connected")
    }
    
    if (clientId != Weinre.clientId) return

    Weinre.targetId = targetId
    
    WebInspector.panels.elements.reset()
    WebInspector.panels.timeline._clearPanel()
    WebInspector.panels.resources.reset()

//-----------------------------------------------------------------------------
method connectionDestroyed(/*int*/ clientId, /*int*/ targetId)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.setClientState(clientId, "not-connected") 
        WebInspector.panels.remote.setTargetState(targetId, "not-connected")
    }
    
    if (clientId != Weinre.clientId) return
    
    Weinre.targetId = null
    
    if (!Weinre.client.autoConnect()) return
    if (!this.client.uiAvailable()) return
    
    var nextTargetId = WebInspector.panels.remote.getNewestTargetId(targetId)
    if (!nextTargetId) return
    
    Weinre.WeinreClientCommands.connectTarget(Weinre.clientId, nextTargetId)
    Weinre.logInfo("autoconnecting to " + nextTargetId)

//-----------------------------------------------------------------------------
method sendCallback(/*int*/ callbackId, /*any*/ result)
    Callback.invoke(callbackId, result)

//-----------------------------------------------------------------------------
method serverProperties(/*any*/ properties)
    if (this.client.uiAvailable()) {
        WebInspector.panels.remote.setServerProperties(properties)
    }
