<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:openflux="http://www.openflux.org/2008"
    xmlns:layouts="com.randomFractals.openflux.layouts.*"     
    xmlns:cameras="com.randomFractals.openflux.cameras.*"
    xmlns:data="com.randomFractals.openflux.model.*"     
    layout="horizontal" 
    viewSourceURL="srcview/index.html" 
    creationComplete="onAppInit();">
    
    <mx:Style source="assets/skins/defaultStyles.css" />
    
    <mx:ArrayCollection id="data">
    <data:Tag label="OpenFlux" frequency="12"/>
    <data:Tag label="Plexiglass"  frequency="14"/>
    <data:Tag label="3D" frequency="11"/>
    <data:Tag label="Tag" frequency="4" />
    <data:Tag label="view" frequency="5"/>
    <data:Tag label="visualization" frequency="3"/>
    <data:Tag label="wall" frequency="4"/>
    <data:Tag label="panorama" frequency="3"/>    
    <data:Tag label="Fish Eye" frequency="2"/>
    <data:Tag label="Random" frequency="15"/>
    <data:Tag label="layout" frequency="9"/>
    <data:Tag label="zoom" frequency="3" />    
    <data:Tag label="hover" frequency="7"/>
    <data:Tag label="camera" frequency="4"/>    
    <data:Tag label="skin" frequency="2"/>
    <data:Tag label="Cover Flow" frequency="2" />
    <data:Tag label="Carousel" />
    <data:Tag label="Spiral Zoom" />
    </mx:ArrayCollection>
        
    <mx:Script>
        <![CDATA[
    
        import mx.controls.Alert;
    import mx.core.IFlexDisplayObject;                               
        import mx.events.ListEvent;
       import mx.events.StyleEvent;        
    import mx.styles.StyleManager;
        import mx.styles.CSSStyleDeclaration;
        
        import com.openflux.utils.ListUtil;
        import com.plexiglass.cameras.ICamera;
        
    private var _skin:String;                
        private var _camera:ICamera;
        private var _selectedLayout:String;                
        private var _selectedItem:Tag;        
        private var _selectedItemDisplay:DisplayObject;

        [Bindable]
        private var showLayoutSettings:Boolean = false;
                
        /**
         * App initialization handler.
         */
        private function onAppInit():void
        {
            this.setFocus();
            this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }
        
        
        /* Layout change methods */
        
        /**
         * Layout change event handler.
         */
        private function onLayoutSelectionChange(event:ListEvent):void
        {
            // reset camera for new layout
            mouseCamera.xOffset = 0;
            mouseCamera.yOffset = 0;                        
            if (_camera == zoomCamera)
            {
                zoomCamera.zoomOut();
            }
            
            // get selected layout
            _selectedLayout = layoutSelector.selectedItem.data;            
            showLayoutSettings = false;
                                    
            // change layout and pick the most suitable camera
            switch (_selectedLayout)
            {
                case "random":
                    list.setStyle('layout', randomLayout);
                    changeCamera("hoverCamera");                                                            
                break;                                                
            case "circle":
                    list.setStyle('layout', circleLayout);
                    changeCamera("hoverCamera");                                                            
                    break;                            
            case "fishEyeCircle":
                    list.setStyle('layout', fishEyeCircleLayout);
                    changeCamera("hoverCamera");                                                            
                    break;                                            
                case "rollerCoaster":
                    list.setStyle('layout', topLeftLayout);
                    changeCamera("hoverCamera");                                        
                break;                                                                                                
            case "carousel":
                    list.setStyle('layout', carouselLayout);
                    changeCamera("simpleCamera");                                                                                                                                        
                    break;
            case "timeMachine":
                    list.setStyle('layout', timeMachineLayout);
                    changeCamera("hoverCamera");                                                            
                    break;
                case "spiral":
                    list.setStyle('layout', spiralLayout);
                    changeCamera("zoomCamera");                                         
                    break;                    
                case "horizontalFlow":
                list.setStyle('layout', coverFlowLayout); 
                coverFlowLayout.direction = 'horizontal';
                    changeCamera("mouseCamera");                            
                    showLayoutSettings = true;                                            
                    break;
            case "verticalFlow":
                    list.setStyle('layout', coverFlowLayout); 
                    coverFlowLayout.direction = 'vertical';
                    changeCamera("hoverCamera");
                    showLayoutSettings = true;                                                                                                                                                                                    
                    break;
            case "horizontalList":
                    list.setStyle('layout', horizontalLayout);
                    changeCamera("mouseCamera");
                    break;
                case "verticalList":
                    list.setStyle('layout', verticalLayout);
                    changeCamera("zoomCamera");                                                             
                break;
                case "flow":
                    list.setStyle('layout', flowLayout);
                    changeCamera("zoomCamera");                    
                    break;                
            default:    // reset to default
                list.setStyle('layout', coverFlowLayout); 
                coverFlowLayout.direction = 'horizontal';                    
                    break;                    
            }
            list.getFocus();                                                                    
        }    
                    
        
        /* Camera change methods */
        
        /**
         * Camera selection change event handler.
         */
        private function onCameraSelectionChange(event:ListEvent):void
        {
            changeCamera(cameraSelector.selectedItem.data);
        }
        
        /**
         * Changes camera selection.
         */
        private function changeCamera(cameraName:String):void
        {            
            switch (cameraName)
            {
                case "hoverCamera":
                    list.setStyle('camera', hoverCamera);
                    cameraSettingsStack.visible = true;                                                        
                    cameraSettingsStack.selectedIndex = 0;
                    cameraSelector.selectedIndex = 1;                                                                
                    break;
                case "mouseCamera":
                    list.setStyle('camera', mouseCamera);
                    cameraSettingsStack.visible = true;                                
                    cameraSettingsStack.selectedIndex = 1;
                    cameraSelector.selectedIndex = 2;                                                                                        
                    break;                        
                case "zoomCamera":
                    list.setStyle('camera', zoomCamera);
                    cameraSettingsStack.visible = false;
                    cameraSelector.selectedIndex = 3;                                                                        
                    break;
                default:    // simple camera
                    list.setStyle('camera', simpleCamera);    
                    cameraSettingsStack.visible = false;    
                    cameraSelector.selectedIndex = 0;            
                    break;                                                                                                                                                                                                                                                                        
            }
            _camera = ICamera(list.getStyle('camera'));
            this.setFocus();                                                        
        }
        
        
        /* Item Selection Methods */
        
        /**
         * List item click event handler.
         */
    private function onListItemClick(event:ListEvent):void
    {
          // get selected item and index
        _selectedItem = Tag(list.selectedItems.getItemAt(0));
      var selectedIndex:int = list ? Math.max(0, ListUtil.selectedIndex(list)) : 0;

            // highlight selected item
      highlightItem(selectedIndex);
      
      // do something else with the selected item here
      
            this.setFocus();                                                        
    }        
    
    /**
    * Changes item selection and zoom on key press.
    */
    private function onKeyDown(event:KeyboardEvent):void
    {
        switch (event.keyCode)
        {
            case Keyboard.LEFT:
                previousItem();
                break;
            case Keyboard.RIGHT:
                nextItem();
                break;
            case Keyboard.SPACE:
                // do something here
                break;
        }
        if (_camera == zoomCamera)
        {
            zoomCamera.zoomCamera();
        }
            this.setFocus();                                                        
    }

        /**
         * Selects the next item in the list.
         */
        private function nextItem():void
        {
          var selectedIndex:int = list ? Math.max(0, ListUtil.selectedIndex(list)) : 0;
            if (selectedIndex < data.length - 1)
            {
                gotoItem(++selectedIndex);
            }
        }
    
        /**
         * Selects the previous item in the list.
         */
        private function previousItem():void
        {
          var selectedIndex:int = list ? Math.max(0, ListUtil.selectedIndex(list)) : 0;
            if (selectedIndex > 0)
            {
                gotoItem(--selectedIndex);
            }
        }
    
        /**
         * Selects the specified item in the list.
         */
        private function gotoItem(selectedIndex:uint):void
        {
            if (selectedIndex >= 0 && selectedIndex < data.length)
            {
                list.selectedItems = new ArrayCollection([list.data.getItemAt(selectedIndex)]); 
                highlightItem(selectedIndex);
            }           
        }
    
        /**
         * Highlights the selected item in the list.
         */
    private function highlightItem(selectedIndex:uint):void
    {
        if (_selectedItemDisplay != null)
        {
            // remove highlight filter from the currently selected item display object
            _selectedItemDisplay.filters = new Array();
        }

            // get selected photo display object
            _selectedItemDisplay = listView.getChildAt(selectedIndex);
        if (_selectedItemDisplay != null)
        {
            // add glow filter
            _selectedItemDisplay.filters = [glow];
            }
    }
    
        /**
         * Changes the selected skin by unloading current style declarations
         * and loading new style declarations from the embedded stylesheet swf file.
         */
        private function changeSkin(skinUrl:String ):void 
        {
            if (_skin != null)
            {
                StyleManager.unloadStyleDeclarations(_skin, true);
            }
            _skin = skinUrl;
        var styleEvent:IEventDispatcher = 
            StyleManager.loadStyleDeclarations(_skin, true);
    }          

        ]]>
    </mx:Script>
    
  <mx:Style>
      List 
    {
      camera: ClassReference("com.plexiglass.cameras.SimpleCamera");
    }
    Tag
    {
            view: ClassReference("com.randomFractals.openflux.views.TagView");
    }
  </mx:Style>
    
        
    <mx:GlowFilter id="glow" color="#FAFBDF" strength="1" />
        
    <!-- OpenFlux Layouts -->
    <layouts:RandomLayout id="randomLayout" 
        gap="50" selectedItemZPosition="-200" />    
    <layouts:CircleLayout id="circleLayout" 
        selectedItemZPosition="-200" />
    <layouts:FishEyeCircleLayout id="fishEyeCircleLayout" 
        selectedItemZPosition="-200" />                    
    <layouts:RollerCoasterLayout id="rollerCoasterLayout" yOffset="200" />
    <openflux:CarouselLayout id="carouselLayout" />    
    <openflux:TimeMachineLayout id="timeMachineLayout" gap="60.0" />        
    <openflux:SpiralLayout id="spiralLayout" gap="400" />    
    <openflux:CoverFlowLayout id="coverFlowLayout" 
        angle="{coverAngle.value}" 
        gap="{coverGap.value}" 
        distance="{coverDistance.value}"/>        
    <openflux:HorizontalLayout id="horizontalLayout" gap="1.0" />    
    <openflux:VerticalLayout id="verticalLayout" gap="1.0" />
    <openflux:TopLeftLayout id="topLeftLayout" />
    <openflux:FlowLayout id="flowLayout" measuredGap="5" 
        horizontalAlignment="center" verticalAlignment="middle"/>        

    <!-- Plexiglass Cameras -->
    <cameras:HoverCamera id="hoverCamera" 
        maxPanAngle="{maxPanAngle.value}" maxTiltAngle="{maxTiltAngle.value}" />    
    <cameras:MouseCamera id="mouseCamera" distance="10" 
        xOffset="{xCameraOffset.value}" yOffset="{yCameraOffset.value}" />
    <cameras:ZoomCamera id="zoomCamera" />
    <openflux:SimpleCamera id="simpleCamera" />        
    
    <!-- Layout Selection UI -->
    <mx:VBox width="20%" height="100%">
        
        <mx:Label text="Layout:" />            
        <mx:ComboBox id="layoutSelector" rowCount="12" 
            change="onLayoutSelectionChange(event)" selectedIndex="0">
            <mx:ArrayCollection>
          <mx:Object data="random" label="Random"/>
          <mx:Object data="circle" label="Circle" />
          <mx:Object data="fishEyeCircle" label="Fishe Eye Circle" />                              
          <mx:Object data="rollerCoaster" label="Roller Coaster"/>                      
          <mx:Object data="carousel" label="Carousel"/>
          <mx:Object data="timeMachine" label="Time Machine"/>
          <mx:Object data="spiral" label="Spiral"/>                                        
          <mx:Object data="horizontalFlow" label="Horizontal Cover Flow"/>
          <mx:Object data="verticalFlow" label="Vertical Cover Flow"/>
          <mx:Object data="horizontalList" label="Horizontal List"/>
          <mx:Object data="verticalList" label="Vertical List"/>
          <mx:Object data="flow" label="Grid"/>
        </mx:ArrayCollection>
        </mx:ComboBox>
        
        <!-- Layout Settings -->
        <mx:ViewStack id="layoutSettingsStack" width="100%" 
            visible="{showLayoutSettings}" 
            includeInLayout="{showLayoutSettings}">
            
            <!-- Cover Flow Settings -->
            <mx:VBox id="coverFlowSettings">                
                <mx:Label text="Cover Flow Settings:" />                
                <mx:Label text="Gap:"/>
                <mx:HSlider id="coverGap" width="100" 
                    value="2" maximum="20" 
                    tickInterval="2" snapInterval="2" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true"/>
            
                <mx:Label text="Angle:"/>
                <mx:HSlider id="coverAngle" width="100" 
                    value="40" maximum="90" 
                    tickInterval="10" snapInterval="10" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true"/>

                <mx:Label text="Distance:"/>
                <mx:HSlider id="coverDistance" width="100" 
                    value="120" maximum="200"
                    tickInterval="10" snapInterval="10" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true" />
            
            </mx:VBox>
            
        </mx:ViewStack>
                
        <mx:Spacer height="20" />        
                
        <!-- Camera Selection UI -->        
        <mx:Label text="Camera:" />            
        <mx:ComboBox id="cameraSelector" 
            change="onCameraSelectionChange(event)" selectedIndex="0">
            <mx:ArrayCollection>
         <mx:Object data="simpleCamera" label="Simple Camera"/>                              
         <mx:Object data="hoverCamera" label="Hover Camera"/>
         <mx:Object data="mouseCamera" label="Mouse Camera"/>
         <mx:Object data="zoomCamera" label="Zoom Camera"/>
        </mx:ArrayCollection>
        </mx:ComboBox>
        
        <!-- Camera Settings -->
        <mx:ViewStack id="cameraSettingsStack" 
            width="100%" visible="false">
        
            <mx:VBox id="hoverCameraSettings" 
                width="100%" height="100%">
                <mx:Label text="Hover Camera Settings:" />
                <mx:Label text="maxPanAngle:" />
                <mx:HSlider id="maxPanAngle" width="100" 
                    value="20" minimum="0" maximum="80" 
                    tickInterval="10" snapInterval="10" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true"/>
                    
                <mx:Label text="maxTiltAngle:" />
                <mx:HSlider id="maxTiltAngle" width="100" 
                    value="20" minimum="0" maximum="90" 
                    tickInterval="10" snapInterval="10" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true"/>                
            </mx:VBox>                    
            
            <mx:VBox id="mouseCameraSettings" 
                width="100%" height="100%" 
                horizontalScrollPolicy="off" 
                verticalScrollPolicy="off">
                <mx:Label text="Mouse Camera Settings:" />
                <mx:Label text="xOffset:" />
                <mx:HSlider id="xCameraOffset" width="100" 
                    value="100" minimum="-400" maximum="400" 
                    tickInterval="10" snapInterval="10" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true"/>
                    
                <mx:Label text="yOffset:" />
                <mx:HSlider id="yCameraOffset" width="100" 
                    value="0" minimum="-400" maximum="400" 
                    tickInterval="10" snapInterval="10" 
                    liveDragging="true"
                    showDataTip="true" 
                    dataTipPlacement="right"
                    showTrackHighlight="true"/>                
            </mx:VBox>            
        </mx:ViewStack>

        <mx:Spacer height="20" />        
            
        <!-- Skin Selection -->
        <mx:Label text="Skin:" />
        <mx:ComboBox id="skinSelector" 
            change="{changeSkin(skinSelector.selectedItem.data);}">
            <mx:ArrayCollection>
        <mx:Object label="Dark" data="assets/skins/defaultStyles.swf"/>
        <mx:Object label="Red" data="assets/skins/red.swf"/>                 
         </mx:ArrayCollection>
        </mx:ComboBox>
        
        <mx:Spacer height="20" />
        
        <mx:Label text="Keyboard Navigation:" />
        <mx:Text width="100%" 
            text="use arrow keys to select next/previous item. Hit spacebar to zoom in/out with Zoom Camera." />
            
    </mx:VBox>
    
    <!-- OpenFlux Plexiglass list -->
  <openflux:List id="list" data="{data}" 
      layout="{randomLayout}" 
      width="80%" height="100%" styleName="list"
      doubleClickEnabled="true" useHandCursor="true" 
        itemClick="onListItemClick(event);" 
        itemDoubleClick="onListItemClick(event);">
            <openflux:view>
                <openflux:PlexiListView id="listView"  />
            </openflux:view>      
  </openflux:List>
        
</mx:Application>