(function($) {
    $.fn.slideGallery = function(options) {
       var defaults = {  
            animation: 'fade', 
            animationSpeed: 800,
            advanceSpeed: 4000, 
            startClockOnMouseOut: true, 
            startClockOnMouseOutAfter: 3000,
            directionalNav: true, 
            captions: true,
            captionAnimationSpeed: 800,
            timer: false,
            bullets: false
            };  
        var options = $.extend(defaults, options); 
        return this.each(function() {
            var activeImage = 0;
            var numberImages = 0;
            var slideGalleryWidth;
            var slideGalleryHeight;
            var locked;
            var slideGallery = $(this).addClass('slideGallery')
            var images = slideGallery.find('img, a img');
            images.each(function() {
                var _img = $(this);
                var _imgWidth = _img.width();
                var _imgHeight = _img.height();
                slideGallery.width(_imgWidth);
                slideGalleryWidth = slideGallery.width()
                slideGallery.height(_imgHeight)
                slideGalleryHeight = slideGallery.height();
                numberImages++;
            });
            images.eq(activeImage).css({"z-index" : 3});
            if(options.timer) {         	
                var timerHTML = '<div class="timer"><span class="mask"><span class="rotator"></span></span><span class="pause"></span></div>'
                slideGallery.append(timerHTML);
                var timer = $('div.timer')
                var timerRunning;
                if(timer.length != 0) {
                    var speed = (options.advanceSpeed)/180;
                    var rotator = $('div.timer span.rotator')
                    var mask = $('div.timer span.mask')
                    var pause = $('div.timer span.pause')
                    var degrees = 0;
                    var clock;
                    function startClock() {
                        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")
                            }
                        }, speed);
                    };  
                    function stopClock() {
                        timerRunning = false;
                        clearInterval(clock)
                        pause.addClass('active')
                    }   
                    startClock();
                    timer.click(function() {
                        if(!timerRunning) {
                            startClock();
                        } else { 
                            stopClock();
                        }
                    })
                    if(options.startClockOnMouseOut){
                        var outTimer;
                        slideGallery.mouseleave(function() {
                            outTimer = setTimeout(function() {
                                if(!timerRunning){
                                    startClock();
                                }
                            }, options.startClockOnMouseOutAfter)
                        })
                        slideGallery.mouseenter(function() {
                            clearTimeout(outTimer);
                        })
                    }
                }
            }           
            function unlock() {
                locked = false;
            }
            function lock() { 
                locked = true;
            }
            
            if(options.captions) {
                var captionHTML = '<div class="caption"><span class="slideGallery-caption"></span></div>';
                slideGallery.append(captionHTML);
                var caption = slideGallery
                	.children('div.caption')
                	.children('span')
                	.addClass('slideGallery-caption')
                	.show();
                	
                function setCaption() {
                	var _captionLocation = images.eq(activeImage).attr('rel');
                    var _captionHTML = $("#"+_captionLocation).html(); 
                    var _captionHeight = caption.height() + 20; 
                             	
                	caption
                		.attr('id',"#"+_captionLocation) 
                    	.html(_captionHTML); 
                    if(!_captionHTML) {
                        caption.parent().stop().animate({"bottom" : -_captionHeight}, options.captionAnimationSpeed);
                    } else { 
                        caption.parent().stop().animate({"bottom" : 0}, options.captionAnimationSpeed);
                    }
                }
            	setCaption();
            }
            
			  if(options.directionalNav) {
                var directionalNavHTML = '<div class="slider-nav"><span class="right">Right</span><span class="left">Left</span></div>';
                slideGallery.append(directionalNavHTML);
                var leftBtn = slideGallery.children('div.slider-nav').children('span.left');
                var rightBtn = slideGallery.children('div.slider-nav').children('span.right');
                leftBtn.click(function() { 
                    if(options.timer) { stopClock(); }
                    shift("prev");
                });
                rightBtn.click(function() {
                    if(options.timer) { stopClock(); }
                    shift("next")
                });
            }
            if(options.bullets) { 
            	var bulletHTML = '<ul class="slideGallery-bullets"></ul>';            	
            	slideGallery.append(bulletHTML);
            	var bullets = $('ul.slideGallery-bullets');
            	for( i=0; i<numberImages; i++) {
            		var liMarkup = $('<li>'+i+'</li>') 
            		$('ul.slideGallery-bullets').append(liMarkup);
            		liMarkup.data('index',i);
            		liMarkup.click(function() {
            			if(options.timer) { stopClock(); }
            			shift($(this).data('index'));
            		});
            	}
            	function setActiveBullet() { 
            		bullets.children('li').removeClass('active').eq(activeImage).addClass('active')
            	}
            	setActiveBullet();
            }
            function shift(direction) {
                var prevActiveImage = activeImage;
                var slideDirection = direction;
                if(prevActiveImage == slideDirection) { return false; }
                function resetAndUnlock() {
                    images.eq(prevActiveImage).css({"z-index" : 1});
                    unlock();
                }
                if(!locked) {
                    lock();
	                 if(direction == "next") {
                        activeImage++
                        if(activeImage == numberImages) {
                            activeImage = 0;
                        }
                    } else if(direction == "prev") {
                        activeImage--
                        if(activeImage < 0) {
                            activeImage = numberImages-1;
                        }
                    } else {
                        activeImage = direction;
                        if (prevActiveImage < activeImage) { 
                            slideDirection = "next";
                        } else if (prevActiveImage > activeImage) { 
                            slideDirection = "prev"
                        }
                    }
                     if(options.bullets) { setActiveBullet(); }              
                    if(options.animation == "fade") {
                        images.eq(prevActiveImage).css({"z-index" : 2});
                        images.eq(activeImage).css({"opacity" : 0, "z-index" : 3})
                        .animate({"opacity" : 1}, options.animationSpeed, resetAndUnlock);
                        if(options.captions) { setCaption(); }
                    }
                    if(options.animation == "horizontal-slide") {
                        images.eq(prevActiveImage).css({"z-index" : 2});
                        if(slideDirection == "next") {
                            images.eq(activeImage).css({"left": slideGalleryWidth, "z-index" : 3})
                            .animate({"left" : 0}, options.animationSpeed, resetAndUnlock);
                        }
                        if(slideDirection == "prev") {
                            images.eq(activeImage).css({"left": -slideGalleryWidth, "z-index" : 3})
                            .animate({"left" : 0}, options.animationSpeed, resetAndUnlock);
                        }
                        if(options.captions) { setCaption(); }
                    }
                    if(options.animation == "vertical-slide") { 
                        images.eq(prevActiveImage).css({"z-index" : 2});
                        if(slideDirection == "prev") {
                            images.eq(activeImage).css({"top": slideGalleryHeight, "z-index" : 3})
                            .animate({"top" : 0}, options.animationSpeed, resetAndUnlock);
                        }
                        if(slideDirection == "next") {
                            images.eq(activeImage).css({"top": -slideGalleryHeight, "z-index" : 3})
                            .animate({"top" : 0}, options.animationSpeed, resetAndUnlock);
                        }
                        if(options.captions) { setCaption(); }
                    }
                }
            }
        });
    }
})(jQuery);
        
