<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute"
    creationComplete="init();" 
    backgroundGradientColors="[#000000, #3e3e3e]"
    horizontalScrollPolicy="off"
    verticalScrollPolicy="off" viewSourceURL="srcview/index.html">
    <mx:Script>
        <![CDATA[
            import mx.effects.easing.*;
            import mx.managers.PopUpManager;
            import mx.controls.Alert;
            import mx.managers.CursorManager;
            import data.PodcastVO;
            import mx.collections.ArrayCollection;
            import flash.utils.describeType;
            import com.adobe.webapis.odeo.events.OdeoResultEvent;
            import com.adobe.webapis.odeo.OdeoService;
            
            /**
             * Basic Odeo API Example
             * Sean Moore
             * seantheflashguy.com
             * actionscriptcheatsheet.com
             * seantheflashguy@gmail.com
             * 09/30/07
             */
             
            private var odeoService:OdeoService;             
            private var podcastSound:Sound;
            private var podcastSoundChannel:SoundChannel;
            private var searchTimer:Timer;
            private var searching:Boolean = false;
            private var odeoBusyServerAlert:*;
            private var flashTimeline:*;
            private var mp3Player_mc:MovieClip;
            private var playButton_mc:MovieClip;
            private var pauseButton_mc:MovieClip;
            private var stopButton_mc:MovieClip;
            private var podcastSoundPosition:Number;
            private var podcastSoundIsPlaying:int;
                      
            [Bindable]
            private var podcasts:ArrayCollection;             
            [Bindable]
            private var DEFAULT_SEARCH_TEXT:String = "Enter a search term.";             
            [Bindable]
            private var tileListY:Number;            
            [Bindable]
            private var logoYPos:Number;
             
            private function init():void
             {                 
                 createOdeoService();
                 reflectSearchCanvas();                 
                 initUI();
                 setupApplicationListeners();                                                   
             }
             private function initUI():void
             {
                 mainProgressBar.visible = false;
                 tileListY = headerBGCanvasReflection.height + headerBGCanvasReflection.y;                                               
                 odeoLogo.y = -100;
                 mp3PlayerSWF.y = -100;
                 headerBar.y = -100;
             }
             private function setupApplicationListeners():void
             {
                 addEventListener( Event.ENTER_FRAME, onAppEnterFrame );
                 addEventListener( KeyboardEvent.KEY_DOWN, keyPressed );
             }
             private function keyPressed( event:KeyboardEvent ):void
             {
                if ( event.keyCode == Keyboard.ENTER ) { 
                    doOdeoSearch();
                }
             }
             private function onAppEnterFrame( event:Event ):void
             {
                 if ( searchText.text.length <= 0 ) {
                     reflectSearchCanvas();
                 }
             }
             private function createOdeoService():void
             {
                 odeoService = new OdeoService();
                 odeoService.addEventListener( OdeoResultEvent.ON_SEARCH_TAG_RESULT, onOdeoServiceResult );
                 odeoService.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onOdeoServiceSecurityError );
                 odeoService.addEventListener( IOErrorEvent.IO_ERROR, onOdeoServiceIOError );
             }
             private function onOdeoServiceSecurityError( event:SecurityErrorEvent ):void
             {
                 trace( ">> onOdeoServiceSecurityError" );    
             }
             private function onOdeoServiceIOError( event:IOErrorEvent ):void
             {
                 trace( ">> onOdeoServiceIOError" );
             }
             private function doOdeoSearch():void
             {
                 if ( searchText ) {                     
                     searching = true;                     
                     searchOdeoServiceByTag(searchText.text);                     
                     searchTimer = new Timer(20000, 1);
                     searchTimer.addEventListener( TimerEvent.TIMER_COMPLETE, onSearchTimerCompleted );
                     searchTimer.start();
                }
             }
             private function onSearchTimerCompleted( event:TimerEvent ):void
             {
                 // after 20 seconds if the odeo service is flaking out
                 // remove the progress bar and return the cursor to
                 // regular pointer mode...
                 if ( searching ) {
                     searching = false;
                     mainProgressBar.visible = false;
                     CursorManager.removeBusyCursor();
                     var msg:String = "Odeo is currently experiencing a heavy server load. Please try your search again.";
                     odeoBusyServerAlert = Alert.show( msg, "Odeo busy, try again." );

                 }
                 trace( ">> onSearchTimerCompleted called @ " + getTimer() + " ms" );
             }
             private function searchOdeoServiceByTag( tag:String ):void
             {
                 if ( tag ) {
                     podcasts = null;
                    odeoService.searchTag(tag);
                    mainProgressBar.visible = true;
                    CursorManager.setBusyCursor();
                }
             }
             private function onOdeoServiceResult( event:OdeoResultEvent ):void
             {                 
                 searching = false;
                 if ( odeoBusyServerAlert ) {
                     odeoBusyServerAlert.visible = false;
                     PopUpManager.removePopUp( odeoBusyServerAlert );
                }
                 
                 mainProgressBar.visible = false;
                 CursorManager.removeBusyCursor();
                 
                 var e:OdeoResultEvent = event;
                 //trace(flash.utils.describeType(e));
                 //trace("e.data.podcasts="+e.data.podcasts);
                 var podcastsArray:Array = new Array;
                for ( var i:uint=0; i<e.data.podcasts.length; i++ ) {
                    var podcastVO:PodcastVO = new PodcastVO( e.data.podcasts[i] );
                    podcastsArray.push( podcastVO );
                }
                 podcasts = new ArrayCollection( podcastsArray );                 
                 odeoResultTileList.visible = true;
             }
             private function onOdeoResultTileListClicked( event:Event ):void
             {                 
                 playPodcast(event.currentTarget.selectedItem.url);
             }
             private function playPodcast( url:String ):void
             {
                LCDText.text = odeoResultTileList.selectedItem.title;
                 
                 if ( podcastSound ) {
                     podcastSound.close();
                     podcastSound.removeEventListener( Event.COMPLETE, onPodcastSoundComplete );
                    podcastSound = null;
                 }

                podcastSound = new Sound();
                podcastSound.addEventListener( IOErrorEvent.IO_ERROR, onSoundIOError );
                podcastSound.load( new URLRequest( url ) );
                
                if ( podcastSoundChannel ) {
                    podcastSoundChannel.stop();
                    podcastSoundChannel = null;
                }
                podcastSoundChannel = new SoundChannel();
                podcastSoundChannel = podcastSound.play( 0 );
                
                var voltransform:SoundTransform = podcastSoundChannel.soundTransform;
                voltransform.volume = 0.6;                
                podcastSoundChannel.soundTransform = voltransform;
             }
             private function onPodcastSoundComplete(event:Event):void
             {
                trace( ">> onPodcastSoundComplete" );
             }
             private function onSoundIOError( event:IOErrorEvent ):void
             {
                 trace( ">> onSoundIOError" );
             }
             private function onSearchTextChanged( event:Event ):void
             {
                 reflectSearchCanvas();
                 if ( event.currentTarget.text <= 0 ) {
                     searchBtn.enabled = false;
                 } else {
                     searchBtn.enabled = true;
                 }
             }
             private function reflectSearchCanvas():void
             {
                 headerBGCanvasReflection.graphics.clear();
                 
                 var bd:BitmapData = new BitmapData( searchTextCanvas.width, searchTextCanvas.height );
                bd.draw(searchTextCanvas);
                headerBGCanvasReflection.graphics.beginBitmapFill( bd );
                headerBGCanvasReflection.graphics.drawRect( 0, 0, headerBGCanvasReflection.width, headerBGCanvasReflection.height );
                headerBGCanvasReflection.graphics.endFill();
                headerBGCanvasReflection.scaleY = -1;
                headerBGCanvasReflection.y = searchTextCanvas.y + searchTextCanvas.height*2;    

                 createSearchCanvasMask();
                 
             }         
             private function createSearchCanvasMask():void
             {
                 reflectionMaskCanvas.graphics.clear();
                 var fillType:String = GradientType.LINEAR;
                var colors:Array = [0xFF0000, 0x0000FF];
                var alphas:Array = [100, 0];
                var ratios:Array = [0, 255];
                var matr:Matrix = new Matrix();
                matr.createGradientBox( headerBGCanvasReflection.width, headerBGCanvasReflection.height, (90/180)*Math.PI, 0, 0 );
                var spreadMethod:String = SpreadMethod.PAD;
                reflectionMaskCanvas.graphics.beginGradientFill( fillType, colors, alphas, ratios, matr, spreadMethod );  
                reflectionMaskCanvas.graphics.drawRect( 0,0,headerBGCanvasReflection.width,headerBGCanvasReflection.height );
                reflectionMaskCanvas.cacheAsBitmap = true;
                headerBGCanvasReflection.cacheAsBitmap = true;
                headerBGCanvasReflection.mask = reflectionMaskCanvas;
             }
             private function onSearchTextFocused( event:Event ):void
             {
                 trace( ">> onSearchTextFocused" );                 
                 searchText.text = "";         
                 searchText.setStyle( "color", "0x000000" );
             }
             private function onSearchOdeoBtnClicked(event:Event):void
             {
                 doOdeoSearch();
             }
             private function onMP3PlayerSWFCompleted( event:Event ):void
             {                 
                 flashTimeline = event.currentTarget.content;
                 mp3Player_mc = flashTimeline.mp3Player;
                 playButton_mc = mp3Player_mc.playButton;
                 pauseButton_mc = mp3Player_mc.pauseButton;
                 stopButton_mc = mp3Player_mc.stopButton;
                 stopButton_mc.useHandCursor = true;
                 stopButton_mc.buttonMode = true;
                 stopButton_mc.addEventListener( MouseEvent.CLICK, onStopButtonClicked );
                 stopButton_mc.addEventListener( MouseEvent.MOUSE_OVER, onMP3PlayerButtonMouseOver );
                 stopButton_mc.addEventListener( MouseEvent.MOUSE_OUT, onMP3PlayerButtonMouseOut );
                 
                 playButton_mc.useHandCursor = true;
                 playButton_mc.buttonMode = true;
                 playButton_mc.addEventListener( MouseEvent.CLICK, onPlayButtonClicked );
                 playButton_mc.addEventListener( MouseEvent.MOUSE_OVER, onMP3PlayerButtonMouseOver );
                 playButton_mc.addEventListener( MouseEvent.MOUSE_OUT, onMP3PlayerButtonMouseOut );
                 
                 pauseButton_mc.useHandCursor = true;
                 pauseButton_mc.buttonMode = true;
                 pauseButton_mc.addEventListener( MouseEvent.CLICK, onPauseButtonClicked );
                 pauseButton_mc.addEventListener( MouseEvent.MOUSE_OVER, onMP3PlayerButtonMouseOver );
                 pauseButton_mc.addEventListener( MouseEvent.MOUSE_OUT, onMP3PlayerButtonMouseOut );                 
                 
                 MP3PlayerAnimation.play( [mp3PlayerSWF] );             
             }
             private function onStopButtonClicked( event:MouseEvent ):void
             {
                 if ( podcastSoundChannel ) {
                    podcastSoundChannel.stop();
                    podcastSoundIsPlaying = 1;
                    podcastSoundPosition = 0;
                 }
             }
             private function onPlayButtonClicked( event:MouseEvent ):void
             {                 
                 if ( podcastSoundChannel ) {
                    if ( podcastSoundIsPlaying == 0 )    {                
                    } else {
                        podcastSoundChannel = podcastSound.play( podcastSoundPosition );            
                        podcastSoundIsPlaying = 0;            
                    }
                 }
             }
             private function onPauseButtonClicked( event:MouseEvent ):void
             {
                 if ( podcastSoundChannel ) {
                    podcastSoundPosition = podcastSoundChannel.position;
                    podcastSoundChannel.stop();
                    podcastSoundIsPlaying = 1;
                 }
             }
             private function onMP3PlayerButtonMouseOver( event:MouseEvent ):void
             {
             }
             private function onMP3PlayerButtonMouseOut( event:MouseEvent ):void
             {
             }             
             private function onSeanTheFlashGuyLogoClicked( event:MouseEvent ):void
             {
                 var request:URLRequest = new URLRequest( "http://www.seantheflashguy.com/blog" );
                navigateToURL( request, "_blank" );
             }
        ]]>
    </mx:Script>    
    <mx:Parallel id="HeaderBarAnimation">
        <mx:children>
            <mx:Move startDelay="500" 
                easingFunction="Quadratic.easeOut" 
                duration="1500" 
                yFrom="-100" yTo="0"/>                
            <mx:Fade startDelay="500" 
                easingFunction="Quadratic.easeOut" 
                duration="1500"/>
        </mx:children>
    </mx:Parallel>
    
    <mx:Parallel id="LogoAnimation">
        <mx:children>
            <mx:Move startDelay="500" 
                easingFunction="Bounce.easeOut" 
                duration="1200" 
                yFrom="-100" 
                yTo="60"/>
            <mx:Fade startDelay="500" 
                easingFunction="Bounce.easeOut" 
                duration="1000"/>
        </mx:children>
    </mx:Parallel>            
    <mx:Parallel id="MP3PlayerAnimation">
        <mx:children>
            <mx:Move startDelay="1000" 
                easingFunction="Bounce.easeOut" 
                duration="1200" 
                yFrom="-100" yTo="60"/>
            <mx:Fade startDelay="1000" 
                easingFunction="Bounce.easeOut" 
                duration="1000"/>
        </mx:children>
    </mx:Parallel>    
    <mx:Parallel id="ProgressBarAnimationShow">
        <mx:children>                
            <mx:Fade duration="1000"/>
            <mx:WipeUp duration="1000"/>
        </mx:children>
    </mx:Parallel>    
    <mx:Parallel id="ProgressBarAnimationHide">
        <mx:children>                
            <mx:Fade duration="1000"/>
            <mx:WipeDown duration="1000"/>
        </mx:children>
    </mx:Parallel>    
    <mx:Parallel id="STFGLogoAnimation">
        <mx:children>
            <mx:WipeLeft duration="1000"/>
            <mx:Fade duration="1000"/>
        </mx:children>
    </mx:Parallel>    
    <mx:Image id="odeoLogo" 
        x="77" y="60" 
        completeEffect="LogoAnimation" 
        source="images/odeo_logo.jpg" 
        scaleContent="false" 
        autoLoad="true"/>    
    <mx:Canvas id="searchTextCanvas" 
        x="66" y="143" 
        width="751" height="71" 
        backgroundColor="#000000" >
        <mx:TextInput id="searchText" 
            focusIn="onSearchTextFocused(event);" 
            text="{DEFAULT_SEARCH_TEXT}" 
            x="10" y="10" 
            change="onSearchTextChanged(event);" 
            color="#b6b6b6" 
            width="626" height="55" 
            fontSize="33"/>
        <mx:Button id="searchBtn" 
            click="onSearchOdeoBtnClicked(event);" 
            x="644" y="10" 
            label="&gt;&gt;" 
            color="#060606" 
            width="97" height="55" 
            fontSize="33"/>
    </mx:Canvas>    
    <mx:Canvas id="headerBGCanvasReflection" 
        alpha="0.35" 
        width="751" height="71" 
        x="66" y="214"  
        backgroundColor="#000000">    
    </mx:Canvas>
    <mx:Canvas id="reflectionMaskCanvas" 
        width="751" height="71" 
        x="66" y="214">
    </mx:Canvas>    
    <mx:TileList id="odeoResultTileList"
        dataProvider="{podcasts}" 
        width="100%" height="100%"
        rowHeight="108"
        columnCount="1"
        itemRenderer="ui.OdeoResultRenderer" 
        alternatingItemColors="[0x181818, 0x000000]"
        backgroundAlpha="0.0"
        click="onOdeoResultTileListClicked(event)"
        visible="false"
        showEffect="Fade"
        horizontalScrollPolicy="off"
        rollOverColor="#323232"
        selectionColor="#323232"
        y="280"
        borderStyle="none"/>    
    <mx:SWFLoader id="headerBar" 
        source="ui/headerBar.swf" 
        visible="true" 
        x="0" 
        y="0"
        width="100%" height="15" 
        completeEffect="HeaderBarAnimation"
         scaleContent="false"/>    
    <mx:ProgressBar id="mainProgressBar"
        x="0" y="0" 
        visible="false"
        hideEffect="ProgressBarAnimationHide"
        showEffect="ProgressBarAnimationShow"
        labelPlacement="center" 
        indeterminate="true" 
        label=""
        height="15" width="100%" alpha="0.33"/>
    <mx:SWFLoader y="60" id="mp3PlayerSWF" 
        complete="onMP3PlayerSWFCompleted(event);" 
        x="530"
        source="ui/mp3player.swf"/>
    <mx:Label id="LCDText" 
        x="553" y="78" 
        width="181" height="21" 
        color="#001a22"/>
    <mx:SWFLoader id="seantheflashguyLogo" 
        right="25" bottom="18" 
        source="ui/seantheflashguylogosmall.swf"
        click="onSeanTheFlashGuyLogoClicked(event);"
        useHandCursor="true"
        buttonMode="true"
        completeEffect="STFGLogoAnimation"/>
</mx:Application>