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

//-----------------------------------------------------------------------------
class CSSStore
    this.__styleMap    = {}
    this.__nextId      = 0

//-----------------------------------------------------------------------------
init
    var Properties = []

//-----------------------------------------------------------------------------
static method addCSSProperties(properties)
    Properties = properties

//-----------------------------------------------------------------------------
method getStyle(styleId)
    return this.__styleMap[styleId]

//-----------------------------------------------------------------------------
method getStyleId(style)
    if (style.__weinre_id) { 
        return style.__weinre_id
    }
    
    style.__weinre_id = this._nextId()
    this.__styleMap[style.__weinre_id] = style
    
    return style.__weinre_id

//-----------------------------------------------------------------------------
method getInlineStyle(node)
    var styleObject = this.buildObjectForStyle(node.style, true)
    for (var i=0; i<styleObject.cssProperties.length; i++) {
        styleObject.cssProperties[i].status = "style"
    }
    return styleObject

//-----------------------------------------------------------------------------
method getComputedStyle(node)
    if (!node) return {}
    if (node.nodeType != Node.ELEMENT_NODE) return {}
    
    var styleObject = this.buildObjectForStyle(window.getComputedStyle(node), false)
    return styleObject

//-----------------------------------------------------------------------------
method getMatchedCSSRules(node)
    var result = []
    
    for (var i=0; i<document.styleSheets.length; i++) {
        var cssStyleSheet = document.styleSheets[i]
        
        if (!cssStyleSheet.cssRules) continue
        
        for (var j=0; j<cssStyleSheet.cssRules.length; j++) {
            var cssRule = cssStyleSheet.cssRules[j]
            
            if (!elementMatchesSelector(node, cssRule.selectorText)) continue
            
            var object = {}
            
            object.ruleId = this.getStyleId(cssRule)
            object.selectorText = cssRule.selectorText
            object.style = this.buildObjectForStyle(cssRule.style, true)
            result.push(object)
        }
    }
    
    return result

//-----------------------------------------------------------------------------
method getStyleAttributes(node)
    var result = {}
    
    return result

//-----------------------------------------------------------------------------
method getPseudoElements(node)
    var result = []
    
    return result

//-----------------------------------------------------------------------------
method buildObjectForStyle(style, bind)
    var result = {
        width:         null,
        height:        null,
        properties:    [],
        cssProperties: []
    }
    
    if (!style) return result
    
    if (bind) {
        var styleId = this.getStyleId(style)
        result.id = styleId

        /*
        CSSStyleSheet* parentStyleSheet = InspectorCSSStore::getParentStyleSheet(style);
        if (parentStyleSheet)
            result->setNumber("parentStyleSheetId", cssStore()->bindStyleSheet(parentStyleSheet));

        DisabledStyleDeclaration* disabledStyle = cssStore()->disabledStyleForId(styleId, false);
        if (disabledStyle)
            result->setArray("disabled", buildArrayForDisabledStyleProperties(disabledStyle));
        */
    }
    
    result.width  = style.getPropertyValue("width")
    result.height = style.getPropertyValue("height")

    this.populateObjectWithStyleProperties(style, result)
    
    return result

//-----------------------------------------------------------------------------
method populateObjectWithStyleProperties(style, result)
    var properties = []
    var shorthandValues = {}

    if (style) {
        var foundShorthands = {}
        for (var i=0; i < style.length; i++) {
            var property = {}
            var name = style.item(i)

            property.name = name
            property.priority = style.getPropertyPriority(name)
            property.implicit = false // style.isPropertyImplicit(name)
            property.shorthand = ""
            property.status    = "active"
            property.parsedOk  = true
            property.value     = style.getPropertyValue(name)

            properties.push(property);
        }
    }
    
    result.cssProperties   = properties
    result.shorthandValues = shorthandValues

//-----------------------------------------------------------------------------
method _nextId
    return "" + (++this.__nextId)
    
//-----------------------------------------------------------------------------
function mozMatchesSelector(element, selector)
    if (!element.mozMatchesSelector) return false
    return element.mozMatchesSelector(selector)

//-----------------------------------------------------------------------------
function webkitMatchesSelector(element, selector)
    if (!element.webkitMatchesSelector) return false
    return element.webkitMatchesSelector(selector)

//-----------------------------------------------------------------------------
function fallbackMatchesSelector(element, selector)
    return false
    
//-----------------------------------------------------------------------------
init
    var elementMatchesSelector
    
    if      (Element.prototype.webkitMatchesSelector) elementMatchesSelector = webkitMatchesSelector 
    else if (Element.prototype.mozMatchesSelector)    elementMatchesSelector = mozMatchesSelector
    else                                              elementMatchesSelector = fallbackMatchesSelector