(function($) {
    $.fn.extend({
       
        /*
         * scrollList: 
         * Scrolls an ordered or unordered list in a given direction.
         *
         * Example calls:
         * // Scroll list up @ 20 pixels/second with a 1s delay (default)
         * $j('#scroll_list').scrollList();
         * 
         *
         * // Scroll list down @ 20 pixels/second with 500ms delay
         * $j('#scroll_list').scrollList('down', 20, 500); 
         *
         * Example html:
         * <div id="scroll_list_container">
         *     <ul>
         *         <li>Item 1</li>
         *         <li>Item 2</li>
         *         <li>Item 3</li>
         *     </ul>
         * </div>
         *         
         * Example css:
         * - up/down
         * ul { margin:0; padding:0; }
         * #scroll_list_container { max-height:30px; overflow:hidden; }
         *
         */
         
        scrollList : function(direction, pixels_per_second, delay) {
  						
	            if ('undefined' == typeof(pixels_per_second)) {
	                pixels_per_second = 20;
	            }
	            
	            if ('undefined' == typeof(delay)) {
	                delay = 1000;
	            }
	            
	            if ('undefined' == typeof(direction) || -1 == $.inArray(direction, ['up', 'down'])) {
	                direction = 'up';
	            }
							
							var isScrolling = false;
	            var $list = $(this);
	            var $lis = $list.children('li');
	            var $current_li;
	            var pixels_per_millisecond = pixels_per_second / 1000;
	            var easing = (delay == 0) ? 'linear' : 'swing';
	
	            // Set position relative if position is currently static so top/left properties will affect it's position            
	            if ('static' == $list.css('position')) {
	                $list.css('position', 'relative');
	            }
	            
	            
	            if ('up' == direction) {
	                $current_li = $lis.filter(':first');
	            } else {
	
	                /* 
	                 * If down, move the last li to the beginning and move the entire
	                 * list up to allow the next li to scroll into view rather than just appear.
	                 */
//	                var $last_li = $lis.filter(':last');
//	                
//	                $list.css('top', '-' + $last_li.outerHeight() + 'px');
//	                
//	                $last_li.remove();
//	                $lis.filter(':first').before($last_li);
//	                $lis = $list.children('li');
	                $current_li = $lis.filter(':last');
	            }
	
	            
	            function scrollListNext() {
		            if(!stopScrolling && !isScrolling){        		
  									isScrolling = true;
  								            		
		                var distance, property;
		                var css = {};
		
		                property = 'top';             
		                distance = $current_li.outerHeight();               
		
		                switch (direction) {
		                    case 'up':   
		                        css.top = '-' + distance + 'px';
		                        break;
		                        
		                    case 'down':                
		                        css.top = 0;
		                        break;
		                        
		                };
		                
		                var duration = distance / pixels_per_millisecond;
		                $list.animate(css, duration, easing, function() {
		                    $current_li.remove();
		                    if ('up' == direction) {
		                        $list.css(property, 0);
		                        $lis.filter(':last').after($current_li);
		                        $lis = $list.children('li');
		                        $current_li = $lis.filter(':first');
		                    }
		                    else {
		                        $list.css(property, '-' + distance + 'px');
		                        $lis.filter(':first').before($current_li);
		                        $lis = $list.children('li');
		                        $current_li = $lis.filter(':last');
		                    }
		                    isScrolling = false;
												setTimeout(scrollListNext, delay);
		                });
		          	}
	            };
	            
	            setTimeout(scrollListNext, delay);
					}
    });
})(jQuery);
