if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

(function($) {
    var functions = {
        gotoIndex: function(index) {
            var self = $(this);
            
		    var nextButton = self.data('crazyScrollerNextButton');
		    var previousButton = self.data('crazyScrollerPreviousButton');		   
            
            var scrollableUl = self.data('crazyScrollerScrollableUl');
            var scrollAmount = self.data('crazyScrollerScrollAmount');
            
			var icon = self.data('crazyScrollerIcon');
			var currentIconUrl = self.data('crazyScrollerCurrentIconUrl');
            
            
            // Clamp the index
            var numberOfItems = scrollableUl.find('li').size();
            if (index <= 0) { 
                index = 0;
                previousButton.hide();
            } else {
                previousButton.show();
            }
            if (index >= numberOfItems - 1) {
                index = numberOfItems - 1;
                nextButton.hide();
            } else {
                nextButton.show();                
            }

			if(functions.changeForeground.call(self, index, icon) == false){
				if (icon.size() > 0) {
					functions.changeIcon.call(self, index);
				}
				
				// The position to scroll to and then scroll to it
	            var scrollX = index * scrollAmount;
	            scrollableUl.animate({ 'left': -scrollX });
			}			
			           
           	// Store the scrolled to index
            self.data('crazyScrollerCurrentIndex', index);
        },

		changeIcon: function(index){
			var self = $(this);
			var scrollableUl = self.data('crazyScrollerScrollableUl');
			var icon = self.data('crazyScrollerIcon');
            var currentIconUrl = self.data('crazyScrollerCurrentIconUrl');

            // Find the item and grab the icon url
			var item = scrollableUl.find('li:eq(' + index + ')');
            var iconUrl = item.attr('data-icon');
	
			if (currentIconUrl != iconUrl) {
	            var img = $('<img></img>').attr('src', iconUrl)
                   self.data('crazyScrollerCurrentIconUrl', iconUrl);

                   icon.find('img').fadeOut('fast', function() {
                       $(this).remove();
                   });
                   img.appendTo(icon)
                   img.hide();
                   img.fadeIn('fast');
               }
		},
		
		changeForeground: function(index, icon){
			var self = $(this);
			var parentDiv = $('.carousel');
			var foregroundChanged = false;		
			var scrollableUl = self.data('crazyScrollerScrollableUl');
            var item = scrollableUl.find('li:eq(' + index + ')');

			// Switch the foreground class				
			var foregroundClass = item.attr('data-foreground');
			var foregroundClasses = self.data('crazyScrollerForegroundClasses');

			if(foregroundClass && !parentDiv.hasClass(foregroundClass)){
				parentDiv.fadeOut('fast', function() {
					$.each(foregroundClasses, function(i, currentClass) {
						if (parentDiv.hasClass(currentClass)){
							parentDiv.removeClass(currentClass);
						}							
					});
					
					if (icon.size() > 0) {
						functions.changeIcon.call(self, index);
					}
					
					parentDiv.toggleClass(foregroundClass);
					parentDiv.fadeIn('fast');

					// Adjust scroll width
					scrollAmount = item.outerWidth(true);
					self.data('crazyScrollerScrollAmount', scrollAmount);

					// The position to scroll to and then scroll to it
		            scrollableUl.css({ 'left': -index * scrollAmount });
				});
				return true;	
			}
			return false;
		},
        
        gotoPrevious: function() {
            var self = $(this);
            
            // Scroll to previous index
            var index = self.data('crazyScrollerCurrentIndex');
            functions.checkForNewHref.call(self, index - 1);
            functions.gotoIndex.call(self, index - 1);
        },
        
        gotoNext: function() {
            var self = $(this);
            
            // Scroll to next index
            var index = self.data('crazyScrollerCurrentIndex');
            functions.checkForNewHref.call(self, index + 1);
            functions.gotoIndex.call(self, index + 1);
        },
        
        checkForNewHref: function(index){
            var self = $(this);
            var slides = self.data('crazyScrollerItems');
            var options = self.data('crazyScrollerOptions');
            var linkButton = self.data('crazyScrollerLink')
            var currentSlide = slides.eq(index);
            var tagData = currentSlide.attr(options.slideDataTag);
            
            if (tagData) 
            	linkButton.attr('href', tagData);
        }
    };
    
    $.fn.crazyscroller = function(options) {
		options = $.extend({}, $.fn.crazyscroller.defaults, options);
		
		this.each(function() {
		    var self = $(this);
		    
		    // If loaded already, then ignore
		    if (self.data('crazyscrollerLoaded')) {
		        return;
		    }
		    
		    // Let plugin know it's already been called before
		    self.data('crazyscrollerLoaded', true);
		    
		    // Grab the buttons and the scrollable area
		    var nextButton = self.find('.next');
		    var previousButton = self.find('.prev');
		    var linkButton = self.find(options.slideshowLinkButton);
		    var scrollableUl = self.find('.scroll');
			var items = scrollableUl.find('li');
		    var icon = self.find('.icon');
		    
		    // Grab scroll amount from li width
		    var scrollAmount = scrollableUl.find('li').outerWidth(true);
		    
		    // Store them into data so we can grab them later
		    self.data('crazyScrollerNextButton', nextButton);
		    self.data('crazyScrollerPreviousButton', previousButton);
		    self.data('crazyScrollerLink', linkButton);
		    self.data('crazyScrollerItems', items);
		    self.data('crazyScrollerIcon', icon);		    
		    self.data('crazyScrollerScrollableUl', scrollableUl);
		    self.data('crazyScrollerScrollAmount', scrollAmount);
		    self.data('crazyScrollerOptions', options);
		    
		    // Activate buttons
		    nextButton.click(function() {
		        functions.gotoNext.call(self);
		        return false;
		    });
		    previousButton.click(function() {
		        functions.gotoPrevious.call(self);
		        return false;
		    });
		
			// Find possible foreground classes
			var foregroundClasses = [];
			items.each(function(){
				var item = $(this);
				var foregroundClass = item.attr('data-foreground');
				if (foregroundClass !== undefined && foregroundClasses.indexOf(foregroundClass) == -1) {
					foregroundClasses.push(foregroundClass);
				}
			});
			self.data('crazyScrollerForegroundClasses', foregroundClasses);
			
		    // Start at zero
		    functions.gotoIndex.call(self, 0);
		});
		
		return this;
    };
    
	$.fn.crazyscroller.defaults = {
		slideshowLinkButton:'.nav .callout',		// The link in the slideshow to external URLs
		slideDataTag:'data-href'					// The tag containing a reference to the external URL
	};
})(jQuery);
