/*
 * Create a 3D carousel similar to the popular Flash carousel
 *
 * @name		carousel3d
 * @author		Kevin Crossman
 * @contact		kevincrossman@gmail.com
 * @version		1.1
 * @date			Oct 29 2008
 * @type    	 	jQuery
 * @example  
 *
 *	 	* Place icon images inside <div id="carousel" />
 *
 * 				<div id='carousel'>
 *						<img src='images/image1.png' alt='image1' /> 
 *						<img src='images/image2.png' alt='image2' /> 
 *						<img src='images/image3.png' alt='image3' /> 
 *						<img src='images/image4.png' alt='image4' /> 
 *
 *		* to make image a page link, add class 'link' and set the longdesc attr to a web address
 *						<img class="link" src='images/image5.png' alt='image5' longdesc="http://plugins.jquery.com/" /> 
 *
 *				</div>
 *
 *	 	* If using text box, place divs inside <div id="carouselText" /> and add <div class="text" /> to house the info when displayed
 * 		* divs should contain content that will be displayed when the icon is clicked
 *					
 * 				<div class="text"></div>
 *				<div id="carouselText">
 *					<div>customize this space for icon 1</div>
 *					<div>customize this space for icon 2</div>
 *					<div>customize this space for icon 3</div>
 *					<div>customize this space for icon 4</div>
 *				</div>
 *
 *
 * 				
 *
 */
jQuery.easing.def = "easeInOutQuint";
(function($) {

	$.fn.extend({
		
		carousel3d: function(options) {

				opt = $.extend({},$.carouselSetup.defaults, options);		              // extend options
				
				$this = $(this);
				
				opt.speed = parseInt(6 - opt.speed);												
        contSpeed = btnSpeed * $.browser.msie ? 0 : 0;											// original continuous speed
        opt.speed = opt.speed * $.browser.msie ? 14500 : 13500;											// original mouse speed
				
				$imgs = $('img', $this).hide();											// set variable with carousel images; hide for now
				$texts = $('div', $('#carouselText')).hide();					// set variable with carousel text boxes; hide for now
				
				items = $imgs.size(); 														// number of icons in carousel
				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
				
				if (opt.padding == 0) opt.padding = 1;								// padding must be at least 1
				
				$imgs.each(function(i) { new $.imageSetUp(this, i) });	// setup images
				new $.carouselSetup();													// setup carousel        
        
    }
	});
    
	$.imageSetUp = function(im, _index) {
		
		im.orig_w = $(im).width(), im.orig_h = $(im).height();				// save the original dimensions; used when image is clicked
		
		var w_h = resize( im.orig_w, 230, im.orig_h, 152).split('|');		// calculate w/h of images in carousel
		im.h = w_h[1], im.w = w_h[0];
		
    im.slot = _index * opt.padding;												// position of the image in the carousel
		im.angle = parseInt(( _index * opt.padding ) * (( Math.PI * 2 ) / numSlots )*1000)/1000;		// original angle of the image
		
		im.clicked = { 																				// css to animate when image is clicked
			top: parseInt(opt.centerY - im.orig_h/3) + 'px',
			left: parseInt(opt.centerX - im.orig_w/3) + 'px',
			width: im.orig_w + 'px',
			height: im.orig_h + 'px'
		};
		im.animateOn = function(el) { $imgs.fadeOut(700); el.animate( im.clicked, 500 ) }; 	// hide the carousel
		
		new $.TextBoxSetUp(im, _index);											// setup text box
		
		$(im).attr('id', 'pix'+_index).css({position: 'absolute'});				// id will be referenced when moving the image
			
		$(im).one('click', clickOn);												// bind clickOn to image
		
	};
	
  $.TextBoxSetUp = function(im, _index) {
    im.textClicked = {																			// css to animate when image is clicked
			left: opt.centerX + 228 - opt.radiusX - im.w + 'px',  //image position 
			top: opt.centerY + 'px',
			width: im.w + 'px',
			height: im.h + 'px',
      opacity: 1
		};
		im.textBoxCss = {																			// textBox positioning css 
			top: opt.centerY - 28 + 'px',
			left: opt.centerX - 86 + 'px'
		};
		im.textAnimateOn = function(el) {
			$imgs.fadeOut(350);
			el.animate( im.textClicked, 800 );
			$('#text').css( im.textBoxCss ).html( $texts.eq(_index).html() ).fadeIn(400);
		};
		
	};  
	
	function Decay() {
		var tmdelay = 0;
		for (idecays=1; idecays <= 7; idecays++)	{
			idecay = (((idecays - 7) / 1000) * -1);
				tmdelay = idecays * 100;
			$('#carousel').delay(tmdelay).show(10, function() {
					rate = idecay;
			});
		}
	}
	
	$.carouselSetup = function() {
	
		var im, _t, _s;
		
		$('#carousel').mousemove(function(e) { rate = ((e.pageX - opt.centerX) / opt.speed);  }).mouseout(function(e){ rate = 0; });
		//$('#carousel').mousemove(function(e) { rate = ((e.pageX - opt.centerX) / opt.speed);  }).mouseout(function(e){ Decay(); });
		
		// javascript Motion Tween by PHILIPPE MAEGERMAN; very similar to tweening in Flash.
		// check out the full details at his site: http://jstween.blogspot.com/
		t1 = new Tween(new Object(), 'xyz', Tween.regularEaseInOut, 0, 10000, 10000);
            
		t1.onMotionChanged = function(event) {
			for (var j=0; j<items, im=$('#pix'+j)[0]; j++) {
				
				im.slot = (im.slot == numSlots - 1) ? 0: im.slot++;			// if image is in last slot, set as first slot; else advance 1 slot
				_t = Math.sin(im.angle) * opt.radiusY + opt.centerY;		// calculate top positioning
				_s = ((_t - opt.perspective) / (opt.centerY + opt.radiusY - opt.perspective));	// calculate size of image based on position in carsousel
				
				$(im).css({ 																		// set css values for image
					top: _t, 
					left: Math.cos(im.angle) * opt.radiusX + opt.centerX, 	// calculate left positioning
					width: im.w * _s, 															// multiply image size by newly calculated size
					height: im.h * _s, 
					zIndex: Math.round(_t)-50,										// z-index makes front images fully visible
					opacity: Math.sin(im.angle)+1.4 });	// if fadeEffect is set, calculate opacity based on location in carousel
				
				if (opt.fadeEffect == 1) {
					$(im)[ Math.sin(im.angle)<=0 ? 'hide' : !$(im).is(':visible') ? 'show' : ''  ];
				}
				
				im.angle += rate;			// change image angle based on carousel speed
      }
    };
       	
       	t1.start();																					// start the motion
       	$imgs.show();																// show the images
  };
       
  var opt, numSlots, items, rate = contSpeed = btnSpeed = 0;		// initialize variables

	function clickOn() {																		// actions when image in carousel is clicked
		t1.stop(); 																					// stop the Tween motion
		var elem = this;
			
		$cloned = 																				// clone the image clicked and leave the original in place (this seemed easier than pulling the orig out of place)
		$(this).clone().prependTo($this).click(function() { 					// add to carousel, when clicked again . . .	
			$imgs.fadeIn(400);																	// show the carousel images
			$(this)																					// animate back to carousel slot
				.attr('class', 'clicky')
        .animate({
				
					left: $(elem).offset().left + 'px', 									// change position
					top: $(elem).offset().top + 'px', 
					width: $(elem).width() + 'px', 										//  and size
					height: $(elem).height() + 'px' 
             	}, function() {	
					$(this).remove();															// remove the cloned image, 
            		$(elem).one('click', clickOn);										// rebind the image click event,
            		t1.start();																		// and restart carousel 
          		});
          	$('#text:visible').fadeOut(400);													// if showing, hide the text box
       	});
       	
       	elem.textAnimateOn($cloned);			// animate the clone; position to side of text box
  };
	
	function resize(w, max_w, h, max_h) {										// resize the images
		if (w>max_w || h>max_h) {
			var x_ratio = max_w / w;
			var y_ratio = max_h / h;
			if ((x_ratio * h) < max_h) return max_w + '|' + Math.ceil(x_ratio * h);
			else return Math.ceil(y_ratio * w) + '|' + max_h;
		}
		else return w + '|' + h;
	};
	
	function resetAnimations() {														// clicked images and text boxes must be repositioned after resizing screen
    var carousel = $('#carousel').offset();
    var TextOffset = carousel.left + 280;
    var ImageOffset = carousel.left + 24;
		$('#text').css('left','' + TextOffset + 'px');
		$imgs.each(function(i) {
      $('.clicky').css('left','' + ImageOffset + 'px');
		});
	};
	
  $(window).resize(function() {
    var carousel = $('#carousel').offset();
		opt.centerX = carousel.left + 362;
		resetAnimations();
	});

    $.carouselSetup.defaults = {	
        control: 'mouse',	  															// 'button', 'mouse', or  'continuous' control
        speed: 0,																					// speed of mouse or button.  use scale of 1-5
        radiusX: 340,																			// x radius of the carousel
        radiusY: 28,																			// y radius of the carousel
        centerX: 0,																				// x position on the screen
        centerY: 190,																			// y position on the screen
        perspective: 120,																	// perspective of the image 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
        fadeEffect: 1,																		// fade icons as cycle to the back of the carousel
        textBox: 1																				//  1 = display text area for each icon, 0 = no display
    };

})(jQuery);
