// Deshabilita seleccionar texto 
$.fn.disableTextSelect = function() {

	return this.each(function(){
		if($.browser.mozilla){//Firefox
			$(this).css('MozUserSelect','none');
		}else if($.browser.msie){//IE
			$(this).bind('selectstart',function(){return false;});
		}else{//Opera, etc.
			// Buggy on chrome
			//$(this).mousedown(function(){return false;});
		}
	});
}

$.fn.carousel = function( config ) {

	return this.each(function() {
	
		var i;
	
		var options = {
			autoplay 				: false,
			timeout					: 5000,
			loop					: false,
			speed					: 500,
			stepCount				: 1,			
			disableAnimation		: false,
			disableStyles			: false,
			ease					: $.easing["easeInOutSine"] ? "easeInOutSine" : "swing",
					
			itemHeight				: 0,
			
			/* Contenedores */
			canvasItem				: this,
			contentItem				: "ul:first-child,ol:first-child",
			listItem				: "li",
			controlsItem			: this,
			selectedClass			: "selected",
			
			/* Controles */
			firstControl			: "",
			leftControl				: "<a href='#'>left</a>",
			rightControl			: "<a href='#'>right</a>",
			lastControl				: "",
			pageControl				: "", /* %page% para imprimir el numero de pagina */
			pageSeparator			: " | ",
			
			onChange				: null,
			
			paddingLeft				: 0,
			paddingRight			: 0
		};
		
		$.extend( options, config );
			
		var canvas = $(options.canvasItem);
		var canvasWidth = $(options.canvasItem).width();
		
		var content = $(options.contentItem, this);
		var list = $(options.listItem, content);
		
		var canvasHeight = options.itemHeight || canvas.height() || list.first().height();
		
		var loopLeft=[], loopRight=[];
		
		if (list.size() == 0) return;
		
		var allControls = [];
		
		var current = 0;
		var apInterval;
					
		var createControls = function() {
		
			var controls = {
				first: options.firstControl ? $(options.firstControl) : null,
				left: options.leftControl ? $(options.leftControl) : null,
				right: options.rightControl ? $(options.rightControl) : null,
				last: options.lastControl ? $(options.lastControl) : null,
				page: []
			}
			
			/* Crea los controles de acceso a cada pagina */
			if (options.pageControl) {
				for (i=0; i<list.size(); i+=options.stepCount) {
					controls.page.push( $( options.pageControl.replace("%page%", i+1) ) );
				}
			}
			
			/* Asignamos accion a los controles */
			if (controls.first) controls.first.click( first );
			if (controls.left) controls.left.click( prev );
			if (controls.right) controls.right.click( next );
			if (controls.last) controls.last.click( last );
			for (i in controls.page) controls.page[i].attr("page", i).click( function(e) { page( $(this).attr("page"), e ); } );
			
			allControls.push( controls );
			
			return controls;
		};
		
		var animate = function( instant, customTarget ) {
				
			reportChange();
			
			for (var i in allControls) {
				for (var j in allControls[i].page) {
					if (parseInt(j) == current) allControls[i].page[j].addClass(options.selectedClass);
					else allControls[i].page[j].removeClass(options.selectedClass);
				}
			}
			
			if (options.disableAnimation) return;			
			
			if (typeof customTarget == "number") customTarget = $(list[customTarget]);
			var target = customTarget || $(list[current]);
		
			content.animate( {
				marginLeft: - target.offset().left + content.offset().left + options.paddingLeft
			}, instant ? 0 : options.speed, options.ease )
					
		};
		
		var reportChange = function() {
		
			if (typeof(options.onChange) === "function") options.onChange({
				current : current,
				page	: Math.floor(current/options.stepCount),
				total	: list.length,
				item	: list[current],
				playing : options.autoplay
			});			
		
		}
		
		var autoplay = function( force ) {
		
			if (options.autoplay || force ) {
				apInterval = setTimeout( next, options.timeout );
				options.autoplay = true;
			}
		
		}
		
		var stopAutoplay = function() {
			options.autoplay = false;
			clearTimeout( apInterval );
		}
				
		var init = function() {
		
			var i;
			
			if ( options.autoplay > 0 ) {
				options.timeout = options.autoplay;
				options.autoplay = true;
			}
					
			if (!options.disableStyles) {
				content.width( (canvasWidth + 50) * list.length );
			
				canvas.css( { overflow:"hidden", height:canvasHeight } );
				content.css( { overflow:"visible" } );
				list.css( { "float":"left", overflow:"visible" } );
			}
			
			/* Efecto loop infinito (duplicamos elementos) */
			if (options.loop && list.size() > options.stepCount) {
				var o, c;
							
				// Anteriores
				c = options.stepCount*2
				for (i = list.size() - options.stepCount*2; i < list.size(); i++ ) {
					o = list.eq(i%list.length).clone(true).insertBefore( list.eq(0) );
					loopLeft[--c] = o;
				}
				
				// Posteriores
				c = 0;
				o = list.eq( list.size()-1 );
				for (i = 0; i < options.stepCount*2; i++ ) {
					o = list.eq(i%list.length).clone(true).insertAfter( o );
					loopRight[c++] = o;
				}

			}
			
			/* Aņadimos controles */		
			if (list.length > options.stepCount) {

				$(options.controlsItem).each( function() {
					var self = $(this);
					var controls = createControls();
					
					// Clonamos el objeto
					if (controls.first) self.append( controls.first ).append(" ");
					if (controls.left) self.append( controls.left ).append(" ");
					for (i in controls.page) self.append( controls.page[i] ).append(parseInt(i)<list.length-1?options.pageSeparator:" ");
					if (controls.right) self.append( controls.right ).append(" ");
					if (controls.last) self.append( controls.last ).append(" ");
				} );
				
				autoplay();
				
			}
			
			canvas.disableTextSelect();
			
			animate(true);
			
		};
		
		var next = function( e ) {
			if (e && isNaN(e)) {
				e.preventDefault();
				stopAutoplay();
			}
			current+=options.stepCount;
			if (current >= list.length ) {
				if (options.loop) {
					animate(true, loopLeft[ Math.abs((current - options.stepCount) - list.length) - 1 ] );
					current = current%list.length;
				} else current = list.length-options.stepCount;
			}
			animate();
			autoplay();
		};
		
		var prev = function( e ) {
			if (e) {
				e.preventDefault();
				stopAutoplay();
			}
			current-=options.stepCount;
			if (current < 0) {
				if (options.loop) {
					animate(true, loopRight[ Math.abs(current + options.stepCount) ] );
					current = current+list.length;
				} else current = 0;
			}
			animate();
			autoplay();
		};
		
		var first = function( e ) {
			if (e) e.preventDefault();
			current=0;
			animate();
		};
		
		var last = function( e ) {
			if (e) e.preventDefault();
			current=list.length-options.stepCount;
			animate();
		};
		
		var page = function( n, e ) {
			if (e) e.preventDefault();
			current=parseInt(n)*options.stepCount;
			animate();
		};
		
		init();
		
		// Acceso externo
		this.next = next;
		this.prev = prev;
		this.first = first;
		this.last = last;
		this.page = page;
		this.setTimeout = function( t ) { options.timeout = t; }
		this.getTimeout = function() { return options.timeout; }
		this.isPlaying = function() { return options.autoplay; }
		this.start = function() { autoplay( true ); reportChange(); }
		this.stop = function() { stopAutoplay(); reportChange(); }
		this.change = reportChange;
		
	
	});

}
