/*
 * 3D carousel navigation, inspired by Kevin Crossman's jquery plugin carousel3d (version 0.3) - contact: kevincrossman@gmail.com
 *
 * @name		nav 3D carousel
 * @author		Miran Melansek
 * @contact		melansek@bonmedia.de
 * @version		0.1
 * @date		August 30 2008
 * @type    	jQuery
 * @example  
 *
 */
 
var last_mouse_x = 0; 
var last_mouse_y = 0;
var last_speed = 0; // current speed of the navigation carousel
var target_speed = 0; // current target speed of the navigation carousel
 
(function($) {

    $.fn.nav3Dcarousel = function(options) {

        var opt = $.extend({}, $.fn.nav3Dcarousel.defaults, options);
		var n3Dc_running = false;
		
		return this.each(function() {
        
            $this = $(this);  // #nav_carousel
            $imgs = $('img', $this).hide();  // $imgs = images in #carousel
            
            var items = $this.children('a').size();  // items = the number of visible images circling the carousel
			
			// handle clicks on nav_buttons
			
			
			if (opt.padding==0) 
			{
				opt.padding=10;
			}
			
			var numSlots = items * opt.padding; 
			var speed = 0;
			 
            $o = new Array();
			$c = new Array();
			l = new Array();  // left positions of each slot
            t = new Array();  // top positions of each slot
            s = new Array();  // sizes of each slot (sizes vary to create depth)
            d = new Array();  // each image
           
			$().mousemove(function(e){
								   
					last_mouse_x = e.pageX;
					last_mouse_y = e.pageY;
					if(Math.abs( last_mouse_x - Math.floor(opt.width / 2) - opt.centerX) < (opt.radiusX ) && Math.abs( last_mouse_y - (opt.centerY + Math.floor(opt.height / 2))) < (opt.radiusY * 3))
					{
						target_speed = (last_mouse_x - opt.centerX -  Math.floor(opt.width / 2)*0.4) / Math.abs(opt.damping);
						if(!n3Dc_running)
						{
							startCarousel();
						}
					}
					else
					{
						target_speed = 0;
					}
   			}); 
   			
			// function for actions when image in carousel is clicked
			function clickOn() {

				return true;
  			}; 
			
			// calulate the data for each slot in the carousel; 
			// data is assigned to images as they rotate around the carousel
            for (var j = 0; j < numSlots; j++) {
                var angle = j * ((Math.PI * 2) / numSlots);
                t[j] = Math.sin(angle) * opt.radiusY + opt.centerY;
                s[j] = ((t[j] - opt.perspective) / (opt.centerY + opt.radiusY - opt.perspective)) ;
				l[j] = Math.cos(angle)  * opt.radiusX * (t[j] / (opt.centerY + opt.radiusY)) + opt.centerX;
                
				//$("body").append('<div style="position: absolute; background-color: #FF0000; top:'+t[j]+'px; left:'+l[j]+'px; width:5px; height:5px; z-index:1000"></div>');
            }
			
            $imgs.each(function(i)  {
            	
				var n = i*opt.padding + 4; // cosmetic
				if(n >=  numSlots)
				{
					n = n - numSlots;
				}
				
				var _href = $(this).parent("a").attr("href");
				var _title = $(this).attr('alt');
				$("#nav_carousel").append('<a id="nav_caption' + i + '" class="caption_text" href="' + _href + '">' + _title.replace("\n", "<br />") + '</a>');
				$(this).attr({
							 'alt': '',
							 'title': '',
							 'link': $(this).parent("a").attr("href")
						}).css('cursor', 'pointer');
			
				// object holder for captions
				$c[i] = new Object();
				$c[i]._obj = $("#nav_caption" + i);
				$c[i]._height = $c[i]._obj.height();
				$c[i]._width = $c[i]._obj.width();
				
				// object holder for images
				$o[i] = new Object();
                $o[i]._img = $(this);
                $o[i]._h = opt.height ? opt.height : $(this).height();
                $o[i]._w = opt.width ? opt.width : $(this).width();
                $o[i]._slot = n;
                $o[i]._angle = (n) * ((Math.PI*2)/numSlots);
				//$("#content").append(i + ': ' + $o[i]._angle + 'slot: ' + n + ' pi: ' + Math.PI*2 + ' numSlots: ' + numSlots + '<br />');
                
				$(this).addClass('orig' + (n)).attr({
                    name: n
                }).css({
                    position: 'absolute',
                    top: t[n] + 'px',
                    left: l[n] + 'px',
                    width: Math.round($o[i]._w * s[n]) + 'px',
                    height: Math.round($o[i]._h * s[n]) + 'px',
					"z-index": Math.floor(t[n])
                }).show();
				
				if(!is_ie)
				{
					$(this).css({
					filter:	"alpha(opacity="+(s[n]*100)+")", 
					"-moz-opacity":s[n],
					opacity: s[n]
					});
				}
				
				
				var _opacity = s[n] * s[n] * s[n] ;
				var _colorval = Math.floor(_opacity * 255 * (((t[n] > opt.centerY ) ? 1 : 0.7)));
	
				$c[i]._obj.css({	
					top: Math.round(t[n] + ((t[n] > opt.centerY ) ? $o[i]._h * s[n] / 2 + 21 : -1 * ($c[i]._height + 5))) + 'px',
					left: Math.round(l[n] - (($c[i]._width - $o[i]._w * s[n])/2)) + 'px',
					"z-index": Math.floor(t[n]),
					color: 'rgb('+_colorval+','+_colorval+','+_colorval+')',
					visibility: 'visible'
				});
				
            });
		    
			$imgs.show();
   
			// function that starts the carousel rotation
            var startCarousel = function() {

				n3Dc_running = true;
				
				// function that runs the carousel rotation 
				// uses jquery.timers plugin
                $this.everyTime(opt.timer, 'carouselTimer',
                function() {
					
					var _elasticity = Math.abs(target_speed - last_speed) < (opt.elasticity) ? opt.elasticity / 10 : opt.elasticity;

					speed = last_speed + (_elasticity * (target_speed < last_speed ? -1 : 1));
					
					if(Math.abs(speed) < (_elasticity) && Math.abs(target_speed - last_speed) < (_elasticity))
					{
						speed = 0;
					}
					
					last_speed = speed;
					
					if(speed == 0) // stop timer
					{
						n3Dc_running = false;
						$this.stopTime('carouselTimer');
						return true;
					}
					
					var steps = Math.floor(speed*400);
					
					

                    $imgs.each(function(i) {
						
						var n = parseInt(this.name);
                        if (steps > 0 && (n + steps) >= numSlots) 
						{
							n = n - numSlots;
						}
						else if (steps < 0 && (n + steps) < 0) 
						{
							n = n + numSlots;
						}
                        
						this.name = 1 * (n + steps);
						
						if(i==0)
						{
							$("#speed").html('slot: ' + this.name + ' steps: ' + steps);// + ' left: '+l[n]+' top: '+t[n]+' faktor: '+s[n]);	
						}
												
						// reassign the positions
                        var n = parseInt(this.name);
                        $(this).css({
                            left: Math.round(l[n]) + 'px',
                            top: Math.round(t[n]) + 'px',
							width: Math.round($o[i]._w * s[n]) + 'px',
                    		height: Math.round($o[i]._h * s[n]) + 'px',
							"z-index": Math.floor(t[n])});
						
						// IE7: CSS transparency is problematic, if used with PNGs having transparent parts
						if(!is_ie)
						{
							$(this).css({
							filter:	"alpha(opacity="+(s[n]*100)+")", 
							"-moz-opacity":s[n],
							opacity: s[n]
							});
						}
						
						var _opacity = s[n] * s[n] * s[n] ;
						var _colorval = Math.floor(_opacity * 255 * (((t[n] > opt.centerY ) ? 1 : 0.7)));
	
						$c[i]._obj.css({	
							top: Math.round(t[n] + ((t[n] > opt.centerY ) ? $o[i]._h * s[n] / 2 + 21  : -1 * ($c[i]._height + 5))) + 'px',
//							top: t[n] + ((t[n] > opt.centerY ) ? Math.round(($o[i]._h - 70)* s[n])  : -1 * ($c[i]._height + 5)) + 'px',
							left: Math.floor(l[n] - (($c[i]._width - $o[i]._w * s[n])/2)) + 'px',
							"z-index": Math.floor(t[n]),
							color: 'rgb('+_colorval+','+_colorval+','+_colorval+')'
							
						});
                    });
                });
            };
			
			//startCarousel();
			
			var nav_button_click = function(dir) {
				last_speed = dir * 104 / Math.abs(opt.damping);
				
						if(!n3Dc_running)
						{
							startCarousel();
						}
				
			};
			
			$("#nav_button_left").css("cursor","pointer").mousedown(function(){ 
				nav_button_click(5.0)
				$(this).attr("src", root_path + "img/e/basic/c_button_left_md.png");
				}).mouseover(function(){ 
				$(this).attr("src", root_path + "img/e/basic/c_button_left_mo.png");
				}).mouseup(function(){ 
				$(this).attr("src", root_path + "img/e/basic/c_button_left.png");
				}).mouseout(function(){ 
				$(this).attr("src", root_path + "img/e/basic/c_button_left.png");
				});
			
			$("#nav_button_right").css("cursor","pointer").mousedown(function(){ 
				nav_button_click(-3.95)
				$(this).attr("src", root_path + "img/e/basic/c_button_right_md.png");
				}).mouseover(function(){ 
				$(this).attr("src", root_path + "img/e/basic/c_button_right_mo.png");
				}).mouseup(function(){ 
				$(this).attr("src", root_path + "img/e/basic/c_button_right.png");
				}).mouseout(function(){ 
				$(this).attr("src", root_path + "img/e/basic/c_button_right.png");
				});
			
			// trigger_nav_button_click is set for first pageview in session 
			if(trigger_nav_button_click)
			{
				nav_button_click(6.779);
			}
			
        });
    };

	// plugin defaults
	$.fn.nav3Dcarousel.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: 450,  // x position on the screen
    	centerY: 350,  // 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
		height: 100,
		width: 100,
		damping: 8000,
		elasticity: 0.0002,
		timer: '1ms'
	};
})(jQuery);
