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

//-----------------------------------------------------------------------------
class NodeStore
    this.__nodeMap      = {}
    this.__nodeDataMap  = {}
    this.inspectedNodes = []
    
    document.addEventListener("DOMSubtreeModified",       handleDOMSubtreeModified, false)
    document.addEventListener("DOMNodeInserted",          handleDOMNodeInserted, false)
    document.addEventListener("DOMNodeRemoved",           handleDOMNodeRemoved, false)
    document.addEventListener("DOMAttrModified",          handleDOMAttrModified, false)
    document.addEventListener("DOMCharacterDataModified", handleDOMCharacterDataModified, false)

//-----------------------------------------------------------------------------
method addInspectedNode(nodeId)
    this.inspectedNodes.unshift(nodeId)
    if (this.inspectedNodes.length > 5) {
        this.inspectedNodes = this.inspectedNodes.slice(0,5)
    }

//-----------------------------------------------------------------------------
method getInspectedNode(index)
    return this.inspectedNodes[index]

//-----------------------------------------------------------------------------
method getNode(nodeId)
    return this.__nodeMap[nodeId]

//-----------------------------------------------------------------------------
method checkNodeId(node)
    return IDGenerator.checkId(node)

//-----------------------------------------------------------------------------
method getNodeId(node)
    var id = this.checkNodeId(node)
    if (id) {
        return id
    }

    return IDGenerator.getId(node, this.__nodeMap)    

//-----------------------------------------------------------------------------
method getNodeData(nodeId, depth)
    return this.serializeNode(this.getNode(nodeId), depth)

//-----------------------------------------------------------------------------
method getPreviousSiblingId(node)
    while (true) {
        var sib = node.previousSibling
        if (!sib) return 0
        
        var id = this.checkNodeId(sib)
        if (id) return id
        
        node = sib
    }

//-----------------------------------------------------------------------------
method nextNodeId()
    return "" + IDGenerator.next()

//-----------------------------------------------------------------------------
method serializeNode(node, depth)
    var nodeName  = ""
    var nodeValue = null
    var localName = null
    var id = this.getNodeId(node) 
    
    switch(node.nodeType) {
        case Node.TEXT_NODE:    
        case Node.COMMENT_NODE:
        case Node.CDATA_SECTION_NODE:
            nodeValue = node.nodeValue
            break
        case Node.ATTRIBUTE_NODE:
            localName = node.localName
            break
        case Node.DOCUMENT_FRAGMENT_NODE:
            break
        case Node.DOCUMENT_NODE:
        case Node.ELEMENT_NODE:
        default:
            nodeName  = node.nodeName
            localName = node.localName
            break
    }
    
    var nodeData = {
        id:        id,
        nodeType:  node.nodeType,
        nodeName:  nodeName,
        localName: localName,
        nodeValue: nodeValue
    }
    
    if (node.nodeType == Node.ELEMENT_NODE || node.nodeType == Node.DOCUMENT_NODE || node.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
        nodeData.childNodeCount = this.childNodeCount(node)
        var children = this.serializeNodeChildren(node, depth)
        if (children.length) {
            nodeData.children = children
        }
        
        if (node.nodeType == Node.ELEMENT_NODE) {
            nodeData.attributes = []
            for (var i=0; i<node.attributes.length; i++) {
                nodeData.attributes.push(node.attributes[i].nodeName)
                nodeData.attributes.push(node.attributes[i].nodeValue)
            }
        } 
        
        else if (node.nodeType == Node.DOCUMENT_NODE) {
            nodeData.documentURL = window.location.href
        }
    } 
    
    else if (node.nodeType == Node.DOCUMENT_TYPE_NODE) {
        nodeData.publicId       = node.publicId
        nodeData.systemId       = node.systemId
        nodeData.internalSubset = node.internalSubset
    } 
    
    else if (node.nodeType == Node.ATTRIBUTE_NODE) {
        nodeData.name  = node.nodeName
        nodeData.value = node.nodeValue
    }

    return nodeData

//-----------------------------------------------------------------------------
method serializeNodeChildren(node, depth)
    var result   = []
    var childIds = this.childNodeIds(node)
    
    if (depth == 0) {
        if (childIds.length == 1) {
            var childNode = this.getNode(childIds[0])
            if (childNode.nodeType == Node.TEXT_NODE) {
                result.push(this.serializeNode(childNode))
            }
        }
        return result
    }
    
    depth--;
    for (var i=0; i<childIds.length; i++) {
        result.push(this.serializeNode(this.getNode(childIds[i]), depth))
    }
    
    return result

//-----------------------------------------------------------------------------
method childNodeCount(node)
    return this.childNodeIds(node).length

//-----------------------------------------------------------------------------
method childNodeIds(node)
    var ids = []
    
    for (var i=0; i<node.childNodes.length; i++) {
        if (this.isToBeSkipped(node.childNodes[i])) continue
        ids.push(this.getNodeId(node.childNodes[i]))
    }
    
    return ids

//-----------------------------------------------------------------------------
method isToBeSkipped(node)
    if (!node) return true
    if (node.__weinreHighlighter) return true 
    if (node.nodeType != Node.TEXT_NODE) return false
    return !!node.nodeValue.match(/^\s*$/) 

//-----------------------------------------------------------------------------
function handleDOMSubtreeModified(event)
    if (!event.attrChange) return
    
    NodeStore.handleDOMAttrModified(event)

//-----------------------------------------------------------------------------
function handleDOMNodeInserted(event)
    var targetId = Weinre.nodeStore.checkNodeId(event.target)
    var parentId = Weinre.nodeStore.checkNodeId(event.relatedNode)
    
    if (!parentId) return
    
    var child = Weinre.nodeStore.serializeNode(event.target, 0)
    var previous = Weinre.nodeStore.getPreviousSiblingId(event.target)
    Weinre.wi.DOMNotify.childNodeInserted(parentId, previous, child)

//-----------------------------------------------------------------------------
function handleDOMNodeRemoved(event)
    var targetId = Weinre.nodeStore.checkNodeId(event.target)
    var parentId = Weinre.nodeStore.checkNodeId(event.relatedNode)
    
    if (!parentId) return
    
    if (targetId) {
        Weinre.wi.DOMNotify.childNodeRemoved(parentId, targetId)
    }
    else {
        var childCount = Weinre.nodeStore.childNodeCount(event.relatedNode)
        Weinre.wi.DOMNotify.childNodeCountUpdated(parentId, childCount)
    }

//-----------------------------------------------------------------------------
// This event is not actually fired in WebKit, but DOMSubtreeModified may
// be fired for attribute changes.  Doesn't seem to be at the moment.
function handleDOMAttrModified(event)
    var targetId = Weinre.nodeStore.checkNodeId(event.target)
    if (!targetId) return
    
    attrs = []
    for (var i=0; i<event.target.attributes.length; i++) {
        attrs.push(event.target.attributes[i].name)
        attrs.push(event.target.attributes[i].value)
    }
    
    Weinre.wi.DOMNotify.attributesUpdated(targetId, attrs)

//-----------------------------------------------------------------------------
function handleDOMCharacterDataModified(event)
    var targetId = Weinre.nodeStore.checkNodeId(event.target)
    if (!targetId) return
    
    Weinre.wi.DOMNotify.characterDataModified(targetId, event.newValue)
