(function( $ ){
    $.fn.panelslider = function (options) {
        var settings = {
            'selectedIndex' : 1,
            'visiblePanels' : 4,        // Amount of visible/focal panels
            'panelSpacing' : 4,         // Spacing between each panel  
            'panelWidth' : 210,         // Width of each panel
            'animationSpeed' : 500,     // Speed of the transition animation in milliseconds
            'bodyWidth' : 1000           // Needed to define the initial starting point of the panels
        };
       
       $.extend(settings, options);
       
        return this.each(function () {
            //Global Variables
            var $this = $(this),
                totalPanels = $this.find(".panelItems li.panel").css("margin-right", settings.panelSpacing).css("width", settings.panelWidth).length,
                maxIncrement = Math.round(totalPanels / settings.visiblePanels) - 1,
                increment = 0,
                isAnimating = false,
                prevIncrement = 0;
        
            // Item Spacer used to emulate the first position of the slider
            var spacerHTML = '<li class="itemSpacer" style="height: 1px;float: left;"></li>';
            $this.find(".panelItems").prepend(spacerHTML);
            
            // Directional Navigation
            var navHTML = '<div class="sliderNav"><span class="left"></span><span class="right"></span></div>';
            if(totalPanels > settings.visiblePanels) {
                 $this.parent().append(navHTML);
            }

            
            var $prevBtn = $this.parent().find("span.left"),
                $nextBtn = $this.parent().find("span.right");
            
            setSpacerWidth();
            
            // Set the inital selected index
            scrollTo(settings.selectedIndex);

            // Event Handlers
            $prevBtn.click(function(e) {
                e.preventDefault();
                prev(e);
            });

            $nextBtn.click(function(e) {
                e.preventDefault();
                next(e);
            });
            
            $(window).resize(function() {
                setSpacerWidth();
            });
            
            // Previous navigational functionality
            function prev(e) {
                if (!isAnimating) {
                    if (increment > 0) {
                        prevIncrement = increment;
                        increment--;
                        scrollTo(increment);
                    }
                }    
            }
            
            // Next navigational functionality
            function next(e) {
                if (!isAnimating) {
                    if (increment < maxIncrement) {
                        prevIncrement = increment;
                        increment++
                        scrollTo(increment);
                    }
                }
            }
            
            // Updates the width of the panel item spacer which is used to simulate the beginning of the slider
            function setSpacerWidth() {
                var offset =  settings.bodyWidth/2;
                var trueWidth = ($(window).width() / 2) - offset;
                
                $this.find(".itemSpacer").css("width", (trueWidth + "px"));
            }
            
            // Generic scroll functionality
            function scroll(position, speed) {
                isAnimating = true;
                $this.animate({
                    'scrollLeft': position
                }, speed, 'linear', function() {
                    isAnimating = false
                });
            }
            
            function scrollTo(index) {
                if(index >= 0 && index <= maxIncrement) {
                    if(index != increment) {
                        prevIncrement = increment;
                        increment = index;
                    }
                    
                    var sliderWidth = ((settings.panelWidth + settings.panelSpacing) * settings.visiblePanels) - settings.panelSpacing;
                        nextPos = sliderWidth * index;
                        speed = settings.animationSpeed;
                        nextSet = 0;
                    
                    if(index >= 0 && index < maxIncrement) {
                        
                        if(index > 0) {
                            if($nextBtn.hasClass("disabled")) {
                                $nextBtn.removeClass("disabled");
                            }
                            
                             if($prevBtn.hasClass("disabled")) {
                                $prevBtn.removeClass("disabled");
                            }
                        }else {
                            if (!$prevBtn.hasClass("disabled")) {
                                $prevBtn.addClass("disabled");
                            }
                        }
                        
                        if(prevIncrement == maxIncrement && index == maxIncrement - 1 && totalPanels % settings.visiblePanels != 0) {
                            nextSet = totalPanels - (maxIncrement * settings.visiblePanels);
                            
                            // Adjust the speed of the animation due to the amount of panels that actually need to be tweened
                            speedAdjustment = settings.animationSpeed - Math.round(settings.animationSpeed * (nextSet/settings.visiblePanels));
                            speed -= speedAdjustment;    
                        }
                    }else if(index == maxIncrement) {
                        
                        if(totalPanels % settings.visiblePanels != 0) {
                            nextSet = totalPanels - (maxIncrement * settings.visiblePanels);
                            nextPos = (sliderWidth * (maxIncrement - 1))+ ((settings.panelWidth + settings.panelSpacing) * nextSet);
                            
                            // Adjust the speed of the animation due to the amount of panels that actually need to be tweened
                            speedAdjustment = settings.animationSpeed - Math.round(settings.animationSpeed * (nextSet/settings.visiblePanels));
                            speed -= speedAdjustment;
                        }
                        
                        if(!$nextBtn.hasClass("disabled")) {
                            $nextBtn.addClass("disabled");
                        }
                    }
                    
                    scroll(nextPos, speed);  
                }
            }
        });
    }
})( jQuery );
