(function($){
    var options;
    
    $.fn.fdSlideshow = function(callerOptions) {
        var container = this;
        options = $.extend({
            pauseOnHover: false,
            speed: 1000,
            delay: 3000,
            isDebugOn: false,
            timer: '',
            index: 999999,
            counter: 1,
            queue: [],
            slideWidth: 0,
            slideCount: 0,
            containerSelector: '',
            container: container,
            slideContainerSelector: 'ul.slideshowImages',
            slideContainer: [],
            controlContainerSelector: 'ul.slideshowControls',
            controlContainer: [],
            slides: [],
            controls: [],
            isStarted: true,
            currentHover: 99999
        }, callerOptions || {});
        
        // Container
        options.containerSelector = $(options.container).attr('id');
        
        // Slides
        options.slideContainer = $(options.container).find(options.slideContainerSelector);
        options.slideWidth = $(options.slideContainer).find('li:first img').width();
        options.slides = $(options.slideContainer).find('li').css({ position: 'absolute', top: '0', left: '0' }).detach();
        options.slideCount = options.slides.length;
        
        // Controls
        options.controlContainer = $(options.container).find(options.controlContainerSelector);
        options.controls = $(options.controlContainer).find('li');
        
        $(options.controls).each(function(i) {
            $(this).data('index', i).click(function() {
                if (options.isDebugOn) {
                    console.log('Control click event fired, calling showSlide(' + i + ')');
                }
                showSlide(i);
                
                return false;
            }).hover(
                function() {
                    if (options.isDebugOn) {
                        console.log('Control hover in event');
                    }
                    options.currentHover = $(this).data('index');
                    if ($(this).data('index') == options.index) {
                        clearTimeout(options.timer);
                        options.isStarted = false;
                    }
                },
                function() {
                    if (options.isDebugOn) {
                        console.log('Control hover out event');
                    }
                    
                    options.currentHover = 99999;
                    
                    if ($(this).data('index') == options.index) {
                        clearTimeout(options.timer);
                        
                        var nextSlideIndex = options.index+1;
                        if (nextSlideIndex == options.slideCount) {
                            nextSlideIndex = 0;
                        }
                        
                        options.timer = setTimeout(function() {
                            showSlide(nextSlideIndex);
                        }, options.delay);
                        options.isStarted = true;
                    }
                }
            );
        });
        
        showSlide(0);
        return this;
    };
    
    var showSlide = function(index) {
        clearTimeout(options.timer);
        options.isStarted = false;
        
        if (options.isDebugOn) {
            console.log('------------------------------------\nshowSlide(' + index + ') called');
        }
        if (index != options.index) {
            if (options.isDebugOn) {
                console.log('index(' + index + ') does not equal options.index(' + options.index + '), processing slide...');
            }
            
            options.index = index;
            
            var nextIndex = options.index+1;
            if (nextIndex >= options.slideCount) {
                nextIndex = 0;
            }
            if (options.isDebugOn) {
                console.log('Next index is ' + nextIndex);
            }
            
            var slide = $(options.slides[index]).clone(true);
            if (options.isDebugOn) {
                console.log(slide);
            }
            
            
            $(slide).css({
                'position': 'absolute',
                'top': '0',
                'left': '0',
                'z-index': 1000-options.counter
            });
            
            options.counter++;
            
            var slideAnchor = $(slide).find('a');
            if (options.isDebugOn) {
                console.log(slideAnchor);
            }
            
            if (options.pauseOnHover) {
                $(slideAnchor).hover(
                    function() {
                        if (options.isDebugOn) {
                            console.log('Slide hover in event');
                        }
                        clearTimeout(options.timer);
                        options.isStarted = false;
                    },
                    function() {
                        if (options.isDebugOn) {
                            console.log('Slide hover out event');
                        }
                        clearTimeout(options.timer);
                        
                        var showNextSlideIndex = options.index+1;
                        if (showNextSlideIndex == options.slideCount) {
                            showNextSlideIndex = 0;
                        }
                        
                        options.timer = setTimeout(function() {
                            showSlide(showNextSlideIndex);    
                        }, options.delay);
                        
                        options.isStarted = true;
                    }
                );
            }
            
            if (options.queue.length > 0) {
                $(options.queue.shift()).animate({ left: options.slideWidth }, options.speed, function() {
                        $(this).remove();
                });
            }
            
            $(options.slideContainer).prepend(slide);
            options.queue.push(slide);
            
            $(options.controls).each(function(i) {
                $(this).find('a').removeClass('controlActive');
            });
            $(options.controls[index]).find('a').addClass('controlActive');
            
            if (options.isDebugOn) {
                console.log('options.currentHover\: ' + options.currentHover);
                console.log('options.index\: ' + options.index);
            }
            
            if (options.currentHover != options.index) {
                clearTimeout(options.timer);
                
                var showNextIndex = options.index+1;
                if (showNextIndex == options.slideCount) {
                    showNextIndex = 0;
                }
                
                options.timer = setTimeout(function() {
                    showSlide(showNextIndex);    
                }, options.delay);
            }
        }
    };
})(jQuery);

