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

requireClass ./NodeStore
requireClass ./CSSStore
requireClass ./ElementHighlighter
requireClass ./InjectedScriptHostImpl

requireClass ./WeinreTargetEventsImpl

requireClass ./WiConsoleImpl
requireClass ./WiCSSImpl
requireClass ./WiDatabaseImpl
requireClass ./WiDOMImpl
requireClass ./WiDOMStorageImpl
requireClass ./WiInspectorImpl
requireClass ./WiRuntimeImpl

//-----------------------------------------------------------------------------
class Target

//-----------------------------------------------------------------------------
static method main
    Weinre.target = new Target()
    Weinre.target.initialize()
    
    Weinre.addCSSProperties = function addCSSProperties(properties) {
        CSSStore.addCSSProperties(properties)
    }
    
//------------------------------------------------------------------------------
method setWeinreServerURLFromScriptSrc()
    if (window.WeinreServerURL) return
    
    var elements = document.getElementsByTagName("script")

    var scripts = ["Target.", "target-script.", "target-script-min."]
    for (var i=0; i<elements.length; i++) {
        var element = elements[i]
        
        for (j=0; j<scripts.length; j++) {
            if (-1 != element.src.indexOf("/" + scripts[j])) {
                var pattern = /(http:\/\/(.*?)\/)/
                var match   = pattern.exec(element.src)
                if (match) {
                    window.WeinreServerURL = match[1]
                    return 
                }
            }
        }
    }
    
    var message = "unable to calculate the weinre server url; explicity set the variable window.WeinreServerURL instead" 
    alert(message)
    throw new Ex(arguments, message)

//-----------------------------------------------------------------------------
method initialize()
    this.setWeinreServerURLFromScriptSrc()
    
    if (window.WeinreServerURL[window.WeinreServerURL.length-1] != "/") {
        window.WeinreServerURL += "/"
    }   
    
    var injectedScriptHost = new InjectedScriptHostImpl()
    Weinre.injectedScript = injectedScriptConstructor(injectedScriptHost, window, 0, "?")
    
    window.addEventListener("load", Binding(this, "onLoaded"), false)

    var messageDispatcher = new MessageDispatcher(window.WeinreServerURL + "ws/target")
    Weinre.messageDispatcher = messageDispatcher

    Weinre.wi = {}
    
    Weinre.wi.Console          = new WiConsoleImpl()
    Weinre.wi.CSS              = new WiCSSImpl()
    Weinre.wi.Database         = new WiDatabaseImpl()
    Weinre.wi.DOM              = new WiDOMImpl()
    Weinre.wi.DOMStorage       = new WiDOMStorageImpl()
    Weinre.wi.Inspector        = new WiInspectorImpl()
    Weinre.wi.Runtime          = new WiRuntimeImpl()
    
    messageDispatcher.registerInterface("Console",          Weinre.wi.Console          , false)
    messageDispatcher.registerInterface("CSS",              Weinre.wi.CSS              , false)
    messageDispatcher.registerInterface("Database",         Weinre.wi.Database         , false)
    messageDispatcher.registerInterface("DOM",              Weinre.wi.DOM              , false)
    messageDispatcher.registerInterface("DOMStorage",       Weinre.wi.DOMStorage       , false)
    messageDispatcher.registerInterface("Inspector",        Weinre.wi.Inspector        , false)
    messageDispatcher.registerInterface("Runtime",          Weinre.wi.Runtime          , false)
    
    messageDispatcher.registerInterface("WeinreTargetEvents", new WeinreTargetEventsImpl(), true)

    Weinre.wi.ApplicationCacheNotify = messageDispatcher.createProxy("ApplicationCacheNotify")
    Weinre.wi.ConsoleNotify          = messageDispatcher.createProxy("ConsoleNotify")
    Weinre.wi.DOMNotify              = messageDispatcher.createProxy("DOMNotify")
    Weinre.wi.DOMStorageNotify       = messageDispatcher.createProxy("DOMStorageNotify")
    Weinre.wi.DatabaseNotify         = messageDispatcher.createProxy("DatabaseNotify")
    Weinre.wi.InspectorNotify        = messageDispatcher.createProxy("InspectorNotify")
    Weinre.wi.TimelineNotify         = messageDispatcher.createProxy("TimelineNotify")
    
    Weinre.WeinreTargetCommands  = messageDispatcher.createProxy("WeinreTargetCommands")

    messageDispatcher.getWebSocket().addEventListener("open", Binding(this, this.cb_webSocketOpened))
    
    Weinre.nodeStore = new NodeStore()
    Weinre.cssStore  = new CSSStore()
    
    window.addEventListener("error", function(e) {Target.handleError(e)}, false)
    
    
//-----------------------------------------------------------------------------
static method handleError(event)
    var filename = event.filename || "[unknown filename]"
    var lineno   = event.lineno   || "[unknown lineno]"
    var message  = event.message  || "[unknown message]"

    Weinre.logError("error occurred: " + filename + ":" + lineno + ": " + message)

//-----------------------------------------------------------------------------
method cb_webSocketOpened()
    Weinre.WeinreTargetCommands.registerTarget(window.location.href, Binding(this, this.cb_registerTarget))

//-----------------------------------------------------------------------------
method cb_registerTarget(targetId)
    Weinre.targetId    = targetId
    Weinre.connectorId = targetId
    
    Callback.setConnectorId(targetId)

//-----------------------------------------------------------------------------
method onLoaded()

//-----------------------------------------------------------------------------
method setDocument()
    Weinre.elementHighlighter = new ElementHighlighter()
    
    var nodeId = Weinre.nodeStore.getNodeId(document)
    var nodeData = Weinre.nodeStore.getNodeData(nodeId, 2)

    Weinre.wi.DOMNotify.setDocument(nodeData)
