(function($){
	$.fn.rotate3DMenu = function ( click_area )
	{
		var menu = new Rotate3DMenu();
		menu.height = this[0].offsetHeight;
		menu.width = this[0].offsetWidth;
		menu.objects = this;
		menu.clickable = click_area[0];
		menu.onMouseMove = rotate3DOnMouseMove;
		menu.onMouseDown = rotate3DOnMouseDown;
		menu.onMouseUp = rotate3DOnMouseUp;
		menu.clickable.menu = menu;
		
		this.each( function( i )
		{
			//initialize each object:
			this.i = 2*Math.PI*(1/(menu.objects.length))*i;
			this.x3d = menu.mid_x + menu.x_range*Math.cos( this.i );
			this.y3d = menu.mid_y + menu.y_range*Math.sin( this.i );
			this.z_w = menu.width*( 1 + menu.scale*Math.sin( this.i ) );
			this.z_h = menu.height*( 1 + menu.scale*Math.sin( this.i ) );
		});
		
		$(menu.clickable).addEnterFrameListener( 1000/32 , "moveObjects" );
		
		$(menu.clickable).mousedown( rotate3DOnMouseDown );
		$(menu.clickable).mouseup( rotate3DOnMouseUp );
		
		$(menu.clickable).bind( 'mousedown' , { object : menu.clickable } , rotate3DOnMouseDown );
		$(menu.clickable).bind( 'mouseup' , { object : menu.clickable } , rotate3DOnMouseUp );
		
		return this.each( function( i )
		{
			$(this).css( { 	left : this.x3d + 'px' , 
							top : this.y3d + 'px' ,
							width : this.z_w + 'px' , 
							height : this.z_h + 'px' ,
							zIndex : Math.round( this.z_w ) } );
			/*
			this.style.left = this.x;
			this.style.top = this.y;
			this.style.width = this.z_w;
			this.style.height = this.z_h;
			this.style.zIndex = Math.round( this.z_w );
			*/
		});
	};
})(jQuery);

function rotate3DOnMouseMove( event )
{
	var object = event.data.object;

	var x = event.pageX - object.style.left;
	var y = event.pageY - object.style.top;
	
	var menu = object.menu;
	menu.objects.each( function( i )
	{
		if( y < menu.mid_y )
		{
			this.i += (x - menu.prev_x)/200;
		}
		else
		{
			this.i -= (x - menu.prev_x)/200;
		};
	});
	
	menu.prev_prev_x = menu.prev_x;
	menu.prev_x = x;
	menu.prev_y = y;
}

function rotate3DOnMouseDown( event )
{
	var object = event.data.object;

	var menu = object.menu;
	menu.speed = 0;
	menu.is_dragging = true;
	
	menu.prev_prev_x = event.pageX;
	menu.prev_x = event.pageX;
	menu.prev_y = event.pageY;
	$(object).bind( "mousemove" , { object : object } , rotate3DOnMouseMove );
	
	if( event.preventDefault )
	{
		//event.preventDefault();
	};
	
	return;
};

function rotate3DOnMouseUp( event )
{
	var object = event.data.object;
	
	var menu = object.menu;
	
	menu.is_dragging = false;
	$(object).unbind( "mousemove" , rotate3DOnMouseMove );
	
	var x = event.pageX - object.style.left;
	var y = event.pageY - object.style.top;
	
	if( y < menu.mid_y )
	{
		menu.speed = (x - menu.prev_prev_x)/200;
	}
	else
	{
		menu.speed = -(x - menu.prev_prev_x)/200;
	};
};

function Rotate3DMenu()
{
	this.mid_x = 500;
	this.mid_y = 350;
	this.x_range = this.mid_x/2;
	this.y_range = this.mid_y/4;
	this.scale = .3;
	this.height;
	this.width;
	this.speed = 0;
	this.prev_x = 0;
	this.prev_y = 0;
	this.prev_prev_x = 0;
	this.objects;
	this.clickable;
	this.is_dragging;
};

function moveObjects( target )
{
	var menu;

	if( typeof target == 'string' )
	{
		target = $('#' + target )[0];
		menu = target.menu;
	}
	else
	{
		menu = target.menu;
	};
	
	menu.objects.each( function( i )
	{
		this.i += target.menu.speed;
		
		this.x3d = menu.mid_x + 	menu.x_range*Math.cos( this.i );
		this.y3d = 	menu.mid_y + 	menu.y_range*Math.sin( this.i );
		this.z_w = 	menu.width*( 1 + 	menu.scale*Math.sin( this.i ) );
		this.z_h = 	menu.height*( 1 + 	menu.scale*Math.sin( this.i ) );
		
		$(this).css( { 	height : this.z_w + 'px' , 
						width : this.z_h + 'px' ,
						left : (this.x3d - this.z_w/2) + 'px' ,
						top : (this.y3d - this.z_h/2) + 'px' ,
						zIndex : Math.round( this.z_w ) } );
		
		/*
		this.style.height = this.z_w + 'px';
		this.style.width = this.z_h + 'px';
		this.style.left = (this.x3d - this.z_w/2) + 'px';
		this.style.top = (this.y3d - this.z_h/2) + 'px';
		this.style.zIndex = Math.round( this.z_w );
		*/
	});
	
	if( Math.abs( 	menu.speed ) < 0.00001 )
	{
			menu.speed = 0;
		if( !	menu.is_dragging )
		{
			//$(target).removeEnterFrameListener( "moveObjects" );
		};
	}
	else
	{
		menu.speed = menu.speed*0.95;
	};
	
	return;
};

function move3dObjects( event )
{
	var object = event.data.object;
	var speed = event.data.speed;
	
	object.menu.speed = speed;
	
	event.preventDefault();
	
}

