<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    initialize="init();" viewSourceURL="srcview/index.html" xmlns:local="*">
    
<mx:Style>
    
    Application
    {
        colorId: "color4";
        fontSize: 12;
        backgroundColorId: "color0";
    }
    
    Panel
    {
        borderColorId: "color3";
    }
    
    .header
    {
        colorId: "color1";
        fontSize: 14;
    }
    
    .warningContainer
    {
        backgroundImageId: "bitmap0";
        backgroundSize: "100%";
        
        borderColorId: "color4";
        borderThickness: 1px;
        borderStyle: "solid";
        cornerRadius: 4px;
    }
    
    .infoContainer
    {
        backgroundImageId: "bitmap1";
        backgroundSize: "100%";
        
        borderColorId: "color2";
        borderThickness: 1px;
        borderStyle: "solid";
        cornerRadius: 4px;
    }
    
</mx:Style>

<mx:Script>
<![CDATA[
    import flash.utils.getQualifiedClassName;
    import bitmaps.*;
    import mx.collections.ArrayCollection;
    
    private static const idAttributes:Array = 
    [
        "color",
        "backgroundColor",
        "backgroundImage",
        "borderColor"
    ];
    
    private var style1:Object = 
    {
        label: "Gray",
        color0: 0x222222,
        color1: 0x333333,
        color2: 0x666666,
        color3: 0xAAAAAA,
        color4: 0xDDDDDD,
        bitmap0: BitmapPicker.getRandomBitmapData(),
        bitmap1: BitmapPicker.getRandomBitmapData()
    };
    
    private var style2:Object = 
    {
        label: "Green",
        color0: 0x002200,
        color1: 0x004400,
        color2: 0x008800,
        color3: 0x00BB00,
        color4: 0x00FF00,
        bitmap0: BitmapPicker.getRandomBitmapData(),
        bitmap1: BitmapPicker.getRandomBitmapData()
    };
    
    [Bindable]
    private var styles:ArrayCollection;
    
    private var customStyleIndex:int = 0;
    
    private var bitmapClassCache:Array = [ B0, B1, B2 ];
    
    /**
     *  @param object Keys are Strings like "color1", values are real style 
     *  values ex. "0xFFCC00". 
     */
    private function applyStyle(object:Object):void
    {
        var selectors:Array = StyleManager.selectors;
        var bitmapClassCacheIndex:int = 0;
        var n:int = selectors.length;
        for (var i:int = 0; i < n; i++)
        {
            var selector:String = selectors[i];
            var declaration:CSSStyleDeclaration = StyleManager.getStyleDeclaration(selector);
            
            for each (name in idAttributes)
            {
                var idValue:String = declaration.getStyle(name + "Id") as String;
                if (!idValue)
                    continue;
                if (object[idValue] is BitmapData)
                {
                    var bitmapClass:Class = RuntimeBitmapAsset.bitmapDatas[idValue];
                    if (!bitmapClass)
                    {
                        bitmapClassCacheIndex = bitmapClassCacheIndex % bitmapClassCache.length;
                        bitmapClass = bitmapClassCache[bitmapClassCacheIndex++];
                        RuntimeBitmapAsset.bitmapDatas[
                            getQualifiedClassName(new bitmapClass())] = object[idValue];
                    }
                    declaration.setStyle(name, bitmapClass);
                }
                else if (object.hasOwnProperty(idValue))
                {
                    declaration.setStyle(name, object[idValue]);
                }
                else 
                {
                    declaration.clearStyle(name);
                }
            }
            StyleManager.setStyleDeclaration(selector, declaration, i == n - 1);
        }
    }
    
    private function init():void
    {
        styles = new ArrayCollection([ style1, style2 ]);
        
        applyStyle(style1);
    }
    
    private function createNewStyleEntering():void
    {
        var ffffff:int = Math.pow(2, 24);
        color0Picker.selectedColor = ffffff * Math.random() * 0.2;
        color1Picker.selectedColor = ffffff * Math.random() * 0.4;
        color2Picker.selectedColor = ffffff * Math.random() * 0.6;
        color3Picker.selectedColor = ffffff * Math.random() * 0.8;
        color4Picker.selectedColor = ffffff * Math.random();
    }
    
    private function saveAndApply():void
    {
        var newStyle:Object = 
        {
            label: "Custom style " + customStyleIndex++,
            color0: color0Picker.selectedColor,
            color1: color1Picker.selectedColor,
            color2: color2Picker.selectedColor,
            color3: color3Picker.selectedColor,
            color4: color4Picker.selectedColor,
            bitmap0: bitmap0Picker.selectedBitmapData,
            bitmap1: bitmap1Picker.selectedBitmapData
        };
        if (styles.length > 8)
            styles.removeItemAt(2);
        styles.addItem(newStyle);
        applyStyle(newStyle);
        
        currentState = null;
    }
    
    private function bar_itemClickHandler():void
    {
        applyStyle(styles[bar.selectedIndex]);
    }
    
]]>
</mx:Script>
    
    <mx:ApplicationControlBar top="10" horizontalCenter="0">
        
        <mx:Label text="Switch style or create new:"/>
        
        <mx:ButtonBar id="bar" dataProvider="{styles}" labelField="label" 
            itemClick="bar_itemClickHandler()"/>
        
        <mx:LinkButton label="Create new style" click="currentState = 'createNewStyle'"/> 
        
    </mx:ApplicationControlBar>
    
    <mx:Panel id="showPanel" layout="vertical" title="Custom runtime styles"
        verticalCenter="0" horizontalCenter="0" paddingBottom="10"
        paddingLeft="10" paddingRight="10" paddingTop="10">
        
        <mx:Label styleName="header" text="It's not necessary to create separate .swf for each Flex runtime style."/>
        
        <mx:Box styleName="warningContainer">
            
            <mx:Label text="You can just set some properties in one skin to different values."/>
            
        </mx:Box>
        
        <mx:Box styleName="infoContainer">
            
            <mx:Label text="This approach brings custom styling to the next level ;)"/>
            
        </mx:Box>
        
    </mx:Panel>
    
    <mx:states>
        
        <mx:State name="createNewStyle" enterState="createNewStyleEntering();">
            
            <mx:RemoveChild target="{showPanel}"/>
            
            <mx:AddChild>
                
                <mx:Panel layout="vertical" title="Create new style"
                    verticalCenter="0" horizontalCenter="0">
                    
                    <mx:Form>
                        
                        <mx:FormItem label="Color 0">
                            
                            <mx:ColorPicker id="color0Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem label="Color 1">
                            
                            <mx:ColorPicker id="color1Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem label="Color 2">
                            
                            <mx:ColorPicker id="color2Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem label="Color 3">
                            
                            <mx:ColorPicker id="color3Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem label="Color 4">
                            
                            <mx:ColorPicker id="color4Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem label="Bitmap 0">
                            
                            <local:BitmapPicker id="bitmap0Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem label="Bitmap 1">
                            
                            <local:BitmapPicker id="bitmap1Picker"/>
                            
                        </mx:FormItem>
                        
                        <mx:FormItem>
                            
                            <mx:Button label="Save and apply" click="saveAndApply();"/> 
                            
                        </mx:FormItem>
                        
                    </mx:Form>
                    
                </mx:Panel>
                
            </mx:AddChild>
            
        </mx:State>
        
    </mx:states>
    
</mx:Application>