<?xml version="1.0" encoding="utf-8"?>
<!--

  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.

-->
<!--- The default skin class for the textInput of a Spark ComboBox component.  
        
      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabledStates="0.5" blendMode="normal">

    <fx:Metadata>
    <![CDATA[ 
    /** 
     * @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
        [HostComponent("spark.components.TextInput")]
    ]]>
    </fx:Metadata> 
    
    <fx:Script fb:purpose="styling">
        private var paddingChanged:Boolean;
        private var cornerRadius:Number = 0;
        
        
        /**
         *  @private
         */
        override protected function commitProperties():void
        {
            super.commitProperties();
            
            if (paddingChanged)
            {
                updatePadding();
                paddingChanged = false;
            }
        }
        
        
        /**
         *  @private
         */
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            if (getStyle("borderVisible") == true)
            {
                border.visible = true;
                shadow.visible = true;
                background.left = background.top = background.right = background.bottom = 1;
                textDisplay.left = textDisplay.top = textDisplay.right = textDisplay.bottom = 1;
            }
            else
            {
                border.visible = false;
                shadow.visible = false;
                background.left = background.top = background.right = background.bottom = 0;
                textDisplay.left = textDisplay.top = textDisplay.right = textDisplay.bottom = 0;
            }
            
            borderStroke.color = getStyle("borderColor");
            borderStroke.alpha = getStyle("borderAlpha");
            
            /* var cr:Number = getStyle("cornerRadius");
            
            if (cornerRadius != cr)
            {
                cornerRadius = cr;
                shadow.bottomLeftRadiusX = shadow.topLeftRadiusX = cornerRadius;
                border.bottomLeftRadiusX = border.topLeftRadiusX = cornerRadius;
                background.bottomLeftRadiusX = background.topLeftRadiusX = cornerRadius;
            } */
            
            super.updateDisplayList(unscaledWidth, unscaledHeight);
        }

        /**
         *  @private
         */
        private function updatePadding():void
        {
            if (!textDisplay)
                return;
            
            // Push padding styles into the textDisplay
            var padding:Number;
            
            padding = getStyle("paddingLeft");
            if (textDisplay.getStyle("paddingLeft") != padding)
                textDisplay.setStyle("paddingLeft", padding);
            
            padding = getStyle("paddingTop");
            if (textDisplay.getStyle("paddingTop") != padding)
                textDisplay.setStyle("paddingTop", padding);
            
            padding = getStyle("paddingRight");
            if (textDisplay.getStyle("paddingRight") != padding)
                textDisplay.setStyle("paddingRight", padding);
            
            padding = getStyle("paddingBottom");
            if (textDisplay.getStyle("paddingBottom") != padding)
                textDisplay.setStyle("paddingBottom", padding);
        }
        
        /**
         *  @private
         */
        override public function styleChanged(styleProp:String):void
        {
            super.styleChanged(styleProp);
            
            if (!styleProp || styleProp.indexOf("padding") == 0)
            {
                paddingChanged = true;
                invalidateProperties();
            }
        }
    </fx:Script>
    
    <fx:Script>
        <![CDATA[
        /**
         * @inheritDoc
         */
        override public function get focusSkinExclusions():Array { return [ textDisplay ] };            
        ]]>
    </fx:Script>
    
    <s:states>
        <s:State name="normal"/>
        <s:State name="disabled" stateGroups="disabledStates"/>
        <s:State name="normalWithPrompt"/>
        <s:State name="disabledWithPrompt" stateGroups="disabledStates"/>
    </s:states>
    
    <!-- border --> 
    <s:Rect left="0" right="0" top="0" bottom="0" id="border">
        <s:stroke>     
            <s:SolidColorStroke id="borderStroke" weight="1" color="0x82826b" />
        </s:stroke>
    </s:Rect>

    <!-- fill -->
    <!--- Defines the appearance of the TextInput component's background. -->
    <s:Rect id="background" left="1" right="1" top="1" bottom="1">
        <s:fill>
        <!--- Defines the background fill color. -->
            <s:SolidColor id="bgFill" color="0xf3f4de" />
        </s:fill>
    </s:Rect>
    
    <!-- shadow -->
    <s:Rect left="1" top="1" right="1" height="1" id="shadow">
        <s:fill>
            <s:SolidColor color="0x000000" alpha="0.12" />
        </s:fill>
    </s:Rect>
    
    <!-- text -->
    <s:RichEditableText id="textDisplay"
              lineBreak="explicit"
              verticalAlign="middle"
              widthInChars="10"
              left="1" right="1" top="1" bottom="1" />

</s:Skin>
