(function($) {

	$.fn.jqrotator = function( custom ) {
	
		// Options by default
		var defaults = {
			// Time between images in 'automatic' mode (seconds)
			sleep 		: 10,
			// Elapsed time before 'automatic' mode restarts after clicking a button (seconds) 
			sleepResume : 10,
			// Transition time in miliseconds 
			duration 	: 500,
			// Rotation 
			loop		: true,
			// Type of animation (jquery.easing.js is required to use other types than 'swing') 
			easing 		: 'swing',
			// Start with mute activated 
			startMuted	: true,
			// Disable mute button 
			disableMuteButton	: false
		}	
		var options = $.extend( defaults, custom );
		
		// Actions that apply to media
		var ACTION = {
			Play : 'play',
			Stop : 'stop'
		}
		
		return this.each( function( rotatorIndex ) {
		
			var $container = $(this);
			var $list = $container.find('>ul');
			var $items = $list.find('>li');
			var $buttons = $('<div class="jqrotator-buttons"></div>');
			var baseId = 'jqrotator'+rotatorIndex+'-item';
			var htmlButton = '<a href="#'+baseId+'%%INDEX%%" class="jqrotator-button">%%TEXT%%</a>';
			var htmlMute = '<a href="#" class="jqrotator-mute '+(options.startMuted?'enabled':'')+'">Mute</a>';
			var $current = null;
			var $mute = null;
			var timer = null;
			
			// Gets an element by passing an index, ID or jQuery instance 
			var getItem = function( item ) {
				if (typeof item == 'string') return $( '#'+item );
				else if (typeof item == 'number') return $items.eq( item );
				else if (item instanceof $) return item;
				else return $();
			}
			
			// Timer starts 
			var setTimer = function( sec ) {
				clearTimer();
				timer = setTimeout( nextItem, sec*1000 );
			}
			
			// Cleans the timer 
			var clearTimer = function() {
				if (timer) clearTimeout( timer );
				timer = null;
			}
			
			// Click on button 
			var buttonClick = function(e) {
				e.preventDefault();
				jumpTo( this.href.split('#').pop(), options.sleepResume );
			}
			
			// Alternate audio
			var mute = function(e) {
				e.preventDefault();
				if ($mute.hasClass('enabled')) $mute.removeClass('enabled');
				else $mute.addClass('enabled');
				
				if ($current.find('video')) {
					var video = $current.find('video').get(0);
					if ($mute.hasClass('enabled')) video.muted = true;
					else video.muted = false;
				}
			}
			
			// Next element 
			var nextItem = function() {
				var $next = $current.next('li');
				if (!$next.size()) 
					if (options.loop) $next = $items.first();
					else return;
				
				jumpTo( $next );
			}
			
			// Previous element 
			var prevItem = function() {
				var $prev = $current.prev('li');
				if (!$prev.size()) 
					if (options.loop) $prev = $items.last();
					else return;
				
				jumpTo( $prev );
			}			
			
			// Jump to an element
			var jumpTo = function( item, customTim ) {
			
				var $target = getItem( item );
				if (!$target.size()) return;
				if ($current && $target.get(0) == $current.get(0)) return;
				
				var $lastItem = $current;
				$current = $target;
				
				// Target position
				var targetPos = { left : $target.offset().left - $list.offset().left }
								
				// Movement
				$list.stop().animate({
					marginLeft : -targetPos.left+'px'
				}, options.duration, options.easing, function() {
					controlMedia( $lastItem, ACTION.Stop );
				});
				
				// Set button
				$buttons.find('a').removeClass('current');
				$buttons.find('a[href$="#'+$current.attr("id")+'"]').addClass('current');
				
				// Play video or flash 
				controlMedia( $current, ACTION.Play );
				
				// Show/hide mute button
				if ($mute) {
					if ($current.find('video').size()) $mute.fadeIn();
					else $mute.fadeOut();
				}
				
				// Timer
				setTimer( customTim || parseInt($target.attr('data-sleep'),10) || options.sleep );
			}
			
			// Controling video/flash of an element
			var controlMedia = function( item, action ) {
			
				var $target = getItem( item );
				
				// Object to control
				var $video = $target.find('video');
				var $flash = $target.find('object');
				
				if ($video.size() && typeof HTMLVideoElement != 'undefined') { 
					var video = $video.get(0);
					
					switch( action ) {
						case ACTION.Play: video.play(); //video.currentTime=0;
						$video.show(); break;
						case ACTION.Stop: video.pause(); $video.hide(); break;
					}
					
					if (action == ACTION.Play && $mute) {
						if ($mute.hasClass('enabled')) video.muted = true;
						else video.muted = false;
					}
				}
				
				if ($flash.size()) { 
					switch( action ) {
						case ACTION.Play: $flash.show(); break;
						case ACTION.Stop: $flash.hide(); break;
					}
				}			
				
			}
			
			// Classes & styles configuration
			$container.addClass('jqrotator-enabled');
			$list.addClass('jqrotator-list');
			$items.addClass('jqrotator-item');
			$container.css({
				'width' : $container.width()+'px',
				'height' : $container.height()+'px'
			});
			$list.css({
				'width' : ($container.width()*$items.size())+'px'
			});
			
			// Buttons
			$items.each(function(i) {
				$(this).attr('id', baseId+i)
					   .width( $container.width() + 'px' )
					   .height( $container.height() + 'px' );
					   
				var button = $( htmlButton.replace( /%%INDEX%%/gi, i).replace( /%%TEXT%%/gi, i+1) );
				button.bind( 'click', buttonClick );
				$buttons.append( button );
				
				//Stop medias
				controlMedia( $(this), ACTION.Stop );
			});
			$container.append($buttons);
			
			// Mute?
			if ($container.find('video').size() &&
				typeof HTMLVideoElement != 'undefined' &&
				!options.disableMuteButton)
			{
				$mute = $(htmlMute);
				$mute.bind('click', mute).hide();
				$container.append($mute);
			}
			
			// Create control methods in container element
			$container.get(0).nextItem = nextItem;
			$container.get(0).prevItem = prevItem;
			$container.get(0).mute = mute;
			
			// Seleccion primer elemento
			$buttons.find('a:first').trigger('click').hide().fadeIn('slow');
		
		});;
	}

})(jQuery);
