
/*
 * 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) 2011 IBM Corporation
 */

requireClass ../common/Weinre

//-----------------------------------------------------------------------------
class WiCSSImpl
    this.dummyComputedStyle = false

//-----------------------------------------------------------------------------
method getStylesForNode(/*int*/ nodeId, callback)
    var result = {}
    
    var node = Weinre.nodeStore.getNode(nodeId)
    if (!node) {
        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
        return
    }
    
    var computedStyle
    
    if (this.dummyComputedStyle) {
        computedStyle = {
            styleId:            null,
            properties:         [],
            shorthandValues:    [],
            cssProperties:      []
        }
    }
    else {
        computedStyle =  Weinre.cssStore.getComputedStyle(node)
    }
    
    var result = {
        inlineStyle:     Weinre.cssStore.getInlineStyle(node),
        computedStyle:   computedStyle,
        matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(node),
        styleAttributes: Weinre.cssStore.getStyleAttributes(node),
        pseudoElements:  Weinre.cssStore.getPseudoElements(node),
        inherited:       []
    }
    
    var parentNode = node.parentNode
    
    while (parentNode) {
        var parentStyle = {
            inlineStyle:     Weinre.cssStore.getInlineStyle(parentNode),
            matchedCSSRules: Weinre.cssStore.getMatchedCSSRules(parentNode),
        }
        
        result.inherited.push(parentStyle)
        parentNode = parentNode.parentNode
    }
    
    if (callback) {
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }

//-----------------------------------------------------------------------------
method getComputedStyleForNode(/*int*/ nodeId, callback)
    var node = Weinre.nodeStore.getNode(nodeId)
    if (!node) {
        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
        return
    }

    var result = Weinre.cssStore.getComputedStyle(node) 

    if (callback) {
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }


//-----------------------------------------------------------------------------
method getInlineStyleForNode(/*int*/ nodeId, callback)
    var node = Weinre.nodeStore.getNode(nodeId)
    if (!node) {
        Weinre.logWarning(arguments.callee.signature + " passed an invalid nodeId: " + nodeId)
        return
    }

    var result = Weinre.cssStore.getInlineStyle(node)

    if (callback) {
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }

//-----------------------------------------------------------------------------
method getAllStyles(callback)
    // callback: function(/*any[]*/ styleSheetIds)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method getStyleSheet(/*string*/ styleSheetId, callback)
    // callback: function(/*any*/ styleSheet)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method getStyleSheetText(/*string*/ styleSheetId, callback)
    // callback: function(/*string*/ url, /*string*/ text)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method setStyleSheetText(/*string*/ styleSheetId, /*string*/ text, callback)
    // callback: function(/*boolean*/ success)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method setPropertyText(/*any*/ styleId, /*int*/ propertyIndex, /*string*/ text, /*boolean*/ overwrite, callback)
    // callback: function(/*any*/ style)
    var style = Weinre.cssStore.getStyle(styleId)
    if (!style) {
        Weinre.logWarning("requested style not available: " + styleId)
        return
    }
    
    var newProperties = []
    newPropertyLines = text.split(";")
    for (var i=0; i<newPropertyLines.length; i++) {
        var parts = newPropertyLines[i].split(":", 2)
        if (parts[0] && parts[1]) {
            newProperties.push([parts[0], parts[1]])
        }
    }
    
    var oldProperties = []
    for (var i=0; i<style.length; i++) {
        var name = style.item(i)
        var value = style.getPropertyValue(name)
        oldProperties.push([name, value])
    }

    for (var i=0; i<oldProperties.length; i++) {
        style.removeProperty(oldProperties[i][0])
    }
        
    for (var i=0; i<oldProperties.length; i++) {
        if (i == propertyIndex) {
            for (var j=0; j<newProperties.length; j++) {
                style.setProperty(newProperties[j][0], newProperties[j][1])
            }
            continue
        }
        
        style.setProperty(oldProperties[i][0], oldProperties[i][1])
    }
    
    if (propertyIndex >= oldProperties.length) {
        for (var j=0; j<newProperties.length; j++) {
            style.setProperty(newProperties[j][0], newProperties[j][1])
        }
    }
    
    if (callback) {
        var result = Weinre.cssStore.buildObjectForStyle(style, true)
        Weinre.WeinreTargetCommands.sendClientCallback(callback, [result])
    }

//-----------------------------------------------------------------------------
method toggleProperty(/*any*/ styleId, /*int*/ propertyIndex, /*boolean*/ disable, callback)
    // callback: function(/*any*/ style)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method setRuleSelector(/*any*/ ruleId, /*string*/ selector, callback)
    // callback: function(/*any*/ rule)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method addRule(/*int*/ contextNodeId, /*string*/ selector, callback)
    // callback: function(/*any*/ rule)
    Weinre.notImplemented(arguments.callee.signature)


//-----------------------------------------------------------------------------
method getSupportedCSSProperties(callback)
    return Weinre.getCSSProperties()


//-----------------------------------------------------------------------------
method querySelectorAll(/*int*/ documentId, /*string*/ selector, callback)
    // callback: function(/*any[]*/ result)
    Weinre.notImplemented(arguments.callee.signature)
