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

Copyright (c) 2010 Jason Graham

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" viewSourceURL="srcview/index.html"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="application1_creationCompleteHandler(event)">
  <fx:Declarations>
    <s:RadioButtonGroup id="radioGroup" itemClick="radioGroup_itemClickHandler(event)"/>
    <s:RadioButtonGroup id="radioGroupLayout"/>
    <s:Scale id="scaleOut" applyChangesPostLayout="true" autoCenterTransform="true" duration="500" startDelay="500" scaleXFrom=".3" scaleXTo="1" scaleYFrom=".3" scaleYTo="1"/>
    <s:Scale id="scaleIn" applyChangesPostLayout="true" autoCenterTransform="true" duration="500" scaleXFrom="1" scaleXTo=".3" scaleYFrom="1" scaleYTo=".3"/>
    <s:Rotate3D id="rotateIt" autoCenterTransform="false" duration="1000" angleXFrom="0" angleXTo="360" angleYFrom="0" angleYTo="360"/>
  </fx:Declarations>
  <fx:Script>
    <![CDATA[
      import mx.collections.ArrayCollection;
      import mx.effects.IEffectInstance;
      import mx.effects.Parallel;
      import mx.effects.Sequence;
      import mx.events.EffectEvent;
      import mx.events.FlexEvent;
      import mx.events.ItemClickEvent;
      
      import spark.components.supportClasses.ItemRenderer;
      import spark.effects.Animate;
      import spark.effects.Fade;
      import spark.effects.Move;
      import spark.effects.Rotate;
      import spark.effects.Scale;
      import spark.effects.Scale3D;
      import spark.effects.animation.MotionPath;
      import spark.effects.animation.RepeatBehavior;
      import spark.effects.animation.SimpleMotionPath;
      import spark.layouts.TileOrientation;
      [Bindable]private var dp:ArrayCollection;
      
      private var startValues:ArrayCollection=new ArrayCollection();

      protected function application1_creationCompleteHandler(event:FlexEvent):void
      {
        dp=new ArrayCollection();
        dp.addItem({label:"Item 1",value:1});
        dp.addItem({label:"Item 2",value:2});
        dp.addItem({label:"Item 3",value:3});
        dp.addItem({label:"Item 4",value:4});
        dp.addItem({label:"Item 5",value:5});
        dp.addItem({label:"Item 6",value:6});
        dp.addItem({label:"Item 7",value:7});
        dp.addItem({label:"Item 8",value:8});
        dp.addItem({label:"Item 9",value:9});
        dp.addItem({label:"Item 10",value:10});
        dp.addItem({label:"Item 11",value:11});
        dp.addItem({label:"Item 12",value:12});
      }
      
      private function filterEven( item : Object ) : Boolean
      {
        if (item.value%2 == 0)
        {
          return true;  
        }
        return false;
      }

      private function filterOdd( item : Object ) : Boolean
      {
        if (item.value%2 == 0)
        {
          return false;  
        }
        return true;
      }
      
      private function getStartValues():void
      {
        startValues.removeAll();
        for (var i:Number=0;i<lst.numElements;i++)
        {
          var element:ItemRenderer=lst.getElementAt(i) as ItemRenderer;
          var item:Object=new Object();
          if (element!=null)
          {
            item.point=new Point(element.x,element.y);
            item.elementData=element.data;
            item.elementRef=element;
          }
          else
          {
            item.point=new Point(0,0);
          }
          startValues.addItem(item);
        }
      }

      protected function radioGroup_itemClickHandler(event:ItemClickEvent):void
      {
        if (event.index == 2)
        {
          dp.filterFunction=filterEven;
        }
        else if (event.index==1)
        {
          dp.filterFunction=filterOdd;
        }
        else
        {
          dp.filterFunction=null;
        }
        filterCollection();
      }
      
      private function onEffectEnd(event:EffectEvent):void
      {
        lst.autoLayout=true;
      }

      public function filterCollection():void
      {
        //get the current values before anything changes
        getStartValues();

        //filter the items from the arraycollection
        dp.refresh();
        
        //cause the list to validate 
        lst.validateNow();
        //disable the automatic layout 
        lst.autoLayout=false;
        
        //set up the effects to go from new to old location and whatever else you want to do
        var p:Parallel=new Parallel();
        
        //after all the effects have played turn back on autoLayout 
        p.addEventListener(EffectEvent.EFFECT_END,onEffectEnd);
        
        for (var i:Number=0;i<lst.numElements;i++)
        {
          var element:ItemRenderer=lst.getElementAt(i) as ItemRenderer; 
          var move:Move=new Move();
          move.duration=1000;
          var start:Point=findStartValue(element.data);
          if (start != null)
          {
            move.xFrom=start.x;
            move.yFrom=start.y;
          }
          else
          {
            move.xFrom=0;
            move.yFrom=0;
          }
          move.xTo=element.x;
          move.yTo=element.y;
          
          var p1:Parallel=new Parallel(element);
          if (moveEffect.selected)
          {
            p1.addChild(move);
          }
          if (scaleEffect.selected)
          {
            p1.addChild(scaleIn);
            p1.addChild(scaleOut);
          }
          if (rotateEffect.selected)
          {
            p1.addChild(rotateIt);
          }
          p.addChild(p1);
        }
        //animate the changes
        p.play();
      }
      
      private function findStartValue(item:Object):Point
      {
        for each(var obj:Object in startValues)
        {
          if (obj.elementData == item)
          {
            startValues.removeItemAt(startValues.getItemIndex(obj));
            return obj.point;  
          }
        }
        return null;
      }

    ]]>
  </fx:Script>
  <s:states>
    <s:State name="tileState"/>
    <s:State name="verticalState"/>
    <s:State name="horizontalState"/>
  </s:states>
  <s:layout>
    <s:VerticalLayout/>
  </s:layout>
  <s:HGroup width="100%">
    <s:RadioButton label="Show All" group="{radioGroup}" selected="true"/>
    <s:RadioButton label="Show Odd" group="{radioGroup}"/>
    <s:RadioButton label="Show Even" group="{radioGroup}"/>
  </s:HGroup>
  <s:HGroup width="100%">
    <s:CheckBox id="moveEffect" label="Move Effect" selected="true"/>
    <s:CheckBox id="scaleEffect" label="Scale Effect"/>
    <s:CheckBox id="rotateEffect" label="Rotate Effect"/>
  </s:HGroup>
  <s:HGroup width="100%">
    <s:RadioButton label="Tile Layout" group="{radioGroupLayout}" click="currentState='tileState'" selected="true"/>
    <s:RadioButton label="Vertical Layout" group="{radioGroupLayout}" click="currentState='verticalState'"/>
    <s:RadioButton label="Horizontal Layout" group="{radioGroupLayout}" click="currentState='horizontalState'"/>
  </s:HGroup>
  <s:DataGroup id="lst" dataProvider="{dp}" width="100%" height="100%" itemRenderer="ListFilterEffectRenderer">
    <s:layout.tileState><s:TileLayout orientation="{TileOrientation.COLUMNS}" columnWidth="200" rowHeight="200"  horizontalAlign="center" verticalAlign="middle"/></s:layout.tileState>
    <s:layout.verticalState><s:VerticalLayout rowHeight="200"/></s:layout.verticalState>
    <s:layout.horizontalState><s:HorizontalLayout columnWidth="200"/></s:layout.horizontalState>
  </s:DataGroup>
</s:Application>