<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%"
         xmlns:flxs="com.flexicious.nestedtreedatagrid.*" creationComplete="initializeDataGrid()" xmlns:grids="com.flexicious.grids.*" xmlns:columns="com.flexicious.grids.columns.*" >
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <mx:HBox width="100%">
        <mx:CheckBox label="Start" change="startTimer(event)"/>
        <mx:HSlider id="hSlider" minimum="1" maximum="50" 
               value="@{repeatRate}" snapInterval="1" 
               change="timer.delay = 1000.0 / repeatRate"/>
        <mx:Label text="{hSlider.value} updates/second" />
    </mx:HBox >

    <fx:Script>
        <![CDATA[
            import com.flexicious.nestedtreedatagrid.interfaces.IFlexDataGridCell;
            import com.flexicious.nestedtreedatagrid.valueobjects.RowInfo;
            import com.flexicious.utils.UIUtils;
            
            import mock.FlexiciousMockGenerator;
            
            import mx.collections.ArrayCollection;
            import mx.collections.ArrayList;
            import mx.collections.Sort;
            import mx.collections.SortField;
            import mx.events.PropertyChangeEvent;
            
            [Bindable]private var repeatRate:Number = 12;    
            private var timer:Timer = null;
            private var stocks:ArrayCollection=new ArrayCollection; 
            
            private function initializeDataGrid():void
            {
                for (var i:int=0;i<10000;i++){
                    var chg:Number=FlexiciousMockGenerator.getRandom(-10,10);
                    stocks.addItem({"id":i,"symbol":"TICK" + i, "name":"Ticker with symbol"+i
                        ,"last":FlexiciousMockGenerator.getRandom(20,30),"change":chg+"%","tickUp":(chg>0)});
                }
                stocks.sort=new Sort();
                stocks.sort.fields=[new SortField("id")];
                stocks.refresh();
                fdg.dataProvider=stocks;
            }
            
            private function startTimer(evt:Event):void
            {
                if (!timer)
                {
                    timer = new Timer(1000.0 / repeatRate);
                    timer.addEventListener(TimerEvent.TIMER, updateTimerHandler);
                }
                
                if (evt.currentTarget.selected)
                {
                    timer.start();
                }
                else
                {
                    timer.stop();
                }
            }
            
            private function updateTimerHandler(event:TimerEvent):void
            {
            
                //when this happens, we get a batch from the server that says tickers with XX ids have
                //new values...
                var affectedItems:Array=[]
                //we just randomly update some 25 items out of the 100.
                for(var i:int=0;i<250;i++){
                    var random:Number=FlexiciousMockGenerator.getRandom(0,fdg.dataProvider.length-1);
                    
                    var chg:Number=FlexiciousMockGenerator.getRandom(-10,10);
                    fdg.dataProvider[random].last=FlexiciousMockGenerator.getRandom(20,30)
                    fdg.dataProvider[random].change=chg
                    fdg.dataProvider[random].tickUp=chg>0;
                    affectedItems.push(fdg.dataProvider[random]);
                }
                
                //now the key here is to only update the cells that are affected.
                //this means we navigate to the row, get the affected cell, and invalidate it...
                //we go through the affectedItems, but keep in mind not all of the 
                //affectedItems could be in view. So we check to see if anything is 
                //drawn and if something is drawn, only then refresh it...
                
                for each(var item:Object in affectedItems){
                    //now there is a function call - getCellByRowColumn on the grid.
                    //that will quickly get you the cell to update. but in this case
                    //since we are updating multiple cells in each row, we will just
                    //get the row to update and use its cells collection to quickly
                    //update them
                    
                    for each(var row:RowInfo in fdg.bodyContainer.rows){
                        if(row.data==item){
                            //this means we need to update his cells
                            row.cells[2].component.refreshCell();
                            row.cells[3].component.refreshCell();
                        }
                    }
                }
            }
            
             
            
            private function getCellTextColor(cell:IFlexDataGridCell):uint{
                if(cell.rowInfo.data.tickUp)
                    return 0x000000;
                else
                    return 0xFFFFFF;
            }
            private function getCellBackgroundColor(cell:IFlexDataGridCell):uint{
                if(cell.rowInfo.data.tickUp)
                    return 0x00FF00;
                else
                    return 0xFF0000;
            }
        ]]>
    </fx:Script>
    <flxs:FlexDataGrid id="fdg" width="100%" height="100%">
        <flxs:columns>
            <flxs:FlexDataGridColumn headerText="Symbol" dataField="symbol"/>
            <flxs:FlexDataGridColumn headerText="Name" dataField="name"/>
            <flxs:FlexDataGridColumn headerText="Last" dataField="last" cellTextColorFunction="getCellTextColor" cellBackgroundColorFunction="getCellBackgroundColor"/>
            <flxs:FlexDataGridColumn headerText="Change" dataField="change" cellTextColorFunction="getCellTextColor" cellBackgroundColorFunction="getCellBackgroundColor"/>
        </flxs:columns>
    </flxs:FlexDataGrid>
    
    
</mx:VBox>