<!--

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.

-->
<!--- A skin class for the Spark WindowedApplication and Window containers. 
      This class defines just a border and status bar, but no gripper button, 
      title bar, or title bar buttons.
      
      <p>You can either use  system chrome, the FlexChromSkin class, or 
      the WindowedApplicationSkin class to define the appearance of 
      the WindowedApplication and Window containers. 
      To use the WindowedApplicationSkin class with the WindowedApplication container, 
      set <code>systemChrome</code> to "none" 
      in the application's .xml file, and set the <code>skinClass</code> style to
      spark.skins.spark.WindowedApplicationSkin. 
      To use the WindowedApplicationSkin class with the Window container, 
      set the <code>Window.systemChrome</code> property to "none", 
      and set the <code>skinClass</code> style to
      spark.skins.spark.WindowedApplicationSkin.</p>

      @see spark.components.WindowedApplication
       
      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4 
      
-->
<s:SparkSkin 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.disabledGroup="0.5" >
	<fx:Metadata>[HostComponent("spark.components.WindowedApplication")]</fx:Metadata>

    <fx:Script fb:purpose="styling">
        /*  Define the skin elements that should not be colorized. 
         *  For WindowedApplication, border and status bar background are colorized,
         *  but the content area and status text are not. 
         *  Exclude the titleBar and scroller because they are SparkSkins and we 
         *  don't want to colorize them twice.
         * 
         * @langversion 3.0
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @productversion Flex 4 
         */
        static private const exclusions:Array = ["backgroundRect", "contentGroup", "statusText"];
        
        /**
         * @private
         */
        override public function get colorizeExclusions():Array {return exclusions;}
        
        /**
         * @private
         */
        override protected function initializationComplete():void
        {
            useChromeColor = true;
            super.initializationComplete();
        } 
        
    </fx:Script>
    
     <s:states>
        <s:State name="normal" />
        <s:State name="disabled" stateGroups="disabledGroup" />
        <s:State name="normalAndInactive" stateGroups="inactiveGroup" />
        <s:State name="disabledAndInactive" stateGroups="disabledGroup, inactiveGroup" />
    </s:states>

    <!-- layer 1: background fill -->
	<s:BitmapImage source="@Embed('/assets/icons/bg_logo.png')" top="0" left="0"  scaleMode="letterbox" />
	<s:BitmapImage source="@Embed('/assets/icons/bg_logo.png')" top="25" left="0"  scaleMode="letterbox" />
	<s:BitmapImage id="textIcon" source="@Embed('/assets/icons/apache_flex_logo_text.png')" scaleX=".3" scaleY=".3" smooth="true" horizontalCenter="0" top="5" />

    <!-- layer 2: content + status bar -->
    <s:Group left="0" right="0" top="0" bottom="0" minHeight="24" minWidth="0" >
        <s:layout>
            <s:VerticalLayout gap="0"/>
        </s:layout>
    
        <!-- content -->
        <!--- @copy spark.components.SkinnableContainer#contentGroup -->
        <s:Group id="contentGroup" width="100%" height="100%" minHeight="0" minWidth="0"/>
        
        <!-- status bar -->
        <!--- @copy spark.components.WindowedApplication#statusBar -->
        <s:Group id="statusBar" width="100%" minHeight="24" >
        
            <!-- status bar fill -->
            <s:Rect left="0" right="0" top="0" bottom="0">
               <s:fill>
                    <s:LinearGradient rotation="90">
                        <s:GradientEntry color="0xE2E2E2" />
                        <s:GradientEntry color="0xD9D9D9" />
                    </s:LinearGradient>
               </s:fill>
            </s:Rect>
            
            <!-- status bar highlight -->
            <s:Rect left="1" right="1" top="1" bottom="0" >
               <s:stroke>
                    <s:LinearGradientStroke rotation="90" weight="1">
                        <s:GradientEntry color="0xEAEAEA" />
                        <s:GradientEntry color="0xBEBEBE" />
                    </s:LinearGradientStroke>
               </s:stroke>
            </s:Rect>
        
            <!-- status text -->
            <!--- @copy spark.components.WindowedApplication#statusText -->
            <s:Label id="statusText" top="2" bottom="2" left="10" right="10" verticalAlign="middle" 
                fontSize="10" color="0x585858" width="100%" maxDisplayedLines="1" />

        </s:Group> 
    </s:Group>

</s:SparkSkin>
