(function($){
	$.jqImageCarousel = function(el, options, objectID)
	{
		var base = this;
		//Context Element
		base.contextEl = $(el); 
		
		base.contextEl.data('objectID', objectID);
		
		base.setEvents = function()
		{
			//Adicionar evento click previous
			$(base.options.directionElements.previous).bind('click', function(ev){
				
				ev.preventDefault();
				
				//Before callback
				base.options.before();
				
				var objAnim;
					
				if(base.animDirection == 'left')
				{
					objAnim = { left : '+=' + base.liMeasure };
				}
				else
				{
					objAnim = { top : '+=' + base.liMeasure };
				}
					
				//Animar o elemento
				$('ul:not(:animated)', base.contextEl).animate(objAnim, base.options.animSpeed, base.options.animEasing, function(){
					//Mover o último elemento para a primeira posição
					$('li:last', base.contextEl).insertBefore($('li:first', base.contextEl)); 
						
					//Colocar elemento correcto na sua posição correspondente
					$('ul', base.contextEl).css(base.animDirection, base.ulCssValue);
					
					//After callback
					base.options.after();
				});
			});
			
			//Adicionar evento click next
			$(base.options.directionElements.next).bind('click', function(ev){
				ev.preventDefault();
				
				//Before callback
				base.options.before();
				
				var objAnim;
				
				if(base.animDirection == 'left')
				{
					objAnim = { left : '-=' + base.liMeasure };
				}
				else
				{
					objAnim = { top : '-=' + base.liMeasure };
				}
				
				//Animar o elemento
				$('ul:not(:animated)', base.contextEl).animate(objAnim, base.options.animSpeed, base.options.animEasing, function(){
					//Mover o primeiro elemento para a última posição 
					$('li:first', base.contextEl).insertAfter($('li:last', base.contextEl));      
						
					//Colocar elemento correcto na sua posição correspondente
					$('ul', base.contextEl).css(base.animDirection, base.ulCssValue);
					
					//After callback
					base.options.after();
				});
			});
		};
		
		base.initSetInterval = function()
		{
			base.autoRun = setInterval(function(){ base.autoRotationFunction(); }, base.options.timeInterval);
			
			//Eventos mouseover e mouseout
			if(base.options.stopOnHover)
			{
				$('ul', base.contextEl).bind({
					mouseover : function(){
						clearInterval(base.autoRun);
					},
					
					mouseout : function(){
						base.autoRun = setInterval(function(){ base.autoRotationFunction(); }, base.options.timeInterval);
					}
				});
			}
		};

		//Função usada no SetInterval
		base.autoRotationFunction = function()
		{
			//Before callback
			base.options.before();
			
			var objAnim;
			
			if(base.animDirection == 'left')
			{
				objAnim = { left : '-=' + base.liMeasure };
			}
			else
			{
				objAnim = { top : '-=' + base.liMeasure };
			}
			
			//Animar o elemento
			$('ul:not(:animated)', base.contextEl).animate(objAnim, base.options.animSpeed, base.options.animEasing, function(){
				//Mover o primeiro elemento para a última posição 
				$('li:first', base.contextEl).insertAfter($('li:last', base.contextEl));
					
				//Colocar elemento correcto na sua posição correspondente
				$('ul', base.contextEl).css(base.animDirection, base.ulCssValue);
				
				//After callback
				base.options.after();
			});
		};
		
		//API Method (Argument zero-based)
		base.slideTo = function(slideNum)
		{
			if(typeof(slideNum) == 'number')
			{
				
				if($('ul', base.contextEl).is(':not(:animated)'))
				{
					//Before callback
					base.options.before();
					
					var objAnim, currentIndex, animValue = 0;
					
					currentIndex = $('li[initialPosition='+slideNum+']').index();
					animValue = ((currentIndex - 1) * base.ulCssValue);

					if(base.animDirection == 'left')
					{
						objAnim = { left : '+=' + animValue };
					}
					else
					{
						objAnim = { top : '+=' + animValue };
					}
					
					$('ul', base.contextEl).animate(objAnim, base.options.animSpeed, base.options.animEasing, function(){
						$('li', $(this)).slice(0, currentIndex - 1).each(function(){
							$(this).insertAfter($('li:last', base.contextEl)); 
						});
						
						$('ul', base.contextEl).css(base.animDirection, base.ulCssValue);
						
						//After callback
						base.options.after();
					});	
				}
			}
		};
		
		base.init = function()
		{
			base.options = $.extend($.jqImageCarousel.defaultOptions, options);
			
			//Calcular o tamanho de cada item e o valor a passar à ul
			if(base.options.direction == 'horizontal')
			{
				base.liMeasure = $('li:first', base.contextEl).outerWidth(true);
				base.animDirection = 'left';
			}
			else
			{
				base.liMeasure = $('li:first', base.contextEl).outerHeight(true);
				base.animDirection = 'top';
			}
			
			base.ulCssValue = base.liMeasure * (-1); 
			
			//Mover o último elemento para a primeira posição
			$('li:last', base.contextEl).insertBefore($('li:first', base.contextEl)); 
			
			//Colocar elemento correcto na sua posição correspondente
			//$('ul', base.contextEl).css(base.animDirection, base.ulCssValue);
			var objAnim;
			if(base.animDirection == 'left')
			{
				objAnim = { left : '-=' + base.liMeasure };
			}
			else
			{
				objAnim = { top : '-=' + base.liMeasure };
			}
			
			$('ul', base.contextEl).animate(objAnim, base.options.animSpeed, base.options.animEasing, function(){
				//After callback
				base.options.after();
			});
			
			base.setEvents();
			
			if(base.options.autoRotation)
			{
				base.initSetInterval();
			}
		};
		
		base.init();
	};
	
	$.jqImageCarousel.defaultOptions = {
		direction : 'horizontal',
		animSpeed : 500,
		animEasing : 'swing',
		directionElements : { previous : '.prevarrow', next : '.nextarrow' },
		timeInterval : 5000,
		autoRotation : true,
		stopOnHover : false,
		before : function(){}, //callback invoked before start animation
		after : function(){} //callback invoked after start animation
	};
	
	//Holds currently ID
	$.jqImageCarousel.ObjectID = -1;
	//Array of objects
	$.jqImageCarousel.Objects = [];
	
	$.fn.jqImageCarousel = function(options)
	{
		return this.each(function(){
			if(typeof(options) == 'number')
			{
				$.jqImageCarousel.Objects[$(this).data('objectID')].slideTo(options);
			}
			else
			{
				$.jqImageCarousel.ObjectID++;
				$.jqImageCarousel.Objects[$.jqImageCarousel.ObjectID] = new $.jqImageCarousel(this, options, $.jqImageCarousel.ObjectID);
			}
		});
	};
})(jQuery);
