jQuery.fn.rotator = function(options) {
	var $ = jQuery;
	var orig_arguments = arguments;
	
	var next_image = function(obj) {
		reset_timer(obj);
		
		var images = $(obj).data('images');
		var img = $(".rotator-image", obj);
		if (images.length) {
			// get pointer value
			var p = $(obj).data('pointer') + 1;
			if (p >= images.length) {
				p = 0;
			}
			$(obj).data("pointer", p);
		
			set_image(obj, images[p]);
			
			// show the image
			img.fadeTo(options.fade_speed, 1);
		}
	};
	
	var prev_image = function(obj) {
		reset_timer(obj);
		
		var images = $(obj).data("images");
		var img = $(".rotator-image", obj);
		if (images.length) {
			// get pointer value
			var p = $(obj).data('pointer') - 1;
			if (p < 0) {
				p = images.length - 1;
			}
			$(obj).data("pointer", p);
		
			set_image(obj, images[p]);
		}
	};
	
	var set_image = function(obj, image) {
		$(".rotator-image", obj).fadeTo(options.fade_speed, 0, function() {
			$(".rotator-image-link", obj).attr("href", image.link);
			$(".rotator-image", obj).attr("src", image.src).attr("alt", image.alt);
			$(".rotator-image", obj).fadeTo(options.fade_speed, 1);
		});
	}
	
	var reset_timer = function(obj) {
		if (options.interval) {
			clearTimeout($(obj).data('timer'));
			$(obj).data("timer", setTimeout(next_image, options.interval, obj));
		}
	}
	
	return $(this).each(function() {
		switch (typeof options) {
			case 'undefined':
				options = new Object();
			case 'object':
				// initialize default options if non-existant
				if (typeof options.width == 'undefined')
					options.width = 250;
				if (typeof options.height == 'undefined')
					options.height = 250;
				if (typeof options.interval == 'undefined')
					options.interval = 8000;
				if (typeof options.fade_speed == 'undefined')
					options.fade_speed = "slow";
				if (typeof options.draw_nav == 'undefined')
					options.draw_nav = false;
			
				// initialize the images array
				var images = new Array();
				$("div", this).each(function() {
					images.push({
						src : $("img", this).attr("src"),
						link : $("a", this).length > 0 ? $("a", this).attr("href") : false,
						alt : $("img", this).attr("alt"),
						caption : $("span", this).length > 0 ? $("span", this).html() : false
					});
					$(this).remove();
				});

				// add the rotator image
				var link_start = images[0].link ? '<a href="#" class="rotator-image-link">' : '';
				var link_end = link_start ? '</a' : '';
				$(this).html(link_start + '<img class="rotator-image" src="#" alt="" width="' + options.width + '" height="' + options.height + '" />' + link_end);
				
				if (options.draw_nav) {
					// set the css properties of the prev/next buttons
					$(this).prepend('<div class="rotator-prev rotator-nav"></div><div class="rotator-next rotator-nav"><div>');
					$(".rotator-nav", this).css({
						width : "20%",
						height : "100%",
						display: "block",
						backgroundColor : "#f00",
						position : "absolute",
						zIndex : 1,
						cursor : "pointer"
					});
					$(".rotator-prev", this).css('left', "0");
					$(".rotator-next", this).css('left', "80%");
				}
				
				// set css properties of main div
				$(this).css({
					width : options.width + "px",
					height : options.height + "px",
					display : "block"/*,
					position : "absolute"*/
				})

				// bind the images array to the data object of the DOM element
				$(this).data('images', images);
				$(this).data('pointer', -1);
				$(this).data('timer', null);
				
				// load the first image
				next_image(this);
			break;
			case 'string':
				if (options == 'next') {
					next_image(this);
				} else if (options == 'prev') {
					prev_image(this);
				} else if (options == 'goto') {
					var index = orig_arguments[1];
					var image = $(this).data('images')[index];
					set_image(this, image);
				}
			break;
		}
	});
};