(function($) {                                          // Compliant with jquery.noConflict()
$.fn.carousel = function(o) {
	o = $.extend({

		speed: 400,
		onLoop: null			//Callback function to run after the list goes through one cycle

	}, o || {});

	return this.each(function() {		// Returns the element collection. Chainable.

		var running = false;
		var animCss = "left";		//css property to animate
		var div = $(this);			//the <div>
		var ul = $("ul", div);		//the <ul>
		var li = $("li", ul);		//all <li> elements
		ul.append( li.clone() );	//duplicate the list onto itself
		li = $("li", ul);			//recapture all <li> elements
		var numItems = li.size();	//total number of <li> elements

		li.css({
			overflow: "hidden",
			float: "left",
		});

		ul.css({
			margin: "0",
			padding: "0",
			position: "relative",
			"list-style-type": "none",
			"z-index": "1",
			overflow: "hidden",
			left: "0",
			//border: "1px solid black",		//debug
		});
		
		div.css({
			"visibility": "visible",
				overflow: "hidden",
				position: "relative",
				"z-index": "2",
		});

		//Compute total width of ul
		var ulWidth = 0;
		for ( var i = 0; i < numItems; ++i )
		{
			var el = li.eq(i);
			var liWidth = el.width() + parseInt(el.css('marginLeft')) + parseInt(el.css('marginRight'));
			ulWidth += liWidth;
		}
		ul.css( "width", ulWidth + "px" );

		go();

		function go()
		{
			if ( !running )
			{
				running = true;
				ul.css( animCss, 0 );		//reset position
				ul.animate(
					{ left: -ulWidth / 2 },
					o.speed,
					'linear',
					function()
					{
						if ( o.onLoop )
							o.onLoop.call( this, vis() );
						running = false;
						go();
					}
				);

			}
			return false;
		};
	});
};

})(jQuery);
