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

require ../common/Ex
require ../common/Binding
require ../common/Callback
require ../common/Socket
require ../common/Weinre

require ./NodeStore
require ./CSSStore
require ./ElementHighlighter
require ./InjectedScriptHostImpl

require ./WeinreTargetEventsImpl

// require ./WebInspectorApplicationCacheHandlerImpl
// require ./WebInspectorBackendHandlerImpl
// require ./WebInspectorControllerHandlerImpl
// require ./WebInspectorDOMHandlerImpl   
// require ./WebInspectorDebugHandlerImpl
// require ./WebInspectorProfilerHandlerImpl
// require ./WebInspectorResourceHandlerImpl

require ./WiApplicationCacheImpl
require ./WiBrowserDebuggerImpl
require ./WiCSSImpl
require ./WiConsoleImpl
require ./WiDOMImpl
require ./WiDOMStorageImpl
require ./WiDatabaseImpl
require ./WiDebuggerImpl
require ./WiInjectedScriptImpl
require ./WiInspectorImpl
require ./WiNetworkImpl
require ./WiProfilerImpl
require ./WiRuntimeImpl

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

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static method main
    Weinre.target = new Target()
    
    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 webSocket = new Socket(window.WeinreServerURL + "ws/target")
    Weinre.webSocket = webSocket

    Weinre.wi = {}
    
    Weinre.wi.ApplicationCache = new WiApplicationCacheImpl()
    Weinre.wi.BrowserDebugger  = new WiBrowserDebuggerImpl()
    Weinre.wi.Console          = new WiConsoleImpl()
    Weinre.wi.CSS              = new WiCSSImpl()
    Weinre.wi.Database         = new WiDatabaseImpl()
    Weinre.wi.Debugger         = new WiDebuggerImpl()
    Weinre.wi.DOM              = new WiDOMImpl()
    Weinre.wi.DOMStorage       = new WiDOMStorageImpl()
    Weinre.wi.InjectedScript   = new WiInjectedScriptImpl()
    Weinre.wi.Inspector        = new WiInspectorImpl()
    Weinre.wi.Network          = new WiNetworkImpl()
    Weinre.wi.Profiler         = new WiProfilerImpl()
    Weinre.wi.Runtime          = new WiRuntimeImpl()
    
    webSocket.registerInterface("ApplicationCache", Weinre.wi.ApplicationCache , true)
    webSocket.registerInterface("BrowserDebugger" , Weinre.wi.BrowserDebugger  , true)
    webSocket.registerInterface("Console",          Weinre.wi.Console          , true)
    webSocket.registerInterface("CSS",              Weinre.wi.CSS              , true)
    webSocket.registerInterface("Database",         Weinre.wi.Database         , true)
    webSocket.registerInterface("Debugger",         Weinre.wi.Debugger         , true)
    webSocket.registerInterface("DOM",              Weinre.wi.DOM              , true)
    webSocket.registerInterface("DOMStorage",       Weinre.wi.DOMStorage       , true)
    webSocket.registerInterface("InjectedScript",   Weinre.wi.InjectedScript   , true)
    webSocket.registerInterface("Inspector",        Weinre.wi.Inspector        , true)
    webSocket.registerInterface("Network",          Weinre.wi.Network          , true)
    webSocket.registerInterface("Profiler",         Weinre.wi.Profiler         , true)
    webSocket.registerInterface("Runtime",          Weinre.wi.Runtime          , true)
    
    webSocket.registerInterface("WeinreTargetEvents", new WeinreTargetEventsImpl(), true)

    Weinre.wi.ApplicationCacheNotify = webSocket.createProxy("ApplicationCacheNotify")
    Weinre.wi.ConsoleNotify          = webSocket.createProxy("ConsoleNotify")
    Weinre.wi.DOMNotify              = webSocket.createProxy("DOMNotify")
    Weinre.wi.DOMStorageNotify       = webSocket.createProxy("DOMStorageNotify")
    Weinre.wi.DatabaseNotify         = webSocket.createProxy("DatabaseNotify")
    Weinre.wi.DebuggerNotify         = webSocket.createProxy("DebuggerNotify")
    Weinre.wi.InspectorNotify        = webSocket.createProxy("InspectorNotify")
    Weinre.wi.NetworkNotify          = webSocket.createProxy("NetworkNotify")
    Weinre.wi.ProfilerNotify         = webSocket.createProxy("ProfilerNotify")
    Weinre.wi.TimelineNotify         = webSocket.createProxy("TimelineNotify")
    
    Weinre.WeinreTargetCommands  = webSocket.createProxy("WeinreTargetCommands")
//  window.WebInspector          = webSocket.createProxy("WebInspector")

//  Weinre.Socket.verbose(true)
//  webSocket.open()
    webSocket._socket.addEventListener("open", Binding(this, this.cb_webSocketOpened))
    
    Weinre.nodeStore = new NodeStore()
    Weinre.cssStore  = new CSSStore()

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