		
		function Rotator ($, elem, opts) {
			
			var $                = $;
			var self             = this;
			var container        = elem; // Container Element
			var items            = [];   // Items to rotate
			var timeoutID        = -1;
			var startTime        = -1;
			var pausedTime       = -1;
			var isPaused         = false;
			var currentItemIndex = -1; 
			var rotationCount    = 0;
			
			
			// Private Scope
			var priv = {};
			
			// Public Scope
			var pub  = {};			
			
			// Properties
			var properties = {
				speed       : 500,  // Animation speed
				delay       : 3000, // Delay between transitions
				rotationMax : -1,
				
				animation   : function (itemToShow) {
					$(items[currentItemIndex]).fadeOut(properties.speed, function () {
						$(this).removeClass("active");
						$(itemToShow).fadeIn(properties.interval, function (){ $(this).addClass("active") });
					});
				}
			}				
				
			// Initiator
			priv.init = function () {
				$.extend(properties, opts);				
				items = $(elem).find('.item');
				currentItemIndex = 0;				
				return pub;
			};
			
			
			// Methods	
			pub.transition = function () {
				var nextItemIndex;
				
				if (currentItemIndex < items.length-1) {
					nextItemIndex = currentItemIndex + 1;
				} else {
					nextItemIndex = 0;
					rotationCount++;
				}
				
				if (properties.rotationMax !== -1 && rotationCount >= properties.rotationMax) {
					pub.stop();
				} else {
					properties.animation(items[nextItemIndex]);
					currentItemIndex = nextItemIndex;	
					pub.start();
				}
			};
				
				
			pub.start = function (delay) {
				if (items.length < 2) return;
				if (delay !== null) var delay = properties.delay;
				
				timeoutID = setTimeout(pub.transition, properties.delay);
				startTime = (new Date()).getTime();
			};
			
			
			pub.stop = function () {
				clearTimeout(timeoutID);
			}
				
				
			pub.pause = function () {		
				clearTimeout(timeoutID);
				isPaused = true;
				pausedTime = (new Date()).getTime();			
			};
				
				
			pub.resume = function () {
				if (isPaused) {
					var remainingDelay = properties.delay - ((pausedTime - startTime) % properties.delay);
					isPaused = false;
					pausedTime = -1;
					pub.start(remainingDelay);
				} else {
					pub.start();
				}
			};
			
			
			pub.getItems = function () {
				return items;
			}
			
			
			return priv.init();				
		}
		
