$.fn.listrotator = function(options) {
	var options = options;

	var betweenEachDelay = options.betweenEachDelay || 0;
	var Delay = betweenEachDelay;
	$(this).each(function() {
		
		if (typeof this.listrotator == 'object') return this.listrotator;
		var $ul = $(this);
		var $prev = $(this).parent().find(options.prevAgent+':first');
		var $next = $(this).parent().find(options.nextAgent+':first');
		var $pos = $(this).parent().find(options.posAgent+':first');
		var displayItems = options.displayItems
		
		// init state
		var c = 0;
		
		
		var t = obj = {
			inSwap:false,
			Delay:Delay,
			options:options,
			animDuration:800,
			paused:false,
			$ul:$ul,
			count:$ul.find("li").length,
			currentStartIndex:0,
			displayStatus:function() {
				$pos.html((Math.round(t.currentStartIndex)+1) + " / " + Math.ceil(t.count));
			},
			swap:function($c,$n,anim,afterSwap) {
				var $c=$c;
				var $n=$n;
				var afterSwap = afterSwap;
				var anim = (anim) ?  t.animDuration : 0;

				if (t.inSwap) {
					return false;
					/*setTimeout(function() {
						t.swap($c,$n,anim,afterSwap)
					},100);*/
				}
				t.inSwap = true;
				
				
				$c.slideUp(Math.round(anim/2),function() {
					$(this).hide();
					if (typeof afterSwap == 'function') afterSwap();
					
				});
				$n.slideDown(anim,function(){
						$(this).show();
						t.inSwap = false;
				});
				
				t.displayStatus();
			},
			reset:function(anim) {
				t.currentStartIndex=0;
				var $n = $ul.find("li:lt("+(displayItems)+")");
				var $c = $ul.find("li:gt("+(displayItems-1)+")");
				t.swap($c,$n,anim);
			},
			showNext:function(){
				if (t.inSwap) return false;
				if (t.currentStartIndex > (t.count-displayItems+1)) return false;
				
				t.currentStartIndex += 1;
				t.show(true);

			},
			showPrev:function() {
				if (t.inSwap) return false;
				if (t.currentStartIndex <= 0) return false;
				t.currentStartIndex -= 1;					
				t.show(false);					
			},
			
			rotateNext:function() {
				if (t.inSwap) return false;
				t.currentStartIndex += 1;				
				if (t.currentStartIndex >= t.count) t.currentStartIndex = 0;
				t.show(true);			
			},
			
			rotatePrev:function() {
				t.currentStartIndex -= 1;					
				if (t.currentStartIndex < 0) t.currentStartIndex = t.count-1;
				t.show(false);
			},
			show:function(asc) {
				var asc = asc;
				

				if (asc) {
					var $current = t.$ul.children("li:visible:first");
					var $next = t.$ul.children("li:hidden:first");
					$next.insertAfter(t.$ul.children("li:visible:last"));
					if ($next.length > 0 ) {
						t.swap($current,$next,true,function() {
							t.$ul.append($current);
						});
					} else {
						t.reset(true);							
					}
				} else {
					var $current = t.$ul.children("li:visible:last");
					var $next = t.$ul.children("li:hidden:last");
					$next.insertBefore(t.$ul.children("li:visible:first"));
					if ($next.length > 0 ) {
						t.swap($current,$next,true,function() {
							t.$ul.prepend($current);
						});
					} else {
						t.reset(true);							
					}
				}
				
				
			},
			rotatePause:function() {
				t.paused = true;
			},
			rotateContinue:function() {
				if (t.options.autoRotate) {
					t.paused = false;
					//setTimeout(t.autoRotate,t.options.autoRotate);
				}
			},
			autoRotate:function(){
				if (!t.paused) {
					t.rotateNext();
				}
				setTimeout(t.autoRotate,t.options.autoRotate);
			},
			construct:function() {
				$ul.parent().mouseover(function() {
					t.rotatePause();
				}).mouseout(function() {
					t.rotateContinue();
				})
				
				$prev.click(function() {
					t.rotatePause();
					t.rotatePrev();
					$(this).blur();
				});
			
				$next.click(function() {
					t.rotatePause();
					t.rotateNext();
					$(this).blur();
				});
				
				var i =0;
				$ul.find("li").each(function() {
					$(this).attr("id",i);
					i++;
				});
				
		
				t.reset(anim = false);
				
				if (t.options.autoRotate) {
					setTimeout(t.autoRotate,t.options.autoRotate);
				}
				
			}
		};
		

		obj.construct();
		
		this.listrotator = obj;
		
		Delay += betweenEachDelay;
	})		
}
