(function($){
    // plugin initialization
    $.fn.slider = function(o){
        var slider = this;
        
        // Initialize options for this call
        slider.options = $.extend({
            size : 4,
            onClick : null,
            nextElement : null,
            prevElement : null,
            useEvents : false,
            tabId: 0
        },o);

        // Steup Container
        slider.addClass("tp_slider");
        
        // Create Scroller
        var scroller = slider.find(".scrollableItems");
        var sp = scroller.position().left;
        var item = $(scroller.children().get(0));
        var itemWidth = item.width();
        var pageWidth = slider.find(".scrollcontainer").width();
        var numPages = Math.ceil(scroller.children().length/slider.options.size);
        var mp = (pageWidth*(numPages-1)) * -1;
        var currentPage = 1;

        // Control Elements
        if (slider.options.useEvents == false) {
            if (slider.options.nextElement == null) {
                slider.options.nextElement = slider.find("a.next");
            }
            slider.options.nextElement = $(slider.options.nextElement);
            if (slider.options.prevElement == null) {
                slider.options.prevElement = slider.find("a.prev");
            }
            slider.options.prevElement = $(slider.options.prevElement);
        }
        else {
            // get state set by $.setState
            var state = $(document).data(slider.options.tabId +'_state') || 'default';
            var tabEvents = $('a.'+ slider.options.tabId +'_'+state);

            slider.options.nextElement = tabEvents.filter('.event_sliderNext');
            slider.options.prevElement = tabEvents.filter('.event_sliderPrev');
        }
        // Update Arrows
        var updateArrows = function() {
            if (numPages == 1) {
                slider.options.nextElement.hide();
                slider.options.prevElement.hide();
            } else if (currentPage == numPages) {
                slider.options.nextElement.hide();
                slider.options.prevElement.show();
            } else if (currentPage == 1) {
                slider.options.nextElement.show();
                slider.options.prevElement.hide();
            } else {
                slider.options.nextElement.show();
                slider.options.prevElement.show();
            }
        };
        
        // Animation
        var slide = function(curPos,scrollTo,callback) {
            var scrollPoint = 0;
            var scrollModifier = 25;
            var animationInterval = null;
            
            var direction = "left";
            if (curPos < scrollTo) {
                direction = "right";
            }
            
            var animate = function() {
                scroller.attr("isAnimating","true");
                
                if (direction == "left") {
                    scrollPoint = curPos - scrollModifier;
                    if (scrollPoint < scrollTo) {
                        scrollPoint = scrollTo;
                    }
                } else if (direction == "right") {
                    scrollPoint = curPos + scrollModifier;
                    if (scrollPoint > scrollTo) {
                        scrollPoint = scrollTo;
                    }
                } else {
                     scrollPoint = scrollTo;
                }
                
                // Animate
                curPos = scrollPoint;
                scroller.css("left",scrollPoint+"px");
            
                if (scrollPoint == scrollTo) {
                    scroller.attr("isAnimating","");
                    clearInterval(animationInterval);
                    if (callback) {
                        callback();
                    }
                }
            };
        
            if (!scroller.attr("isAnimating")) {
                animationInterval = setInterval(animate, 15);
            }
        }
        
        slider.bindControls = function() {
            // Next Event
            var nextEvent = function() {
                if (!scroller.attr("isAnimating")) {
                    var op = (sp - scroller.position().left) * -1;
                    var np = op - pageWidth;
                    if (np < mp) {
                        np = mp;
                    }
            
                    slide(op,np,function(){
                        currentPage++;
                        if (currentPage > numPages) {
                            currentPage = numPages;
                        }
                        updateArrows();
                    });
                    
                    $.galog.engagement("app", "Slider Next");
                }
            };

            if (slider.options.useEvents) {
                $.bindEvent('sliderNext',nextEvent);
            } else {
                slider.options.nextElement.bind("click",nextEvent);
            }
        
        
            // Prev Event
            var prevEvent = function() {
                if (!scroller.attr("isAnimating")) {
                    var op = (sp - scroller.position().left) * - 1;
                    var np = op + pageWidth;
                    if (np > 0) {
                        np = 0;
                    }
            
                    slide(op,np,function(){
                        currentPage--;
                        if (currentPage < 1) {
                            currentPage = 1;
                        }
                        updateArrows();
                    });
                    
                    $.galog.engagement("app", "Slider Previous");
                }
            };
        
            if (slider.options.useEvents) {
                $.bindEvent('sliderPrev',prevEvent);
            } else {
                slider.options.prevElement.bind("click",prevEvent);
            }
        
            updateArrows();
        };
        
        
        // Bind events for each item
        slider.bindControls();
        if (slider.options.onClick) {
            slider.find(".scrollableItems").children()
                .bind("click", slider.options.onClick).css('cursor', 'pointer');
        }
        return slider;
    };
})(jQuery);