jQuery.fn.fader = function(options) {
	// default options
	var defaults = {
		fadeDuration: 1500,
		displayDuration: 5000,
		itemWrapperClass: 'items',
		itemTag: 'div',
		startAt: 0,
		loop: true,
		onComplete: false
	};

	// merge default options with supplied options
	var options = jQuery.extend(defaults, options);

	// perform for each matched element in selector
	return this.each(function() {
		// calculate positioning to use
		var position = jQuery(this).css('position') == 'absolute' ? 'absolute' : 'relative';

		// define container selector
		var container = '.' + options.itemWrapperClass;

		// define item selector
		var items = '.' + options.itemClass;

		// define item counter
		var itemCount = 0;

		var me = this;

		// locate container element
		jQuery(me).find(container).each(function() {
			// define reference to container for child functions
			var wrapper = this;

			// set positionining for container
			jQuery(wrapper).css('position', position);

			// find all the child elements we need within the container
			jQuery(wrapper).find(options.itemTag).each(function() {
				// fix for dodgy widths on block elements
				jQuery(this).css('float', 'left');

				// calculate centre position
				var top = (jQuery(wrapper).height() / 2) - (jQuery(this).height() / 2);
				var left = (jQuery(wrapper).width() / 2) - (jQuery(this).width() / 2);

				if(top < 0){top=0}

				// set default item styles
				jQuery(this).css({
					'position': 'absolute',
					'top': top + 'px',
					'left': left + 'px'
				});

				// keep track of count
				itemCount++;
			});

			// Hide all but the first one
			jQuery(wrapper).find(options.itemTag + ':gt(0)').hide();
		});

		// set initial conditions and begin looping
		var index = options.startAt;

		function next() {
			// hide current visible item
			jQuery(me).find(container + ' ' + options.itemTag + ':visible').css('z-index', 1).fadeOut(options.fadeDuration, function() {
				// prevent counter overflow
				if (index >= itemCount) {
					// exit looping if requested
					if (options.loop == false) {
						if (options.onComplete != false) {
							options.onComplete();
						}

						return;
					}

					index = 0;
				}

				// show next item
				jQuery(me).find(container + ' ' + options.itemTag + ':eq(' + index + '):hidden').css('z-index', 2).fadeIn(options.fadeDuration, function() {
					// increase counter for next iteration
					index++;

					// set timer for next execution
					var timer = setTimeout(next, options.displayDuration);
				});
			});
		}

		next();
	});
};