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

//-----------------------------------------------------------------------------
class CSSStore
    this.styleSheetMap = {}
    this.styleRuleMap  = {}
    this.styleDeclMap  = {}
    this.testElement = document.createElement("div")

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

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

//-----------------------------------------------------------------------------
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 styleSheet = document.styleSheets[i]
        
        if (!styleSheet.cssRules) continue
        
        for (var j=0; j<styleSheet.cssRules.length; j++) {
            var cssRule = styleSheet.cssRules[j]
            
            if (!_elementMatchesSelector(node, cssRule.selectorText)) continue
            
            var object = {}
            
            object.ruleId = this._getStyleRuleId(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(styleDecl, bind)
    var result = {
        width:         null,
        height:        null,
        properties:    [],
        cssProperties: []
    }
    
    if (!styleDecl) return result
    
    if (bind) {
        result.styleId = this._getStyleDeclId(styleDecl)
    }
    
    result.width  = styleDecl.getPropertyValue("width")
    result.height = styleDecl.getPropertyValue("height")

    this._populateObjectWithStyleDeclProperties(styleDecl, result)
    
    return result

//-----------------------------------------------------------------------------
method _populateObjectWithStyleDeclProperties(styleDecl, result)
    var properties = []
    var shorthandValues = {}

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

            property.name          = name
            property.priority      = styleDecl.getPropertyPriority(name)
            property.implicit      = styleDecl.isPropertyImplicit(name)
            property.shorthandName = styleDecl.getPropertyShorthand(name)
            property.status        = "active"
            property.parsedOk      = true
            property.value         = styleDecl.getPropertyValue(name)
            
            if (property.shorthandName) {
                if (!shorthandValues[property.shorthandName]) {
                    shorthandValues[property.shorthandName] = styleDecl.getPropertyValue(property.shorthandName)
                }
            }

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

//-----------------------------------------------------------------------------
method _getStyleSheet(id)
    return _getMappableObject(id, this.styleSheetMap)

//-----------------------------------------------------------------------------
method _getStyleSheetId(styleSheet)
    return _getMappableId(styleSheet, this.styleSheetMap)

//-----------------------------------------------------------------------------
method _getStyleRule(id)
    return _getMappableObject(id, this.styleRuleMap)

//-----------------------------------------------------------------------------
method _getStyleRuleId(styleRule)
    return _getMappableId(styleRule, this.styleRuleMap)

//-----------------------------------------------------------------------------
method _getStyleDecl(id)
    return _getMappableObject(id, this.styleDeclMap)

//-----------------------------------------------------------------------------
method _getStyleDeclId(styleDecl)
    var id = _getMappableId(styleDecl, this.styleDeclMap)
    
    this._buildShadowDecl(styleDecl)
    
    return id

//-----------------------------------------------------------------------------
method _buildShadowDecl(styleDecl)
    

//-----------------------------------------------------------------------------
function _getMappableObject(id, map)
    return map[id]

//-----------------------------------------------------------------------------
function _getMappableId(object, map)
    return IDGenerator.getId(object, map)
    
//-----------------------------------------------------------------------------
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