/*
 * Create a 3D carousel similar to the popular Flash carousel
 *
 * @name		carousel3d
 * @author		Kevin Crossman
 * @contact		kevincrossman@gmail.com
 * @version		0.3
 * @date			June 30 2008
 * @type    	 	jQuery
 * @example  
 *
 *
 *	 	* Place icon images inside $('#carousel')
 *
 * 				<div id='carousel'>
 *						<img src='images/icon1.png' alt='icon1' /> 
 *						<img src='images/icon2.png' alt='icon2' /> 
 *						<img src='images/icon3.png' alt='icon3' /> 
 *						<img src='images/icon4.png' alt='icon4' /> 
 *				</div>
 *
 *	 	* Place corresponding spans inside $('#carouselText')
 * 		* spans  contains content that will be displayed when the icon is clicked *

 *				<div id="carouselText">
 *						<span>customize this space for icon 1</span>
 *						<span>customize this space for icon 2</span>
 *						<span>customize this space for icon 3</span>
 *						<span>customize this space for icon 4</span>
 *				</div>
 *
 *	 	* End with a div to display the content from $('#carouselText span')
 *
 * 				<div class="text"></div>
 *
 */
 
(function($) {

    $.fn.carousel3d = function(options) {

        var opt = $.extend({}, $.fn.carousel3d.defaults, options);

        return this.each(function() {
        
            $this = $(this);  // $this = #carousel
            $imgs = $('img', $this).hide();  // $imgs = images in #carousel
            $texts = $('span', $('#carouselText')).hide();  // $texts = spans that store the text info displayed when an image is clicked
            
            var items = $this.children().size();  // items = the number of visible images circling the carousel
            var numSlots = items * opt.padding; // in order for the movement to flow smoothly, there are additional 'slots' in the carousel which the images will pace through
			var speed = 0.01;
			
			if (opt.padding==0) opt.padding=1;
            
            $o = new Array();
           
			$().mousemove(function(e){
				opt.centerX= ((document.documentElement.clientWidth)/2)+25;
                speed = ( e.pageX - opt.centerX)/2500;
				if(speed>=0.025) speed=0.025;
				if(speed<=-0.025) speed = -0.025;

				}); 
   			
			// set up actions to reset carousel when image is clicked again
			function clickOff ($obj, $obj2) { 

				$obj.click( function() {
					// show the carousel images and remove text
					$imgs.fadeIn(1500);
					$('.text').fadeOut(500);
	
					// animate back to carousel position, changing location and size
					$(this).animate({
						left: $obj2.offset().left+'px',
						top: $obj2.offset().top+'px',
						width: $obj2.width()+'px',
						height: $obj2.height()+'px'
					},  500,
					//remove the cloned image, rebind the img click events and start carousel
					function() {
						$(this).remove();
						$imgs.one('click', clickOn);
						t1.start();
					});
				});
			};

			// function for actions when image in carousel is clicked
			function clickOn() {

				$ob = $(this);
				
				t1.stop(); // stop the timer and unbind the mouseout event so that carousel doesn't start again
                
				// close the image clicked and leave the original in place (this seemed easier than pulling the orig out of place)
				// animate the clone to the side of the screen
				if (!opt.textBox) {
					$cloned = $ob.clone().prependTo($this).css('border', '1px solid #fff').animate({ 	
						top: opt.centerY - opt.radiusY + 'px', 
						left: opt.centerX - ($o[$imgs.index($ob)]._orig_w/2) + 'px',
						width: $o[$imgs.index($ob)]._orig_w+'px',
						height: $o[$imgs.index($ob)]._orig_h+'px'
					}, 500); 
      			}
       	 		else {
    	   			$cloned = $ob.clone().prependTo($this).animate({
						left: opt.centerX - $o[$imgs.index($ob)]._orig_w*2,
						top: opt.centerY + $texts.eq($imgs.index($ob)).height()/2,
						width: $o[$imgs.index($ob)]._orig_w+'px',
						height: $o[$imgs.index($ob)]._orig_h+'px'
					}, 500);
					$('.text').css({	
						top: opt.centerY-opt.radiusY, 
       					left: opt.centerX-($cloned.width()/2)
   	 				}).html($texts.eq($imgs.index($ob)).html()).fadeIn(500); 
        		}
               
				// get the text of the matching span index
	 			$imgs.fadeOut(500); // hide the carousel
						
				clickOff($cloned, $ob);
  			};
				
            // assign inital values to images; images will be called by the name attribute 
            // when rotating, so each is assigned a name (separated by the value of the padding)
            $imgs.each(function(i)  {
            
                $o[i] = new Object();
                $o[i]._img = $(this);
                $o[i]._h = $(this).height()*(150/$(this).height());
                $o[i]._w = $(this).width()*(150/$(this).width());
                $o[i]._orig_h = $(this).height();
                $o[i]._orig_w = $(this).width();
                $o[i]._slot = i*opt.padding;
                $o[i]._angle = (i*opt.padding) * ((Math.PI*2)/numSlots);
                
                $(this).addClass('pix'+i);
            });
            
			$imgs.show();
   
			// setup tooltip for images
          	if (opt.showTooltip){
          		$imgs.tooltip({
					track: true,
					delay: 500,
					showURL: false,
					showBody: "|",
					opacity: 0.95,
					fixPNG: true,
					top: -130,
					left: -90
            	}).one('click', clickOn);
            }
            else {
            	$imgs.one('click', clickOn);
            }

			t1 = new Tween(new Object(),'xyz',Tween.bounceEaseOut,0,10000, 10000);
			t1.onMotionChanged = function(event){
   		
   			 	for (var j = 0; j < items; j++) {	
					
					$_this = $o[j]._img;
					
   					if ($o[j]._slot == numSlots-1) $o[j]._slot=0;
   					else $o[j]._slot += 1; 
   					
   					var _a = $o[j]._angle;
               		var _t = Math.sin(_a) * opt.radiusY + opt.centerY;
               		var _l = Math.cos(_a) * opt.radiusX + opt.centerX;
                	var _s = ((_t - opt.perspective) / (opt.centerY + opt.radiusY - opt.perspective));
                			
                	$o[j]._angle += speed;
                	
                	if (!opt.showTooltip) var _border ='1px solid #363636';
                	else var _border = '0';
   					
   					var n = parseInt($o[j]._slot);
					$_this.css({	
						top: _t,
						left: _l,
						width: $o[j]._w * _s,
						height: $o[j]._h * _s,
						position: 'absolute',
						border: _border
					});
				}
			};
			t1.start();
        });
    };

	// plugin defaults
	$.fn.carousel3d.defaults = {
   	 	textBox: 1,  //  1 = display text area for each icon, 0 = no display
    	showTooltip: 1,  // 1= show tooltip, 0 = do not show
    	radiusX: 300,  // x radius of the carousel
    	radiusY: 100,  // y radius of the carousel
    	centerX: ((document.documentElement.clientWidth)/2)+25,
		centerY: 400,  // y position on the screen
    	perspective: 80,  // adjusts the perspective of the icon as it travels around the carousel
    	padding: 24  // the number of padded items in between each icon.  
    					// the more padding, the more precise the incremental movement,
    					// however this also create a lot more calculations
    					// to keep icons evenly spaced, the num of icons should be a multiple of the padding
	};
})(jQuery);

