/*
 * Create a 3D carousel similar to the popular Flash carousel
 *
 * @name		carousel3d
 * @author		Kevin Crossman
 * @contact		kevincrossman@gmail.com
 * @version		1.0
 * @date			Sep 10 2008
 * @type    	 	jQuery
 * @example
 *
 *
 */
(function($) {

	var opt;

    $.fn.carousel3d = function(options) {

        return this.each(function() {

           	opt = $.extend({},$.fn.carousel3d.defaults, options);

            $this = $(this); // $this = #carousel
            $imgs = $('.imgCont', $this).hide(); // $imgs = images in #carousel
            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 w_h = [], w_h_i = [];
            $o = {};


			function getDimensions() {
                w_h_i = resize(this.width, 150, this.height, 150);
				var layout = (w_h_i[0] >= w_h_i[1]);
        		if(layout) {
        			this._me.css({ width: 'auto', height: '100%' });
        		} else {
        			this._me.css({ width: '100%', height: 'auto' });
        		}
			};

            if (opt.padding == 0) opt.padding = 1;

			$(window).resize(function(){
			  opt.centerX = ($(window).width()/2)-65;
			});

            // assign inital values to images;
            $imgs.each(function(i){
				var imgLoad = new Image();
				imgLoad._pi = i;
				imgLoad._me = $(this).children('img');
				imgLoad.onload = getDimensions;
				imgLoad.src = $(this).children('img').attr('src');

				w_h = resize($(this).width(), 150, $(this).height(), 150);

				this._img = $(this);
				this._h = w_h[1];
				this._w = w_h[0];
				this.slot = i * opt.padding;
				this.angle = ((i * opt.padding) * ((Math.PI * 2) / numSlots));
				//this.subimg = {_img: $(this).children('img')};

				this.onAnimate = {
				        top: opt.centerY - $(this).height()/3 + 'px',
				        left: opt.centerX - $(this).width()/3 + 'px',
				        width: $(this).width() + 'px',
				        height: $(this).height() + 'px'  };

				$o[i] = this;
				$(this).addClass('pix' + i).css({position: 'absolute'});
            });

            // setup tooltip for images
             $imgs.one('click', clickOn);

            controls();

            // 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; j++) {
                    $o[j].slot = ($o[j].slot == numSlots - 1) ? 0 : $o[j].slot + 1;

                    var _t = Math.sin($o[j].angle) * opt.radiusY + opt.centerY;
                    var _l = Math.cos($o[j].angle) * opt.radiusX + opt.centerX;
                    var _s = ((_t - opt.perspective) / (opt.centerY + opt.radiusY - opt.perspective));

                    $o[j].angle += opt.speed/3;

                    $o[j]._img.css({ top: _t, left: _l, width: $o[j]._w * _s, height: $o[j]._h * _s, zIndex: Math.round(_t)+100 });
                }
            };
            t1.start();
            $imgs.fadeIn(500);
        });
    };

	function resize(w, max_w, h, max_h) {
		// return w|h
		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 controls() {	// add or remove mouse/button functions
        if (opt.control=='buttons') {
        	opt.speed=0;
     		$('body')
            	.append($('<div id="buttonwrapper"></div>').css({ left: opt.centerX+'px', top: opt.centerY+200*1+'px'})
           		.append(
       				$('<div id="left"></div>')
        				.mouseover(function() { opt.speed = ($.browser.msie) ? .05 : .15 })
            			.mouseout(function() { opt.speed = 0 }),
           			$('<div id="right"></div>')
          				.mouseover(function() { opt.speed = ($.browser.msie) ? -.05 : -.15 })
      					.mouseout(function() { opt.speed = 0 })
   				));
		}	else {
			$('body').mousemove(function(e) {
		          //opt.speed = (!jQuery.support.leadingWhitespace) ? (e.pageX - opt.centerX) / opt.velocity : (e.pageX - opt.centerX) / (opt.velocity / 2);
		          opt.speed = (e.pageX - opt.centerX) / (opt.velocity / 2);
		    });
		}
    }

	// set up actions to reset carousel when image is clicked again
	function clickOff(obj, obj2, lft, tp) {	// set up actions to reset carousel when image is clicked again

		obj.click(function() {
         	// show the carousel images and remove text
            $imgs.fadeIn(1500);

             // animate back to carousel position, changing location and size
            $(this).animate({ left: lft, top: tp, width: obj2.width() + 'px', height: obj2.height() + 'px' }, 1000,
				function() {
					$(this).remove();					//remove the cloned image,
            		$imgs.one('click', clickOn);	//rebind the img click events and start carousel,
            		t1.start();								//restart carousel
          	});
        });
	};

	function clickOn() {	// actions when image in carousel is clicked

		$ths = this;

		if ($(this).children('img').hasClass('link')) {
			window.open($(this).children('img').attr('id'));
		} else {
			$imgs.fadeOut(500);
			t1.stop(); // stop the Tween motion
			// clone 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
			/*
			$cloned = $(this).clone().prependTo($this).css('border', '4px solid #ddd').animate($ths.onAnimate,300);
			//$cloned = $(this).html('<img src="' + imgURL + '" />').prependTo($this).css('border', '4px solid #ddd').animate($ths.onAnimate,300);

			$imgs.fadeOut(500); // hide the carousel

			clickOff($cloned, $(this), $(this).position().left + 'px', $(this).position().top + 'px');
			*/
			imgURL = $(this).children('img').attr("ref");
			imgCAP = $(this).children('img').attr("title");
			$.slimbox(imgURL, imgCAP);
        }
    };
    // plugin defaults
    $.fn.carousel3d.defaults = {
        control: 'mouse',
        //  1 = mouse controls movement, 0 = buttons control movement
        //speed: ($.browser.msie) ? 0.0005 : 0.0001,
        speed: 0.0002,
        // x radius of the carousel
        radiusX: 400,
        // x radius of the carousel
        radiusY: 40,
        // y radius of the carousel
        centerX: ($(window).width()/2)-65,
        // x position on the screen
        centerY: 230,
        // y position on the screen
        perspective: 120,
        // 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
        velocity: 150000
        // the velocity at which the carosel will spin after a mouseover has happened. The higher the value the slower it goes.
    };

})(jQuery);
