/*
 * jQuery Orbit Plugin 1.2.3
 * www.ZURB.com/playground
 * Copyright 2010, ZURB
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */
(function ($) {

    $.fn.orbit = function (options) {

        //Defaults to extend options
        var defaults = {
            animation: 'horizontal-slide',
            // fade, horizontal-slide, vertical-slide, horizontal-push
            animationSpeed: 600,
            // how fast animtions are
            timer: false,
            // true or false to have the timer
            advanceSpeed: 4000,
            // if timer is enabled, time between transitions 
            pauseOnHover: false,
            // if you hover pauses the slider
            startClockOnMouseOut: false,
            // if clock should start on MouseOut
            startClockOnMouseOutAfter: 1000,
            // how long after MouseOut should the timer start again
            directionalNav: true,
            // manual advancing directional navs
            captions: true,
            // do you want captions?
            captionAnimation: 'slideOpen',
            // fade, slideOpen, none
            captionAnimationSpeed: 600,
            // if so how quickly should they animate in
            bullets: true,
            // true or false to activate the bullet navigation
            bulletThumbs: false,
            // thumbnails for the bullets
            bulletThumbLocation: '',
            // location from this file where thumbs will be
            afterSlideChange: function () {} // empty function 
        };

        //Extend those options
        options = $.extend(defaults, options);

        return this.each(function () {

            // ==============
            // ! SETUP   
            // ==============
            //Global Variables
            var activeSlide = 0,
                numberSlides = 0,
                orbitWidth, orbitHeight, locked;

            //Initialize
            var orbit = $(this).addClass('orbit'),
                orbitWrapper = orbit.wrap('<div class="orbit-wrapper" />').parent();
            orbit.add(orbitWidth).width('1px').height('1px');

            //Collect all slides and set slider size of largest image
            var slides = orbit.children('img, a, div');
            slides.each(function () {
                var _slide = $(this),
                    _slideWidth = _slide.width(),
                    _slideHeight = _slide.height();
                if (_slideWidth > orbit.width()) {
                    orbit.add(orbitWrapper).width(_slideWidth);
                    orbitWidth = orbit.width();
                }
                if (_slideHeight > orbit.height()) {
                    orbit.add(orbitWrapper).height(_slideHeight);
                    orbitHeight = orbit.height();
                }
                numberSlides++;
            });

            //Animation locking functions


            function unlock() {
                locked = false;
            }

            function lock() {
                locked = true;
            }

            //If there is only a single slide remove nav, timer and bullets
            if (slides.length === 1) {
                options.directionalNav = false;
                options.timer = false;
                options.bullets = false;
            }

            //Set initial front photo z-index and fades it in
            slides.eq(activeSlide).css({
                "z-index": 3
            }).fadeIn(function () {
                //brings in all other slides IF css declares a display: none
                slides.css({
                    "display": "block"
                });
            }).addClass('currentImg');

            // ==============
            // ! TIMER   
            // ==============
            //Timer Execution


            function startClock() {
                if (!options.timer || options.timer === 'false') {
                    return false;
                    //if timer is hidden, don't need to do crazy calculations
                } else if (timer.is(':hidden')) {
                    clock = setInterval(function (e) {
                        shift("next");
                    }, options.advanceSpeed);
                    //if timer is visible and working, let's do some math
                } else {
                    timerRunning = true;
                    pause.removeClass('active');
                    clock = setInterval(function (e) {
                        var degreeCSS = "rotate(" + degrees + "deg)";
                        degrees += 2;
                        rotator.css({
                            "-webkit-transform": degreeCSS,
                            "-moz-transform": degreeCSS,
                            "-o-transform": degreeCSS
                        });
                        if (degrees > 180) {
                            rotator.addClass('move');
                            mask.addClass('move');
                        }
                        if (degrees > 360) {
                            rotator.removeClass('move');
                            mask.removeClass('move');
                            degrees = 0;
                            shift("next");
                        }
                    }, options.advanceSpeed / 180);
                }
            }

            function stopClock() {
                if (!options.timer || options.timer === 'false') {
                    return false;
                } else {
                    timerRunning = false;
                    clearInterval(clock);
                    pause.addClass('active');
                }
            }

            //Timer Setup
            if (options.timer) {
                var timerHTML = '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>';
                orbitWrapper.append(timerHTML);
                var timer = orbitWrapper.children('div.timer'),
                    timerRunning;
                if (timer.length !== 0) {
                    var rotator = $('div.timer span.rotator'),
                        mask = $('div.timer span.mask'),
                        pause = $('div.timer span.pause'),
                        degrees = 0,
                        clock;
                    startClock();
                    timer.click(function () {
                        if (!timerRunning) {
                            startClock();
                        } else {
                            stopClock();
                        }
                    });
                    if (options.startClockOnMouseOut) {
                        var outTimer;
                        orbitWrapper.mouseleave(function () {
                            outTimer = setTimeout(function () {
                                if (!timerRunning) {
                                    startClock();
                                }
                            }, options.startClockOnMouseOutAfter);
                        });
                        orbitWrapper.mouseenter(function () {
                            clearTimeout(outTimer);
                        });
                    }
                }
            }

            //Pause Timer on hover
            if (options.pauseOnHover) {
                orbitWrapper.mouseenter(function () {
                    stopClock();
                });
            }

            // ==============
            // ! CAPTIONS   
            // ==============
            //Caption Setup
            if (options.captions) {
                var captionHTML = '<div class="orbit-caption currentCaption"></div>';
                orbitWrapper.append(captionHTML);
                var caption = orbitWrapper.children('.orbit-caption');
                setCaption();
            }

            //Caption Execution
            //Caption Execution


            function setCaption() {
                if (!options.captions || options.captions === "false") {
                    return false;
                } else {
                    var _captionLocation = slides.eq(activeSlide).data('caption'); //get ID from rel tag on image
                    if (_captionLocation) {
                        _captionHTML = $(_captionLocation).html(); //get HTML from the matching HTML entity  
                        //Set HTML for the caption if it exists
                        if (_captionHTML) {
                            caption.attr('id', _captionLocation) // Add ID caption
                            .html(_captionHTML); // Change HTML in Caption 
                            //Animations for Caption entrances
                            if (options.captionAnimation === 'none') {
                                caption.show();
                            }
                            if (options.captionAnimation === 'fade') {
                                caption.fadeIn(options.captionAnimationSpeed);
                            }
                            if (options.captionAnimation === 'slideOpen') {
                                caption.slideDown(options.captionAnimationSpeed);
                            }
                        } else {
                            //Animations for Caption exits
                            if (options.captionAnimation === 'none') {
                                caption.hide();
                            }
                            if (options.captionAnimation === 'fade') {
                                caption.fadeOut(options.captionAnimationSpeed);
                            }
                            if (options.captionAnimation === 'slideOpen') {
                                caption.slideUp(options.captionAnimationSpeed);
                            }
                        }
                    }
                }
            }
            // ==================
            // ! DIRECTIONAL NAV   
            // ==================
            //DirectionalNav { rightButton --> shift("next"), leftButton --> shift("prev");
            if (options.directionalNav) {
                if (options.directionalNav === "false") {
                    return false;
                }
                var directionalNavHTML = '<div class="slider-nav"><span class="right">Right</span><span class="left">Left</span></div>';
                orbitWrapper.append(directionalNavHTML);
                var leftBtn = orbitWrapper.children('div.slider-nav').children('span.left'),
                    rightBtn = orbitWrapper.children('div.slider-nav').children('span.right');
                leftBtn.click(function () {
                    stopClock();
                    shift("prev");
                });
                rightBtn.click(function () {
                    stopClock();
                    shift("next");
                });
            }

            // ==================
            // ! BULLET NAV   
            // ==================
            //Bullet Nav Setup
            if (options.bullets) {
                var bulletHTML = '<ul class="orbit-bullets"></ul>';
                orbitWrapper.append(bulletHTML);
                var bullets = orbitWrapper.children('ul.orbit-bullets');
                for (i = 0; i < numberSlides; i++) {
                    var liMarkup = $('<li>' + (i + 1) + '</li>');
                    if (options.bulletThumbs) {
                        var thumbName = slides.eq(i).data('thumb');
                        if (thumbName) {
                            liMarkup = $('<li class="has-thumb">' + i + '</li>');
                            liMarkup.css({
                                "background": "url(" + options.bulletThumbLocation + thumbName + ") no-repeat"
                            });
                        }
                    }
                    orbitWrapper.children('ul.orbit-bullets').append(liMarkup);
                    liMarkup.data('index', i);
                    liMarkup.click(function () {
                        stopClock();
                        shift($(this).data('index'));
                    });
                }
                setActiveBullet();
            }

            //Bullet Nav Execution


            function setActiveBullet() {
                if (!options.bullets) {
                    return false;
                } else {
                    bullets.children('li').removeClass('active').eq(activeSlide).addClass('active');
                }
            }

            // ====================
            // ! SHIFT ANIMATIONS   
            // ====================
            //Animating the shift!


            function shift(direction) {
                //remember previous activeSlide
                var prevActiveSlide = activeSlide,
                    slideDirection = direction;
                //exit function if bullet clicked is same as the current image
                if (prevActiveSlide === slideDirection) {
                    return false;
                }
                //reset Z & Unlock


                function resetAndUnlock() {
                    slides.eq(prevActiveSlide).css({
                        "z-index": 1
                    }).removeClass('currentImg');
                    unlock();
                    options.afterSlideChange.call(this, slides.eq(prevActiveSlide), slides.eq(activeSlide));
                }
                if (slides.length === "1") {
                    return false;
                }
                if (!locked) {
                    lock();
                    //deduce the proper activeImage
                    if (direction === "next") {
                        activeSlide++;
                        if (activeSlide === numberSlides) {
                            activeSlide = 0;
                        }
                    } else if (direction === "prev") {
                        activeSlide--;
                        if (activeSlide < 0) {
                            activeSlide = numberSlides - 1;
                        }
                    } else {
                        activeSlide = direction;
                        if (prevActiveSlide < activeSlide) {
                            slideDirection = "next";
                        } else if (prevActiveSlide > activeSlide) {
                            slideDirection = "prev";
                        }
                    }
                    //set to correct bullet
                    setActiveBullet();

                    //set previous slide z-index to one below what new activeSlide will be
                    slides.eq(prevActiveSlide).css({
                        "z-index": 2
                    }).removeClass('currentImg');

                    //fade
                    if (options.animation === "fade") {
                        slides.eq(activeSlide).css({
                            "opacity": 0,
                            "z-index": 3
                        }).animate({
                            "opacity": 1
                        }, options.animationSpeed, resetAndUnlock).addClass('currentImg');
                    }
                    //horizontal-slide
                    if (options.animation === "horizontal-slide") {
                        if (slideDirection === "next") {
                            slides.eq(activeSlide).css({
                                "left": orbitWidth,
                                "z-index": 3
                            }).animate({
                                "left": 0
                            }, options.animationSpeed, resetAndUnlock).addClass('currentImg');
                        }
                        if (slideDirection === "prev") {
                            slides.eq(activeSlide).css({
                                "left": -orbitWidth,
                                "z-index": 3
                            }).animate({
                                "left": 0
                            }, options.animationSpeed, resetAndUnlock).addClass('currentImg');
                        }
                    }
                    //vertical-slide
                    if (options.animation === "vertical-slide") {
                        if (slideDirection === "prev") {
                            slides.eq(activeSlide).css({
                                "top": orbitHeight,
                                "z-index": 3
                            }).animate({
                                "top": 0
                            }, options.animationSpeed, resetAndUnlock).addClass('currentImg');
                        }
                        if (slideDirection === "next") {
                            slides.eq(activeSlide).css({
                                "top": -orbitHeight,
                                "z-index": 3
                            }).animate({
                                "top": 0
                            }, options.animationSpeed, resetAndUnlock).addClass('currentImg');
                        }
                    }
                    //push-over
                    if (options.animation === "horizontal-push") {
                        if (slideDirection === "next") {
                            slides.eq(activeSlide).css({
                                "left": orbitWidth,
                                "z-index": 3
                            }).animate({
                                "left": 0
                            }, options.animationSpeed, resetAndUnlock);
                            slides.eq(prevActiveSlide).animate({
                                "left": -orbitWidth
                            }, options.animationSpeed).addClass('currentImg');
                        }
                        if (slideDirection === "prev") {
                            slides.eq(activeSlide).css({
                                "left": -orbitWidth,
                                "z-index": 3
                            }).animate({
                                "left": 0
                            }, options.animationSpeed, resetAndUnlock);
                            slides.eq(prevActiveSlide).animate({
                                "left": orbitWidth
                            }, options.animationSpeed).addClass('currentImg');
                        }
                    }
                    setCaption();
                } //lock
            } //orbit function
        }); //each call
    } //orbit plugin call
})(jQuery);
