package {
    import extras.Slide;
    
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.*;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.utils.Timer;

    [SWF(width="640", height="260", frameRate="31", backgroundColor="#000000")]
    public class Slideshow extends Sprite
    {
        protected var data_path :String = 'data/slides.php';
        protected var slides :Array = [];
        protected var myLoader :URLLoader = new URLLoader();
        protected var transition_speed :Number = 1; // In seconds
        protected var transition_delay :Number = 6; // In seconds
        protected var current_slide :int = 0;
        protected var myTimer :Timer;
        
        /**
         * The Slideshow object proper. This simply builds the display and begins to load the individual slides
         * 
         * @constructor
         * @return Slideshow
         */
        public function Slideshow()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align     = StageAlign.TOP_LEFT;
            
            this.loadSlides(this.data_path);
        }
        
        /**
         * Attempts to read the XML document from the provided path and load the slides from it
         * 
         * @param String path The path to the XML document
         * @return void
         */
        protected function loadSlides (path :String) :void
        {
            this.myLoader.load(new URLRequest(path));
            this.myLoader.addEventListener(Event.COMPLETE, processSlidesFromXML);
        }
        
        /**
         * Once the XML has loaded, we call this method to build our Slide objects and attach them to the show
         * 
         * @param Event e The Event.COMPLETE event signaling a successful load
         * @return void
         */
        protected function processSlidesFromXML (e :Event) :void
        {
            this.myLoader.removeEventListener(Event.COMPLETE, processSlidesFromXML);
            var myXML :XML = new XML(e.target.data);
            
            for (var i :int = 0; i < myXML.slide.length(); i++)
            {
                var slide :Slide = new Slide(myXML.slide[i], stage.stageWidth, stage.stageHeight);
                this.slides.push(slide);
                this.addChild(slide);
            }
            
            // Display the first slide
            this.slides[0].visible = true;
            this.slides[0].setLoadedCallback(launchTimer);
        }
        
        /**
         * Fades from the current slide to the one at the provided index
         * 
         * @param int index The desired slide index
         * @return void
         */
        protected function fadeTo (index :int) :void
        {
            // Check valid range
            if (index >= 0 && index < this.slides.length)
            {
                var t_rate :Number = (1 / this.transition_speed) / stage.frameRate; 
                
                this.slides[this.current_slide].fadeOut(t_rate);
                this.slides[index].fadeIn(t_rate);
                this.current_slide = index;
            }
        }
        
        /**
         * Sets up the timer for the actual automated rotation.
         * 
         * @return void
         */
        protected function launchTimer () :void
        {
            this.myTimer = new Timer(this.transition_delay * 1000);
            this.myTimer.addEventListener(TimerEvent.TIMER, showNextSlide);
            this.myTimer.start();
        }
        
        /**
         * Shows the next incremental slide in the show based on what is currently visible
         * 
         * @param TimerEvent e The TimerEvent.TIMER event signaling the switch
         * @return void
         */
        protected function showNextSlide (e :TimerEvent) :void
        {
            var index :int = this.current_slide + 1;
            if (index >= this.slides.length)
            {
                index = 0;
            }
            
            this.fadeTo(index);
        }
    }
}