(function($) {
	$.fn.htmlrotate = function(conf) {
		var opts = {
			// basics
			interval: 5000,
			direction: "forward",
			frozen: 0,
			start: true,

			// callbacks
			onInit: null,
			onStep: null,
			onRotate: null
		};

		$.extend(opts, conf);

		this.each(function() {
			var self = $(this);
			var kids = $(self).children();

			$(kids).eq(0).css("opacity",1).css("position","absolute").css("z-index",3).show();
			$(kids).not(":eq(" + 0 + ")").css("position","absolute").css("z-index",1).css("opacity",0).hide();

			if($.browser.msie == 1) {
				$(kids).each(function() {
					$(this)[0].style.removeAttribute("filter");
				})
			}

			$(self)
				.unbind("htmlrotate.stepforward")
				.unbind("htmlrotate.stepback")
				.unbind("htmlrotate.stop")
				.unbind("htmlrotate.start")
				.unbind("htmlrotate.rotate")

				.data("interval",opts.interval)
				.data("direction",opts.direction)
				.data("frozen",opts.frozen)
				.data("step",function() {
					var index = ($(self).data("index")) ? parseInt($(self).data("index")) : 0;
					var kids  = $(self).children();

					if($(kids).length == 1) { return true; }

					if($(self).data("direction") == "back") {
						var nextindex = index - 1;
						if(nextindex < 0) { nextindex = (kids.length - 1); }
					} else {
						var nextindex = index + 1;
						if(nextindex >= kids.length) { nextindex = 0; }
					}

					$(kids).not(":eq(" + index + ")").css("z-index",1).css("opacity",0).show().stop();
					$(kids[index]).css("z-index",3).css("opacity",1).show().stop();
					$(kids[nextindex]).css("z-index",2).css("opacity",0).show().stop().animate({ opacity: 1 }, "slow", function() { if($(this)[0].style.removeAttribute) { $(this)[0].style.removeAttribute("filter"); } });
					$(kids[index]).css("opacity",1).stop().animate({ opacity: 0 }, "slow", function() { $(kids).not(":eq(" + nextindex + ")").hide(); if($(this)[0].style.removeAttribute) { $(this)[0].style.removeAttribute("filter"); } });
					$(self).data("index",nextindex);

					if(typeof opts.onStep == "function") { opts.onStep(); }
				})
				.data("settimer",function(clr) {
					if(!clr) { clearTimeout($(self).data("timer")); }
					else { $(self).data("timer",($(self).data("frozen") == 0) ? setTimeout(function() { $(self).trigger("htmlrotate.rotate"); }, $(self).data("interval")) : ""); }
				})

				.bind("htmlrotate.stepforward",function() {
					var self = $(this);
					var cur  = $(self).data("direction");

					$(self).data("settimer")(false);

					$(self).data("direction","forward");
					$(self).data("step")();
					$(self).data("direction",cur)

					$(self).data("settimer")(true);
				})
				.bind("htmlrotate.stepback",function() {
					var self = $(this);
					var cur  = $(self).data("direction");

					$(self).data("settimer")(false);

					$(self).data("direction","back");
					$(self).data("step")();
					$(self).data("direction",cur)

					$(self).data("settimer")(true);
				})
				.bind("htmlrotate.rotate",function() {
					var self = $(this);

					$(self).data("settimer")(false);
					$(self).data("step")();

					// Run onRotate
					if(typeof opts.onRotate == "function") { opts.onRotate(); }

					$(self).data("settimer")(true);
				})
				.bind("htmlrotate.start",function() {
					var self = $(this);

					$(self).data("settimer")(false);
					$(self).data("frozen",0);
					$(self).data("settimer")(true);
				})
				.bind("htmlrotate.stop",function() {
					var self = $(this);
					$(self).data("settimer")(false);
					$(self).data("frozen",1);
				})

				if(opts.start == true || opts.start == 1 || opts.start == "true") {
					$(self).trigger("htmlrotate.start");
				}
		})

		// Run OnInit
		if(typeof opts.onInit == "function") { opts.onInit(); }

		return this;
	};
})(jQuery);