$.fn.seriaCarousel = function(params) {


	settings = jQuery.extend({
		queue: new Array(),
		duration:400,
		queueLength: 1000,
		disableQueue: false,
		imageWidth: 280,
		imageHeight: 160,
		minimumZoom: 0.3,
		maximumZoom: 1.5,
		initialRotation: 0,
		zoomFactor: 1,
		easing: function (x, t, b, c, d) {
			return c*((t=t/d-1)*t*t + 1) + b;
		},
		onRotateStart: function(e) {},
		onRotateEnd: function(e) {}
	}, params);

	return this.each(function(){
		var $this = $(this);
		settings.len = $this.children().length;
		$this.children().css({
			position:"absolute",
			listStyleType:"none",
			margin: 0,
			padding: 0
		});

		var curItem = settings.len;

		this.rotate = $.fn.seriaCarousel.rotate;
		this.rotateTo = $.fn.seriaCarousel.rotateTo;
		this.rotateLeft = $.fn.seriaCarousel.rotateLeft;
		this.rotateRight = $.fn.seriaCarousel.rotateRight;
		this.rotateToElement = $.fn.seriaCarousel.rotateToElement;
		var e = this;
		jQuery(window).load(function(){
			e.rotate(0);
			var num=0;
			$(e).children().each(function(){
				$(this).attr("num",num++);
			});
		});
	});
};

$.fn.seriaCarousel.rotate = function(deg) {
	deg=deg%360;
	var $this = $(this);
	var curItem = 0;
	var angle = ((deg+settings.initialRotation)/360)*(2*3.141592);

	if(deg<0)
		deg=360+deg;

	settings.currentDeg = deg;



	$this.children().each(function() {
		var item = $(this);
		var itemAngle = (angle + curItem*((2*3.14159265)/settings.len));
		var zIndex = Math.floor(Math.cos(itemAngle) * 10 + 10);
		var zoom = ((Math.cos(itemAngle) + 1)/2)*(settings.maximumZoom-settings.minimumZoom) + settings.minimumZoom;

		zoom = Math.pow(zoom, settings.zoomFactor);

		var $img = item.find("img");
		if(!$img.get(0).seriaCarouselWidth)
		{ // store pictures original width and height
			$img.get(0).seriaCarouselWidth = $img.width();
			$img.get(0).seriaCarouselHeight = $img.height();
		}

		var zWidth = Math.floor($img.get(0).seriaCarouselWidth * zoom);
		var zHeight = Math.floor($img.get(0).seriaCarouselHeight * zoom)

		var newPosX = Math.floor(((Math.sin(itemAngle)+1)/2) * ($this.width()-settings.imageWidth)) - zWidth/2 + settings.imageWidth/2;
		var newPosY = Math.floor(((Math.cos(itemAngle)+1)/2) * ($this.height()-settings.imageHeight)) - zHeight/2 + settings.imageHeight/2;
	
		$img.css({width:zWidth+"px",height:zHeight+"px"});
		$img.css("opacity",zoom>1?1:zoom);
		item.css({"z-index": zIndex});
		item.css({"left": newPosX + "px","top": newPosY + "px"});

		curItem++;
	});
}

// rotate to any given element by its offset
var currentElementPos = false;

$.fn.seriaCarousel.rotateToElement = function(e) {
	var deg = (360/settings.len);
	$(this).get(0).rotateTo(Math.floor(-deg*e.attr("num")));
	currentElementPos = e.attr("num");
	//alert(currentElementPos);
}

$.fn.seriaCarousel.rotateLeft = function() {
	currentElementPos++;
	if (currentElementPos >= settings.len) currentElementPos = 0;

	$(this).get(0).rotateTo(Math.floor(360 - currentElementPos*(360/settings.len)));
};
$.fn.seriaCarousel.rotateRight = function() {
	currentElementPos--;
	if (currentElementPos < 0) currentElementPos = settings.len - 1;

	$(this).get(0).rotateTo(Math.floor(360 - currentElementPos*(360/settings.len)));
};

//var autoRotateId = setTimeout($.fn.seriaCarousel.rotateLeft, 5000);

$.fn.seriaCarousel.rotateTo = function(targetDeg, duration, callback) {

	if(settings.isRotating)
		return false;
	if(!duration)
		duration = settings.duration;
	var $this = $(this);
	var thisElement = this;
	targetDeg = targetDeg%360;

	while(targetDeg<0)
		targetDeg+=360;

	var easing;
	if(settings.easing)
	{
		if(typeof settings.easing == "function")
			easing = settings.easing;
		else if(jQuery.easing[settings.easing])
			easing = jQuery.easing[settings.easing];
		else if(jQuery.easing.swing)
			easing = jQuery.easing.swing;
		else
			easing = jQuery.easing.linear;
	}
	else if(jQuery.easing.def)
		easing = jQuery.easing[jQuery.easing.def];
	else if(jQuery.easing.swing)
		easing = jQuery.easing.swing;
	else
		easing = jQuery.easing.linear;

	if(targetDeg==settings.currentDeg)
		return false;

	var startTime = false;
	var endTime = false;
	var startDeg = false;

	var callback = function(){
		if(startTime===false)
		{
			startTime = (new Date()).getTime();
			endTime = startTime+duration;
			startDeg = settings.currentDeg;
		}

		var time = (new Date()).getTime();
		var currentElapsedTime = time-startTime;
		var percent = (time-startTime)/(endTime-startTime)
		settings.isRunning = true;


		if(percent>1)
			percent=1;

		if((targetDeg-startDeg)>180) {
			var newDeg = easing(percent,currentElapsedTime,startDeg,-(360-(targetDeg-startDeg)),duration)
		} else if ((targetDeg-startDeg)<-180) {
			var newDeg = easing(percent,currentElapsedTime,startDeg,(360-(startDeg-targetDeg)),duration)
		}
		else {
			var newDeg = easing(percent,currentElapsedTime,startDeg,targetDeg-startDeg,duration)
		}

		$this.get(0).rotate(newDeg);


		if(percent<1){
			setTimeout(callback,0);
		}
		else {
			//alert(currentElementPos);
			settings.isRunning=false;
			settings.onRotateEnd(thisElement, currentElementPos);
			if(!settings.disableQueue && settings.queue.length>0)
			{
				var callback2 = settings.queue.shift();
				callback2();
			}
		}
	};

	if(!settings.isRunning)
	{
		settings.onRotateStart(thisElement);
		callback();
	}
	else
	{ // add callback to queue
		if(!settings.disableQueue && settings.queue.length < settings.queueLength)
			settings.queue[settings.queue.length] = callback;
	}
}
