/*global cmsLoad, jQuery*/
var cmsFiles = ['jquery/timer/jquery.timers.js'];
if(typeof(cmsLoad) === 'function'){
    cmsLoad(cmsFiles);
}

/**
 * A JQuery plugin that will setup a slideshow.
 *
 * @version 1.0
 * @requires
 *      jquery.js
 *      jquery.ui.js - Slide Animation Effects
 *      jquery.timers.js - Slide timed transitions
 * @author Ed Rodriguez Ed.Rodriguez@swfwmd.state.fl.us
 * @param string lapse The defined next tag to show and hide
 * @param string speed The animation speed: slow, fast, normal
 */
(function($){
    $.fn.slideshow = function(options){
		/*------------------
			OBJECT SETUP
		------------------*/
        
		// PRIVATE
        var opts = $.extend({}, $.fn.slideshow.defaults, options);
        var state = 'playing';
        var slides = [];
        
        if(this.children().length <= 0){
            this.show();
            return(this);   
        }
        
        // PUBLIC
        this.inprogress = false;
        this.nav = undefined;
        this.display = undefined;
        this.mode = undefined;
        
        // SET SLIDE
        this.slide = function(next){
            var plugin = this;
            next = Number(next) - 1;
            
            // LOOPING
            if(next > slides.length - 1){
                next = 0;
            }else if(next < 0){
                next = (slides.length - 1);
            }
            
            if(this.inprogress === false){
                $(plugin).stopTime();
                plugin.mode = undefined;
                this.inprogress = true; // ALLEVIATES ASYNC CALLS
                
                this.hide(opts.current, next);
                
                // UPDATE DISPLAY
                this.setDisplay(next);
                
                // NEXT SETUP
                opts.current = next;
                if(opts.current >= slides.length){
                    opts.current = 0;
                }
                
                if(slides.length > 1){
                    $(plugin).everyTime(opts.lapse, function(i){
                        plugin.loop();
                    }, 0);
                }
            }else if(opts.fast){ // FAST TRANSITION (handles rapid clicking)
                $(plugin).stopTime();
                plugin.mode = 'fast';
                this.setNav(next);
                
                // FAST TRANSITION (solves previous issues & bugs)
                $(slides).each(function(i){
                   if(i !== next){
                        $(this).stop(true, true);
                        $(this).css({display:'none'});
                   }
                });
                $(slides[next]).css({display:'block'});               
                
                // UPDATE DISPLAY
                this.setDisplay(next);
                
                // NEXT SETUP
                opts.current = next;
                if(opts.current >= slides.length){
                    opts.current = 0;
                }
                
                // MODE RESET TIMEOUTS
                $(plugin).oneTime(2000, function(i){
                    plugin.mode = undefined;
                    plugin.inprogress = false;
                    $(plugin).everyTime(opts.lapse, function(i){
                        plugin.loop();
                    }, 0);
                }, 0);
            }
        };
        
        this.hide = function(slide, next){
            var plugin = this;
            this.setNav(next);
            
            // HIDE (jquery ui effects)
            if(opts.hide.effect === 'blind' ||
               opts.hide.effect === 'clip' ||
               opts.hide.effect === 'drop' ||
               opts.hide.effect === 'explode' ||
               opts.hide.effect === 'fold' ||
               opts.hide.effect === 'puff' ||
               opts.hide.effect === 'slide' ||
               opts.hide.effect === 'scale'){
                    var html = $(slides[slide]).html();
                    $(slides[slide]).hide(opts.hide.effect, opts.hide.options, opts.hide.speed, function(){
                        $(this).html(html);
                        if(next !== undefined){
                            plugin.show(next);
                        }
                    });
            }
            // HIDE (default effects)
            if(opts.hide.effect === 'fade'){
                $(slides[slide]).fadeOut(opts.hide.speed, function(){
                    if(next !== undefined){
                        plugin.show(next);
                    }
                });
            }
            // HIDE (no effects)
            if(opts.hide.effect === 'none'){
                $(slides[slide]).hide();
                if(next !== undefined){
                    plugin.show(next);
                }
            }
        };
        
        this.show = function(slide){
            var plugin = this;
            if(plugin.mode !== 'fast'){
                // SHOW (jquery ui effects)
                if(opts.show.effect === 'blind' ||
                   opts.show.effect === 'clip' ||
                   opts.show.effect === 'drop' ||
                   opts.show.effect === 'explode' ||
                   opts.show.effect === 'fold' ||
                   opts.show.effect === 'puff' ||
                   opts.show.effect === 'slide' ||
                   opts.show.effect === 'scale'){
                        var html = $(slides[slide]).html();
                        $(slides[slide]).show(opts.show.effect, opts.show.options, opts.show.speed, function(){
                            $(this).html(html);
                            plugin.inprogress = false;
                        });
                }
                // SHOW (default effects)
                if(opts.show.effect === 'fade'){
                    $(slides[slide]).fadeIn(opts.show.speed, function(){
                        plugin.inprogress = false;   
                    });
                }
                // SHOW (no effects)
                if(opts.show.effect === 'none'){
                    $(slides[slide]).show();
                    plugin.inprogress = false;
                }
            }else{
                plugin.mode  = undefined;
            }
        };
        
        // LOOP
        this.loop = function(){
            if(state === 'playing'){
                var num = (opts.current + 1) + 1;
                this.slide(num);
            }
        };
        
        // PREVIOUS
        this.previous = function(event){
            var num = (opts.current - 1) + 1;
            this.slide(num);
            return(false);
        };
        
        // NEXT
        this.next = function(event){
            var num = (opts.current + 1) + 1;
            this.slide(num);
            return(false);
        };
        
        // PAUSE
        this.pause = function(event){
            if(state === 'playing'){
                state = 'paused';
            }else{
                this.inprogress = false;
                state = 'playing';
            }
            return(false);
        };
        
        this.setNav = function(slide){
            // NAVIGATION
            if(this.nav !== undefined){
                this.nav.each(function(i){
                    $(this).children().removeClass(opts.navOn);
                    var item = $($(this).children().get(slide + opts.navOffset));
                    if(!item.hasClass(opts.navOn)){
                        item.addClass(opts.navOn);
                    } 
                });
            }
        };
        
        this.setDisplay = function(slide){
            if(this.display !== undefined){
                var output = (slide+1) + opts.displayText + slides.length;
                this.display.html(output);
            }
        };
        
        // SETUP
        this.setup = function(){
            state = opts.state;
            slides = this.children();
            
            // START
            var start = opts.start;
            if(typeof(start) === 'string'){
                start = start.toLowerCase();
                if(start === 'random'){ // RANDOM STARTS
                    start = Math.floor(Math.random()*slides.length);
                }else if(start === 'first'){
                    start = 0;
                }else if(start === 'last'){
                    start = slides.length - 1;
                }else if(Number(start) >= 1){
                    start = Number(start) - 1;
                }else{
                    start = 0;
                }
            }else if(typeof(start) === 'number'){
                start = start - 1;
            }else{
                start = 0;
            }
            
            if(typeof(start) === 'number'){
                if(start >= slides.length){
                    start = 0;
                }else if(start < 0){
                    start = 0;
                }
            }else{
                start = 0;
            }
            
            opts.current = start;
            opts.hide.effect = opts.hide.effect.toLowerCase();
            opts.show.effect = opts.show.effect.toLowerCase();
            $(slides).hide();
            $(slides[start]).show();
            $(slides[start]).parent().fadeIn();
            
            // LOOP
            var plugin = this;
            if(slides.length > 1){
                $(plugin).everyTime(opts.lapse, function(i){
                    plugin.loop();
                }, 0);
            }
            
            var temp;
            // PAUSE BUTTON
            if(typeof(opts.pause) === 'object' || typeof(opts.pause) === 'string'){
                temp = $(opts.pause);
                temp.bind('click', {}, function(event){
                    plugin.pause(event);
                });
            }
            
            // NEXT BUTTON
            if(typeof(opts.next) === 'object' || typeof(opts.next) === 'string'){
                temp = $(opts.next);
                if(temp.length > 0){
                    temp.bind('click', {}, function(event){
                        plugin.next(event);
                    });
                }
            }
            
            // PREVIOUS BUTTON
            if(typeof(opts.previous) === 'object' || typeof(opts.previous) === 'string'){
                temp = $(opts.previous);
                if(temp.length > 0){
                    temp.bind('click', {}, function(event){
                        plugin.previous(event);
                    });
                }
            }
            
            // DISPLAY FIELD
            if(typeof(opts.display) === 'object' || typeof(opts.display) === 'string'){
                temp = $(opts.display);
                if(temp.length > 0){
                    this.display = temp;
                    this.setDisplay(opts.current);
                }
            }
            
            // NAVIGATION
            if(typeof(opts.nav) === 'object' || typeof(opts.nav) === 'string'){
                temp = $(opts.nav);
                if(temp.length > 0){
                    this.nav = temp;
                }
            }
            this.setNav(start);
        };
        
        // INIT
        this.setup();
        return(this);
    };
    $.fn.slideshow.defaults = {
        show: {
            effect: 'fade',
            options: {},
            speed: 1000
        },
        hide: {
            effect: 'fade',
            options: {},
            speed: 1000
        },
        fast: true,
        lapse: 3500,
        nav: undefined,
        navOn: 'navOn',
        navOffset: 0,
        next: undefined,
        prev: undefined,
        pause: undefined,
        display: undefined,
        displayText: ' of ',
        state: 'playing',
        start: 1
    };
})(jQuery);
