
/*
 * 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 ./CheckForProblems
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
    CheckForProblems.check()
    
    Weinre.target = new Target()
    Weinre.target.initialize()
    
    Weinre.addCSSProperties = function addCSSProperties(properties) {
        CSSStore.addCSSProperties(properties)
    }
    
//------------------------------------------------------------------------------
method setWeinreServerURLFromScriptSrc()
    if (window.WeinreServerURL) return

    var element = this.getTargetScriptElement()
    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 setWeinreServerIdFromScriptSrc()
    if (window.WeinreServerId) return

    var element = this.getTargetScriptElement()

    var hash = element.src.split("#")[1]
    if (!hash) hash = "anonymous"
    
    window.WeinreServerId = hash

//-----------------------------------------------------------------------------
method getTargetScriptElement

    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])) {
                return element
            }
        }
    }

//-----------------------------------------------------------------------------
method initialize()
    var self = this

    this.setWeinreServerURLFromScriptSrc()
    this.setWeinreServerIdFromScriptSrc()
    
    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)
    document.addEventListener("DOMContentLoaded", Binding(this, "onDOMContent"), false)
    
    this._startTime = currentTime()
    
    if (document.readyState == "loaded") {
        setTimeout(function() { self.onDOMContent() }, 10)
    }
    
    if (document.readyState == "complete") {
        setTimeout(function() { self.onDOMContent() }, 10)
        setTimeout(function() { self.onLoaded() }, 20)
    }

    var messageDispatcher = new MessageDispatcher(window.WeinreServerURL + "ws/target", window.WeinreServerId)
    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(targetDescription)
    Weinre.targetDescription    = targetDescription

//-----------------------------------------------------------------------------
method onLoaded
    Weinre.wi.InspectorNotify.loadEventFired(currentTime() - this._startTime)

//-----------------------------------------------------------------------------
method onDOMContent
    Weinre.wi.InspectorNotify.domContentEventFired(currentTime() - this._startTime)

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

    Weinre.wi.DOMNotify.setDocument(nodeData)
    
//-----------------------------------------------------------------------------
// WebKit's currentTime() seems to return time in seconds
function currentTime()
    return (new Date().getMilliseconds()) / 1000.0