<?xml version="1.0" encoding="utf-8"?>
<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/halo" width="410" height="316" xmlns:wizard="net.anirudh.wizard.*"
         title="{currentStepTitle}"            
         >
    <!--
    /*
    * The contents of this file are subject to the Mozilla Public License Version
    * 1.1 (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.mozilla.org/MPL/
    *
    * Software distributed under the License is distributed on an "AS IS" basis,
    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    * for the specific language governing rights and limitations under the
    * License.
    *
    * The Original Code is the Flex4Wizard component.
    *
    * The Initial Developer of the Original Code is
    * Anirudh Sasikumar (http://anirudhs.chaosnet.org/).
    * Portions created by the Initial Developer are Copyright (C) 2008
    * the Initial Developer. All Rights Reserved.
    *
    * Contributor(s):
    *
    */
    -->
    <fx:Metadata>
        [DefaultProperty("wizardChildren")]
        [Event("change", type="mx.events.ListEvent")]
    </fx:Metadata>
    <s:layout>
        <s:BasicLayout />
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.core.IVisualElement;
            import mx.events.ListEvent;
            
            import net.anirudh.wizard.vo.WizardStepVO;
            
            import spark.effects.Move;
            
            [Bindable]private var _wizardViews:ArrayCollection;
            
            [Bindable]public var steps:uint = 0;
            
            [Bindable]public var currentStepTitle:String = "";
            
            [Bindable]private var totSteps:uint = 0;
            
            private var _wizardChildren:Array;
            
            private var createChildrenCalled:Boolean = false;
            private var mxmlContentChanged:Boolean = false;
            
            /* We have a move effect per step. This is so that
               effect plays parallely even when prev/next is pressed
               multiple times */
            private var wizardEffects:Array = [];
            
            override protected function createChildren():void
            {
                super.createChildren();
                createChildrenCalled = true;
                
                if (mxmlContentChanged)
                {
                    mxmlContentChanged = false;
                    setMXMLContent(_wizardChildren);
                }
            }
            
            public function get wizardChildren():Array
            {
                return _wizardChildren;
            }

            public function set wizardChildren(value:Array):void
            {
                if ( createChildrenCalled )
                {
                    setMXMLContent(value);
                }
                else
                {
                    mxmlContentChanged = true;
                    _wizardChildren = value;
                }
            }
            
            private function setMXMLContent(value:Array):void
            {
                var i:int;
                
                // if there's old content and it's different than what 
                // we're trying to set it to, then let's remove all the old 
                // elements first.
                if (_wizardChildren != null && _wizardChildren != value)
                {
                    for (i = _wizardChildren.length - 1; i >= 0; i--)
                    {
                        wizardChildrenGroup.removeElementAt(i);
                    }
                }
                
                _wizardChildren = (value) ? value.concat() : null;  // defensive copy
                
                if (_wizardChildren != null)
                {
                    var n:int = _wizardChildren.length;
                    for (i = 0; i < n; i++)
                    {   
                        var elt:IVisualElement = _wizardChildren[i];
                        
                        // A common mistake is to bind the viewport property of an Scroller
                        // to a group that was defined in the MXML file with a different parent    
                        if (elt.parent && (elt.parent != this))
                            throw new Error(resourceManager.getString("components", "mxmlElementNoMultipleParents", [elt]));
                        
                        wizardChildrenGroup.addElementAt(elt, i);
                        
                        if ( i == 0 )
                        {
                            elt.visible = true;
                        }
                        else
                            elt.visible = false;
                    }
                }
            }

             public function checkTitle():void
            {
                if ( _wizardViews && _wizardViews.length > 0 && steps <= totSteps  )
                {
                    if ( steps < totSteps )
                    {
                         var wvo:WizardStepVO = _wizardViews.getItemAt(steps) as WizardStepVO;
                         if ( wvo )
                         {
                             currentStepTitle = wvo.name;
                         }
                    }
                    else
                    {
                        currentStepTitle = "FINISH";
                    }
                }                
                else
                {
                    currentStepTitle = "";
                }
            }
    
            [Bindable]public function get wizardViews():ArrayCollection
            {
                return _wizardViews;
            }
            
            public function set wizardViews(arr:ArrayCollection):void
            {
                _wizardViews = arr;
                if ( _wizardViews )
                    totSteps = _wizardViews.length; 
                checkTitle();
            }
            
            public function nextStep():void
            {
                if ( steps + 1 <= totSteps )
                {
                    steps++;                    
                    checkTitle();                    
                    changeView();
                    
                    var ti:Timer = new Timer(750, 1);
                    ti.addEventListener(TimerEvent.TIMER, timerHandler1);
                    ti.start();
                    dispatchEvent(new ListEvent(ListEvent.CHANGE, false, false, steps, steps));
                }                
            }
            
            private function playStepMoveEffect(next:Boolean, thestep:uint, target:Object, prevobj:Boolean):void
            {
                var moveeffect:Move;
                
                if ( !next )
                    prevobj = !prevobj;
                
                if ( !wizardEffects.hasOwnProperty(thestep ) )
                {
                    moveeffect = new Move();
                    moveeffect.duration = 800;                    
                    wizardEffects[thestep] = moveeffect;
                    
                    if ( !prevobj )
                    {
                        if ( next )
                        {
                            target.x = 0;
                        }
                        else
                        {
                            target.x = -1 * this.width;    
                        } 
                    }
                    else
                    {
                        if ( next )
                        {
                            target.x = this.width;
                        }
                        else
                        {
                            target.x = 0;
                        }
                    }
                }
                else
                {
                    moveeffect = wizardEffects[thestep ];
                    if ( moveeffect.isPlaying )
                    {
                        moveeffect.stop();                        
                    }
                }
                            
                moveeffect.xFrom = target.x;
                
                if ( prevobj )
                    moveeffect.xTo = 0;
                else
                {
                    if ( !next )
                        moveeffect.xTo = this.width;
                    else
                        moveeffect.xTo = -1 * this.width;
                }
                
                
                moveeffect.play([target]);
            }
                    
            private function changeView(next:Boolean=true):void
            {                
                var vstr:String = "view";
                var pstr:String = "view";
                
                var thestep:uint = 0;
                
                
                if ( next )
                {
                    thestep = steps;
                }
                else
                {
                    thestep = steps + 1 ;
                }

                if ( thestep >= wizardChildrenGroup.numElements )
                {
                    throw Error("Data in wizardViews does not match amount of children in WizardPanel (There is no child " + vstr + ")");
                    return;
                }
                if ( steps >= 0 )
                {
                    var prevobj:Object = wizardChildrenGroup.getElementAt(thestep - 1);
                    
                    playStepMoveEffect(next, thestep - 1, prevobj, false);
                    
                    prevobj.visible = true;
                }
                
                var nextobj:Object = wizardChildrenGroup.getElementAt(thestep );
                nextobj.visible = true;
                
                playStepMoveEffect(next, thestep, nextobj, true);
            }
            
            /* So that progress indicator animates after move is done */
            
            private function timerHandler1(event:TimerEvent):void
            {
                var tim1:Timer = (event.currentTarget as Timer);
                tim1.removeEventListener(TimerEvent.TIMER, timerHandler1);
                wizard.nextStep();
            }
            
            private function timerHandler2(event:TimerEvent):void
            {
                var tim1:Timer = (event.currentTarget as Timer);
                tim1.removeEventListener(TimerEvent.TIMER, timerHandler2);
                wizard.previousStep();    
            }
            
            public function previousStep():void
            {
                if ( steps - 1 >= 0 )
                {
                    steps--;
                    checkTitle();                    
                    changeView(false);
                    
                    var ti:Timer = new Timer(750, 1);
                    ti.addEventListener(TimerEvent.TIMER, timerHandler2);
                    ti.start();
                    dispatchEvent(new ListEvent(ListEvent.CHANGE, false, false, steps, steps));
                }                
            }
        ]]>
    </fx:Script>

    <s:Group clipAndEnableScrolling="true" left="0" right="0" top="0" bottom="0">
        
    
        <wizard:WizardProgress id="wizard" top="0" left="0" right="0"                          
                             views="{wizardViews}"
                             creationComplete="wizard.initStep()"
                             />
                
        <!-- views are added here -->
        <s:Group id="wizardChildrenGroup" left="0" right="0" top="0" bottom="66">
    
            
        </s:Group>
        
        <!-- for the bottom bar (31px high, full wide)-->
        
        <s:Line  
            bottom="31" left="0" right="0">
            <s:stroke>
                <s:Stroke color="0x404040" weight="1"/>
            </s:stroke>
        </s:Line>
        
        <!-- layer 3: title bar fill -->
        
        <s:Rect left="0" right="0" bottom="0" height="30">
            <s:fill>
                <s:LinearGradient rotation="90">
                    <s:GradientEntry color="0xE2E2E2" alpha="0.6"/>
                    <s:GradientEntry color="0xD9D9D9" alpha="0.6"/>
                </s:LinearGradient>
            </s:fill>
        </s:Rect>
        
        <!-- layer 4: title bar highlight -->
    
        <s:Rect left="0" right="0" bottom="0" height="30">
            <s:stroke>
                <s:LinearGradientStroke rotation="90" weight="1">
                    <s:GradientEntry color="0xEAEAEA" alpha="0.6"/>
                    <s:GradientEntry color="0xD9D9D9" alpha="0.6"/>
                </s:LinearGradientStroke>
            </s:stroke>
        </s:Rect>
        <s:Rect left="0" right="0" bottom="30" height="1">
            <s:fill>
                <s:SolidColor color="0xC0C0C0" alpha="0.6" />
            </s:fill>
        </s:Rect>
        
        
        <s:Button  bottom="6" label="PREVIOUS"  left="10" 
                   enabled="{steps > 0}"
                   click="previousStep()" />
        <s:Button  bottom="6" label="NEXT"   right="10" 
                   click="nextStep()"
                   enabled="{steps &lt; totSteps}"
                   />
    </s:Group>
</s:Panel>