////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.styles
{
/*
import flash.display.DisplayObject;
import flash.events.EventDispatcher;
import flash.utils.Dictionary;

import mx.core.Singleton;
import mx.core.mx_internal;
import mx.events.FlexChangeEvent;
import mx.managers.ISystemManager;
import mx.managers.SystemManagerGlobals;
import mx.utils.ObjectUtil;

use namespace mx_internal;
*/
import org.apache.royale.events.EventDispatcher;
import org.apache.royale.core.ValuesManager;

/**
 *  The CSSStyleDeclaration class represents a set of CSS style rules.
 *  The MXML compiler automatically generates one CSSStyleDeclaration object
 *  for each selector in the CSS files associated with a Flex application.
 *  
 *  <p>A CSS rule such as
 *  <pre>
 *      Button { color: #FF0000 }
 *  </pre>
 *  affects every instance of the Button class;
 *  a selector like <code>Button</code> is called a type selector
 *  and must not start with a dot.</p>
 *
 *  <p>A CSS rule such as
 *  <pre>
 *      .redButton { color: #FF0000 }
 *  </pre>
 *  affects only components whose <code>styleName</code> property
 *  is set to <code>"redButton"</code>;
 *  a selector like <code>.redButton</code> is called a class selector
 *  and must start with a dot.</p>
 *
 *  <p>You can access the autogenerated CSSStyleDeclaration objects
 *  using the <code>StyleManager.getStyleDeclaration()</code> method,
 *  passing it either a type selector
 *  <pre>
 *  var buttonDeclaration:CSSStyleDeclaration =
 *      StyleManager.getStyleDeclaration("Button");
 *  </pre>
 *  or a class selector
 *  <pre>
 *  var redButtonStyleDeclaration:CSSStyleDeclaration =
 *      StyleManager.getStyleDeclaration(".redButton");
 *  </pre>
 *  </p>
 *
 *  <p>You can use the <code>getStyle()</code>, <code>setStyle()</code>,
 *  and <code>clearStyle()</code> methods to get, set, and clear 
 *  style properties on a CSSStyleDeclaration.</p>
 *
 *  <p>You can also create and install a CSSStyleDeclaration at run time
 *  using the <code>StyleManager.setStyleDeclaration()</code> method:
 *  <pre>
 *  var newStyleDeclaration:CSSStyleDeclaration = new CSSStyleDeclaration(".bigMargins");
 *  newStyleDeclaration.defaultFactory = function():void
 *  {
 *      leftMargin = 50;
 *      rightMargin = 50;
 *  }
 *  StyleManager.setStyleDeclaration(".bigMargins", newStyleDeclaration, true);
 *  </pre>
 *  </p>
 *
 *  @see mx.core.UIComponent
 *  @see mx.styles.StyleManager
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class CSSStyleDeclaration extends EventDispatcher
{
//    include "../core/Version.as";
        
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @param selector - If the selector is a CSSSelector then advanced
     *  CSS selectors are supported. If a String is used for the selector then
     *  only simple CSS selectors are supported. If the String starts with a
     *  dot it is interpreted as a universal class selector, otherwise it must
     *  represent a simple type selector. If not null, this CSSStyleDeclaration
     *  will be registered with StyleManager. 
     *  
     *  @param styleManager - The style manager to set this declaration into. If the
     *  styleManager is null the top-level style manager will be used.
     * 
     *  @param autoRegisterWithStyleManager - If true set the selector in the styleManager. The selector
     *  will only be set if both <code>selector</code> and <code>styleManager</code> are
     *  both non-null.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function CSSStyleDeclaration(selector:Object=null, styleManager:IStyleManager2=null, autoRegisterWithStyleManager:Boolean = true)
    {
        super();

        /*
        // Do not reference StyleManager directly because this is a bootstrap class
        if (!styleManager)
            styleManager = Singleton.getInstance("mx.styles::IStyleManager2") as IStyleManager2;

        this.styleManager = styleManager;

        if (selector)
        {
            if (selector is CSSSelector)
            {
                this.selector = selector as CSSSelector;
            }
            else
            {
                // Otherwise, a legacy Flex 3 String selector was provided
                selectorString = selector.toString();
            }

            if (autoRegisterWithStyleManager)
                styleManager.setStyleDeclaration(selectorString, this, false);            
        }
        */

    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  defaultFactory
    //----------------------------------

    private var _defaultFactory:Function;
    
    [Inspectable(environment="none")]
    
    /**
     *  This function, if it isn't <code>null</code>,
     *  is usually autogenerated by the MXML compiler.
     *  It produce copies of a plain Object, such as
     *  <code>{ leftMargin: 10, rightMargin: 10 }</code>,
     *  containing name/value pairs for style properties; the object is used
     *  to build a node of the prototype chain for looking up style properties.
     *
     *  <p>If this CSSStyleDeclaration is owned by a UIComponent
     *  written in MXML, this function encodes the style attributes
     *  that were specified on the root tag of the component definition.</p>
     *
     *  <p>If the UIComponent was written in ActionScript,
     *  this property is <code>null</code>.</p>
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get defaultFactory():Function
    {
        return _defaultFactory;
    }
    
    /**
     *  @private
     */ 
    public function set defaultFactory(f:Function):void
    {
        _defaultFactory = f;
    }
 
    private var o:Object;
    
    /**
     *  Gets the value for a specified style property,
     *  as determined solely by this CSSStyleDeclaration.
     *
     *  <p>The returned value may be of any type.</p>
     *
     *  <p>The values <code>null</code>, <code>""</code>, <code>false</code>,
     *  <code>NaN</code>, and <code>0</code> are all valid style values,
     *  but the value <code>undefined</code> is not; it indicates that
     *  the specified style is not set on this CSSStyleDeclaration.
     *  You can use the method <code>StyleManager.isValidStyleValue()</code>
     *  to test the value that is returned.</p>
     *
     *  @param styleProp The name of the style property.
     *
     *  @return The value of the specified style property if set,
     *  or <code>undefined</code> if not.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getStyle(styleProp:String):*
    {
        var v:*;
        
        if (o == null)
        {
            if (defaultFactory != null)
            {
                defaultFactory.prototype = {};
                o = new defaultFactory();
            }
        }
        if (o != null)
        {
            v = o[styleProp];
            if (v !== undefined)
                return v;
        }
        var values:Object = ValuesManager.valuesImpl["values"]; // assume AllCSSValuesImpl
        
        return v;
    }
    
    /**
     *  Sets a style property on this CSSStyleDeclaration.
     *
     *  @param styleProp The name of the style property.
     *
     *  @param newValue The value of the style property.
     *  The value may be of any type.
     *  The values <code>null</code>, <code>""</code>, <code>false</code>,
     *  <code>NaN</code>, and <code>0</code> are all valid style values,
     *  but the value <code>undefined</code> is not.
     *  Setting a style property to the value <code>undefined</code>
     *  is the same as calling the <code>clearStyle()</code> method.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function setStyle(styleProp:String, newValue:*):void
    {
        if (o == null)
        {
            if (defaultFactory != null)
            {
                defaultFactory.prototype = {};
                o = new defaultFactory();
            }
            else
                o = {};            
        }
        o[styleProp] = newValue;
    }
    
    private var _name:String;
    
    public function set name(value:String):void
    {
        _name = value;
        o = ValuesManager.valuesImpl["values"][value]; // assume AllCSSValuesImpl
        if (o == null)
        {
            if (defaultFactory != null)
            {
                defaultFactory.prototype = {};
                o = new defaultFactory();
            }
            else
                o = {};            
            
            ValuesManager.valuesImpl["values"][value] = o;
        }
    }
    
}

}
