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

////////////////////////////////////////////////////////////////////////////////
//
//    Copyright 2014 Ardisia Labs LLC. All Rights Reserved.
//
//    This file is licensed 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.
//
////////////////////////////////////////////////////////////////////////////////

-->
<s:Module xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" 
          xmlns:colorizer="ardisia.components.colorizer.*" 
          xmlns:colorPicker="ardisia.components.colorPicker.*" 
          xmlns:containers="containers.*"
          xmlns:separators="ardisia.components.separators.*"
          xmlns:heatmap="ardisia.charts.heatmap.*" 
          xmlns:gauges="ardisia.components.gauges.*" 
          xmlns:data1="ardisia.components.colorizer.data.*"
          xmlns:data="containers.data.*"
          frameRate="60"
          width="100%" height="100%"
          removedFromStage="removedFromStageHandler(event)">
    
    <!-- scripts -->
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            
            //--------------------------------------
            //  variables
            //--------------------------------------
            
            [Bindable]protected var dp:ArrayCollection;
            
            protected var minMax:Array;
            
            protected var galaxyData:Array;
            
            protected var minX:Number = Number.POSITIVE_INFINITY;
            protected var maxX:Number = Number.NEGATIVE_INFINITY;
            protected var minY:Number = Number.POSITIVE_INFINITY;
            protected var maxY:Number = Number.NEGATIVE_INFINITY;
            protected var minL:Number = Number.POSITIVE_INFINITY;
            protected var maxL:Number = Number.NEGATIVE_INFINITY;
            
            //--------------------------------------
            //  methods
            //--------------------------------------
            
            public function creationComplete():void
            {
                // setup the data for the galaxy 
                var myTextLoader:URLLoader = new URLLoader();
                
                myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
                
                function onLoaded(e:Event):void 
                {
                    galaxyData = [];
                    var rawData:Array = e.target.data.split(/\n/);
                    
                    var rex:RegExp = /\s+/g;
                    
                    for each (var line:String in rawData)
                    {
                        line = line.replace(rex,' ');
                        var lineParts:Array = line.split(' ');
                        if (lineParts[0] && !isNaN(lineParts[0]) && lineParts[1] && !isNaN(lineParts[1]) && lineParts[2] && !isNaN(lineParts[2]))
                        {
                            minX = Math.min(minX, lineParts[0]);
                            maxX = Math.max(maxX, lineParts[0]);
                            minY = Math.min(minY, lineParts[1]);
                            maxY = Math.max(maxY, lineParts[1]);
                            minL = Math.min(minL, lineParts[2]);
                            maxL = Math.max(maxL, lineParts[2]);
                            
                            galaxyData.push([lineParts[0], lineParts[1], lineParts[2]]);
                        }
                    }
                    
                    drawGalaxy();
                }
                
                myTextLoader.load(new URLRequest("data/galaxy.txt"));
                
                // setup the data for the heatmap
                dp = new ArrayCollection();
                
                for each (var item:XML in xml.Nation) 
                {
                    var name:String = item["@name"];
                    var population:Number = parseFloat(item["@population"]);
                    dp.addItem({
                        name:name, 
                        population: population});
                }
                
                // calcualte global min/max
                minMax = [
                    [Number.MAX_VALUE, Number.MIN_VALUE], [Number.MAX_VALUE, Number.MIN_VALUE]                    
                ];
                for (var i:int = 0; i < dp.length; i++)
                {
                    var data:Object = dp[i]; 
                    var pop:Number = Object(data).population; if (!isNaN(pop)){minMax[0][0] = 0; minMax[0][1] = Math.max(pop, minMax[0][1]);}
                }
                
                for (i = 0; i < dp.length; i++)
                {
                    data = dp[i]; 
                    Object(data).populationPercent = (Object(data).population - minMax[0][0]) / (minMax[0][1] - minMax[0][0]);
                }
                
                dp.refresh();
                
                // sort
                var sortedColumns:Vector.<int> = new Vector.<int>();
                sortedColumns.push(1);
                heatmap.sortByColumns(sortedColumns, false);
            }
            
            protected function drawGalaxy():void
            {
                var g:Graphics = galaxyCanvas.graphics;
                galaxyColorizer.rangeMinimum = minL;
                galaxyColorizer.rangeMaximum = maxL;
                
                g.clear();
                
                g.lineStyle(1, 0, 1, true);
                g.drawRect(0, 0, maxX * 3 + 3, maxY * 3 + 3);
                g.endFill();
                g.lineStyle();
                
                for each (var data:Array in galaxyData)
                {
                    var color:uint = galaxyColorizer.getColor(data[2]);
                    g.beginFill(color, 100 * Math.abs(data[2] / (maxL - minL)) );
                    g.drawRect(3 * data[0], 3 * data[1], 3, 3);
                    g.endFill();
                }
                
                // draw legend
                var gGradient:Graphics = legendCanvas.graphics;
                
                for (var i:int = 0; i < 292; i++)
                {
                    color = galaxyColorizer.getColor(minL + i / 292 * (maxL - minL));
                    
                    gGradient.beginFill(color, 1);
                    gGradient.drawRect(i, 0, 1, 16);
                    gGradient.endFill();
                }
            }
            
            //--------------------------------------
            //  event handlers
            //--------------------------------------
            
            protected function hlinearguage1_changeHandler(event:Event):void
            {
                var color:uint = discreteColorizer.getColor(discreteGuage.value);
                gradeCt.setStyle("backgroundColor", color);
                // gradeLabel
                var value:Number = discreteGuage.value;
                var mod:Number = value % 10;
                var plusMinus:String = "";
                if (value == 100)
                {
                    gradeLabel.text = "A+";
                    return;
                }
                if (mod < 3)
                    plusMinus = "-";
                else if (mod >= 7)
                    plusMinus = "+";
                if (value >= 90)
                    var grade:String = "A";
                else if (value >= 80)
                    grade = "B";
                else if (value >= 70)
                    grade = "C";
                else if (value >= 60)
                    grade = "D";
                else
                {    
                    gradeLabel.text = "F";
                    return;
                }
                
                gradeLabel.text = grade + plusMinus;
            }
            
            protected function removedFromStageHandler(event:Event):void
            {
                
            }
            
        ]]>
    </fx:Script>
    
    <!-- declarations -->
    <fx:Declarations>
        
        <fx:XML id="xml" 
                source="data/EUdata.xml"/>    
        
        <!--- heatmap colorizer -->
        <colorizer:GradientColorizer id="heatmapColorizer" 
                                     rangeMinimum="0" rangeMaximum="1">
            <data1:GradientColorizerData ratio="0" color="{colorizerColorMin.selectedColor}" />
            <data1:GradientColorizerData ratio="1" color="{colorizerColorMax.selectedColor}" />
        </colorizer:GradientColorizer>
        
        <!--- discrete colorizer -->
        <colorizer:DiscreteColorizer id="discreteColorizer">
            <data1:DiscreteColorizerData minValue="97" maxValue="100" color="#7A003D"/>
            <data1:DiscreteColorizerData minValue="93" maxValue="97" color="#A30052"/>
            <data1:DiscreteColorizerData minValue="90" maxValue="93" color="#CC0066"/>
            <data1:DiscreteColorizerData minValue="87" maxValue="90" color="#004D99"/>
            <data1:DiscreteColorizerData minValue="83" maxValue="87" color="#0066CC"/>
            <data1:DiscreteColorizerData minValue="80" maxValue="83" color="#0080FF"/>
            <data1:DiscreteColorizerData minValue="77" maxValue="80" color="#004D4D"/>
            <data1:DiscreteColorizerData minValue="73" maxValue="77" color="#006666"/>
            <data1:DiscreteColorizerData minValue="70" maxValue="73" color="#008080"/>
            <data1:DiscreteColorizerData minValue="67" maxValue="70" color="#994D00"/>
            <data1:DiscreteColorizerData minValue="60" maxValue="63" color="#FF8000"/>
            <data1:DiscreteColorizerData minValue="63" maxValue="67" color="#CC6600"/>
            <data1:DiscreteColorizerData minValue="0" maxValue="60" color="#9A9A00"/>
        </colorizer:DiscreteColorizer>
        
        <!--- galaxy colorizer --> 
        <colorizer:GradientColorizer id="galaxyColorizer">
            <data1:GradientColorizerData ratio="{ratioB0Ratio.value}" color="{ratioB0Color.selectedColor}" />
            <data1:GradientColorizerData ratio="{ratioB1Ratio.value}" color="{ratioB1Color.selectedColor}" />
            <data1:GradientColorizerData ratio="{ratioB2Ratio.value}" color="{ratioB2Color.selectedColor}" />
            <data1:GradientColorizerData ratio="{ratioB3Ratio.value}" color="{ratioB3Color.selectedColor}" />
            <data1:GradientColorizerData ratio="{ratioB4Ratio.value}" color="{ratioB4Color.selectedColor}" />
            <data1:GradientColorizerData ratio="{ratioB5Ratio.value}" color="{ratioB5Color.selectedColor}" />
        </colorizer:GradientColorizer>
        
    </fx:Declarations>
    
    <!-- states -->
    <s:states>
        <s:State name="stockholm" />
        <s:State name="london" />
        <s:State name="spark" />
    </s:states>
    
    <!-- application -->
    <containers:DemoApplicationWrapper id="demoAppWrapper" 
                                       width="100%" height="100%"
                                       westRegionTitle="Colorizers Description"
                                       description="Ardisia Colorizers return colors based on passed values, which makes them very useful for data visualization and charting.&#13;&#13;The Ardisia colorizers package includes two types of colorizers: (A) the GradientColorizer which returns a color along a gradient, and (B) the DiscreteColorizer that returns a single color for set value ranges.&#13;&#13;The GradientColorizer component is defined by the 'rangeMinimum'/'rangeMaximum' properties and GradientColorizerData objects which define a ratio and a color. The ratio defines the ratio of the range's value at which the given color will be returned.  For passed values that are in-between defined ratios/colors, this class will automatically calculate the color allowing for a gradient pattern.&#13;&#13;The DiscreteColorizer component returns a color value based on a vector of DiscreteColorizerData objects that define discrete, distinct, and individual colors for each range. Any value passed that is within a range will return the defined color. All values within the range return the same color so there is no gradient and the colors are discrete."
                                       currentState.stockholm="stockholm" currentState.london="london" currentState.spark="spark">
        
        <containers:centerContent>
            
            <!--- example #1 -->
            <data:PrimaryContentData>
                <data:tabLabel>Simple Gradient Colorizer Example</data:tabLabel>
                <data:exampleDescription>This example recycles the Heatmap chart component to illustrate a GradientColorizer with only 2 ratios defined: ratio 0 and ratio 1.  Ratio 0 being the minimum value and ratio 1 is the maximum value.  Values that fall between the min/max will be represented by a color that is calculated along the gradient between the two colors.</data:exampleDescription>
                <data:toolbarContent>
                    <s:Form>
                        <s:FormItem label="Maximum Value (Ratio 1) Color:">
                            <colorPicker:ColorPicker id="colorizerColorMax" 
                                                     selectedColor="#99CC00"
                                                     change="dp.refresh()"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="The color returned for the maximum value by the colorizer."/>
                            </s:helpContent>
                        </s:FormItem>
                        <s:FormItem label="Minimum Value (Ratio 0) Color:">
                            <colorPicker:ColorPicker id="colorizerColorMin" 
                                                     selectedColor="#CC9900"
                                                     change="dp.refresh()"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="The color returned for the minimum value by the colorizer."/>
                            </s:helpContent>
                        </s:FormItem>
                    </s:Form>
                </data:toolbarContent>
                <data:primaryContent>
                    <s:VGroup top="20" bottom="20" 
                              horizontalCenter="0" 
                              horizontalAlign="justify">
                        <heatmap:Heatmap id="heatmap" 
                                         width="350" height="100%"
                                         showDataTips="true"
                                         selectionMode="singleCell"
                                         dataProvider="{dp}">
                            <heatmap:seriesColumn>
                                <s:GridColumn dataField="name"
                                              width="125"
                                              headerText="EU Nation" 
                                              showDataTips="false"/>
                            </heatmap:seriesColumn>
                            <heatmap:dataColumns>
                                <heatmap:HeatmapDataColumn dataField="populationPercent" dataTipField="population" headerText="Population" colorizer="{heatmapColorizer}" sortDescending="true"/>
                            </heatmap:dataColumns>
                        </heatmap:Heatmap>
                        <s:HGroup verticalAlign="middle" 
                                  right="0">
                            <s:Label text="Less" 
                                     fontWeight="bold"/>
                            <s:Rect width="100%" height="10"
                                    right="0">
                                <s:fill>
                                    <s:LinearGradient>
                                        <s:GradientEntry color="{colorizerColorMin.selectedColor}" />
                                        <s:GradientEntry color="{colorizerColorMax.selectedColor}" />
                                    </s:LinearGradient>
                                </s:fill>
                            </s:Rect>
                            <s:Label fontWeight="bold" 
                                     text="More"/>
                        </s:HGroup>
                    </s:VGroup>
                </data:primaryContent>
            </data:PrimaryContentData>
            
            <!--- example #2 -->
            <data:PrimaryContentData>
                <data:tabLabel>Multiple Gradient Colorizer Example</data:tabLabel>
                <data:exampleDescription>GradientColorizers can define an unlimited number of ratios and colors to use to calculate the color to return.&#13;&#13;The example below uses a colorizer with 6 colors and ratios defined to colorize luminosity data returned by the Hubble Space Telescope for a galaxy.</data:exampleDescription>
                <data:toolbarContent>
                    <s:Form>
                        <s:FormItem label="Ratio 0:">
                            <s:layout>
                                <s:HorizontalLayout verticalAlign="middle"
                                                    gap="15"/>
                            </s:layout>
                            <colorPicker:ColorPicker id="ratioB0Color" 
                                                     selectedColor="#FF0000"
                                                     change="drawGalaxy();"/>
                            <s:HSlider id="ratioB0Ratio"
                                       minimum="0" maximum="{ratioB1Ratio.value}" value="0.0" snapInterval="0"
                                       change="drawGalaxy();"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="Ratio 0&#13;&#13;Values at this percentage of the maximum luminosity will be filled with this color."/>
                            </s:helpContent>
                        </s:FormItem>
                        <s:FormItem label="Ratio 1:">
                            <s:layout>
                                <s:HorizontalLayout verticalAlign="middle"
                                                    gap="15"/>
                            </s:layout>
                            <colorPicker:ColorPicker id="ratioB1Color" 
                                                     selectedColor="#00FF00"
                                                     change="drawGalaxy();"/>
                            <s:HSlider id="ratioB1Ratio"
                                       minimum="0" maximum="{ratioB2Ratio.value}" value="0.05" snapInterval="0"
                                       change="drawGalaxy();"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="Ratio 1&#13;&#13;Values at this percentage of the maximum luminosity will be filled with this color."/>
                            </s:helpContent>
                        </s:FormItem>
                        <s:FormItem label="Ratio 2:">
                            <s:layout>
                                <s:HorizontalLayout verticalAlign="middle"
                                                    gap="15"/>
                            </s:layout>
                            <colorPicker:ColorPicker id="ratioB2Color" 
                                                     selectedColor="#0000FF"
                                                     change="drawGalaxy();"/>
                            <s:HSlider id="ratioB2Ratio"
                                       minimum="0" maximum="{ratioB3Ratio.value}" value="0.1" snapInterval="0"
                                       change="drawGalaxy();"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="Ratio 2&#13;&#13;Values at this percentage of the maximum luminosity will be filled with this color."/>
                            </s:helpContent>
                        </s:FormItem>
                        <s:FormItem label="Ratio 3:">
                            <s:layout>
                                <s:HorizontalLayout verticalAlign="middle"
                                                    gap="15"/>
                            </s:layout>
                            <colorPicker:ColorPicker id="ratioB3Color" 
                                                     selectedColor="#FFFF00"
                                                     change="drawGalaxy();"/>
                            <s:HSlider id="ratioB3Ratio"
                                       minimum="0" maximum="{ratioB4Ratio.value}" value="0.15" snapInterval="0"
                                       change="drawGalaxy();"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="Ratio 3&#13;&#13;Values at this percentage of the maximum luminosity will be filled with this color."/>
                            </s:helpContent>
                        </s:FormItem>
                        <s:FormItem label="Ratio 4:">
                            <s:layout>
                                <s:HorizontalLayout verticalAlign="middle"
                                                    gap="15"/>
                            </s:layout>
                            <colorPicker:ColorPicker id="ratioB4Color" 
                                                     selectedColor="#FF00FF"
                                                     change="drawGalaxy();"/>
                            <s:HSlider id="ratioB4Ratio"
                                       minimum="0" maximum="{ratioB5Ratio.value}" value="0.2" snapInterval="0"
                                       change="drawGalaxy();"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="Ratio 4&#13;&#13;Values at this percentage of the maximum luminosity will be filled with this color."/>
                            </s:helpContent>
                        </s:FormItem>
                        <s:FormItem label="Ratio 5:">
                            <s:layout>
                                <s:HorizontalLayout verticalAlign="middle"
                                                    gap="15"/>
                            </s:layout>
                            <colorPicker:ColorPicker id="ratioB5Color" 
                                                     selectedColor="#00FFFF"
                                                     change="drawGalaxy();"/>
                            <s:HSlider id="ratioB5Ratio"
                                       minimum="0" maximum="1" value="1" snapInterval="0"
                                       change="drawGalaxy();"/>
                            <s:helpContent>
                                <s:Image source="@Embed(source='icons/question.png')"
                                         toolTip="Ratio 5&#13;&#13;Values at this percentage of the maximum luminosity will be filled with this color."/>
                            </s:helpContent>
                        </s:FormItem>
                    </s:Form>
                </data:toolbarContent>
                <data:primaryContent>
                    <s:VGroup horizontalCenter="0" verticalCenter="0"
                              gap="20">
                        <s:Group id="galaxyCanvas"
                                 width="360" height="360"/>
                        <s:HGroup verticalAlign="middle">
                            <s:Label text="Luminosity"
                                     fontWeight="bold"/>
                            <s:Group id="legendCanvas" 
                                     height="16" width="200"/>
                        </s:HGroup>
                    </s:VGroup>
                </data:primaryContent>
            </data:PrimaryContentData>
            
            <!--- example #3 -->
            <data:PrimaryContentData>
                <data:tabLabel>Discrete Colorizer Example</data:tabLabel>
                <data:exampleDescription>Discrete colorizers return a single color for a given range. The example below illustrates this by using a horizontal gauge to set a student's test score, and the colorizer will return the color that corresponds to the provided grade.  The same color is returned by all values within a grade range.  In other words, grades of 93 to 96 are all 'A' and will return a dark red.</data:exampleDescription>
                <data:primaryContent>
                    <s:VGroup horizontalCenter="0" verticalCenter="0"
                              gap="20">
                        <s:HGroup verticalAlign="middle">
                            <s:Label text="Student Grade:"
                                     fontSize="18"
                                     fontWeight="bold"/>
                            <s:BorderContainer id="gradeCt"
                                               width="100" height="100"
                                               borderColor="#000000"
                                               backgroundColor="#006666">
                                <s:Label id="gradeLabel"
                                         width="100%" height="100%"
                                         textAlign="center" verticalAlign="middle"
                                         text="C"
                                         color="#FFFFFF"
                                         fontSize="48" paddingLeft="-3" paddingTop="5"/>
                            </s:BorderContainer>
                        </s:HGroup>
                        <gauges:HLinearGauge id="discreteGuage" 
                                             width="500" height="50"
                                             useMultiThumbs="false"
                                             showDataTip="false"
                                             minimum="50" maximum="100" value="75"
                                             minorTickCount="2"
                                             change="hlinearguage1_changeHandler(event)"/>
                        <s:Image source="@Embed(source='images/gradeSpectrum.png')"/>
                    </s:VGroup>
                </data:primaryContent>
            </data:PrimaryContentData>
            
        </containers:centerContent>
        
    </containers:DemoApplicationWrapper>
    
</s:Module>