/**
* Interface Elements for jQuery
* 3D Carousel
*
* http://interface.eyecon.ro
*
* Copyright (c) 2006 Stefan Petre
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
*/
/**
* Created a 3D Carousel from a list of images, with reflections and animated by mouse position
*
* @example window.onload =
*			function()
*			{
*				$('#carousel').Carousel(
*					{
*						itemWidth: 110,
*						itemHeight: 62,
*						itemMinWidth: 50,
*						items: 'a',
*						reflections: .5,
*						rotationSpeed: 1.8
*					}
*				);
*			}
* HTML
*			<div id="carousel">
*				<a href="" title=""><img src="" width="100%" /></a>
*				<a href="" title=""><img src="" width="100%" /></a>
*				<a href="" title=""><img src="" width="100%" /></a>
*				<a href="" title=""><img src="" width="100%" /></a>
*				<a href="" title=""><img src="" width="100%" /></a>
*			</div>
* CSS
*			#carousel
*			{
*				width: 700px;
*				height: 150px;
*				background-color: #111;
*				position: absolute;
*				top: 200px;
*				left: 100px;
*			}
*			#carousel a
*			{
*				position: absolute;
*				width: 110px;
*			}
*
* @desc Creates a 3D carousel from all images inside div tag with id 'carousel'
*
*
* @name 3D Carousel
* @description Created a 3D Carousel from a list of images, with reflections and animated by mouse position
* @param Hash hash A hash of parameters
* @option String items items selection
* @option Integer itemWidth the max width for each item
* @option Integer itemHeight the max height for each item
* @option Integer itemMinWidth the minimum width for each item, the height is automaticaly calculated to keep proportions
* @option Float rotationSpeed the speed for rotation animation
* @option Float reflectionSize the reflection size a fraction from items' height
*
* @type jQuery
* @cat Plugins/Interface
* @author Stefan Petre
*/
jQuery.iCarousel = {

	build : function(options)
	{
		return this.each(
		function()
		{
			var el = this;
			var increment = 2*Math.PI/360;
			var maxRotation = 2*Math.PI;
			if(jQuery(el).css('position') != 'relative' && jQuery(el).css('position') != 'absolute') {
				jQuery(el).css('position', 'relative');
			}
			el.carouselCfg = {
				items : jQuery(options.items, this),
				itemWidth : options.itemWidth,
				itemHeight : options.itemHeight,
				itemMinWidth : options.itemMinWidth,
				maxRotation : maxRotation,
				size : jQuery.iUtil.getSize(this),
				position : jQuery.iUtil.getPosition(this),
				start : Math.PI/2,
				rotationSpeed : options.rotationSpeed,
				reflectionSize : options.reflections,
				reflections : [],
				protectRotation : false,
				increment: 2*Math.PI/360
			};
			el.carouselCfg.radiusX = (el.carouselCfg.size.w - el.carouselCfg.itemWidth)/2;
			el.carouselCfg.radiusY =  (el.carouselCfg.size.h - el.carouselCfg.itemHeight - el.carouselCfg.itemHeight * el.carouselCfg.reflectionSize)/2;
			el.carouselCfg.step =  2*Math.PI/el.carouselCfg.items.size();
			el.carouselCfg.paddingX = el.carouselCfg.size.w/2;
			el.carouselCfg.paddingY = el.carouselCfg.size.h/2 - el.carouselCfg.itemHeight * el.carouselCfg.reflectionSize;
			var reflexions = document.createElement('div');
			jQuery(reflexions)
			.css(
			{
				position: 'absolute',
				zIndex: 1,
				top: 0,
				left: 0
			}
			);
			jQuery(el).append(reflexions);
			el.carouselCfg.items
			.each(
			function(nr)
			{
				image = jQuery('img', this).get(0);
				height = parseInt(el.carouselCfg.itemHeight*el.carouselCfg.reflectionSize);
				if (jQuery.browser.msie) {
					canvas = document.createElement('img');
					jQuery(canvas).css('position', 'absolute');
					canvas.src = image.src;
					canvas.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity=60, style=1, finishOpacity=0, startx=0, starty=0, finishx=0)';

				} else {
					canvas = document.createElement('canvas');
					if (canvas.getContext) {
						context = canvas.getContext("2d");
						canvas.style.position = 'absolute';
						canvas.style.height = height +'px';
						canvas.style.width = el.carouselCfg.itemWidth+'px';
						canvas.height = height;
						canvas.width = el.carouselCfg.itemWidth;
						context.save();

						context.translate(0,height);
						context.scale(1,-1);

						context.drawImage(
						image,
						0,
						0,
						el.carouselCfg.itemWidth,
						height
						);

						context.restore();

						context.globalCompositeOperation = "destination-out";
						var gradient = context.createLinearGradient(
						0,
						0,
						0,
						height
						);

						gradient.addColorStop(1, "rgba(255, 255, 255, 1)");
						gradient.addColorStop(0, "rgba(255, 255, 255, 0.6)");

						context.fillStyle = gradient;
						if (navigator.appVersion.indexOf('WebKit') != -1) {
							context.fill();
						} else {
							context.fillRect(
							0,
							0,
							el.carouselCfg.itemWidth,
							height
							);
						}
					}
				}

				el.carouselCfg.reflections[nr] = canvas;
				jQuery(reflexions).append(canvas);
			}
			)
			.bind(
			'mouseover',
			function(e)
			{
				el.carouselCfg.protectRotation = true;
				el.carouselCfg.speed = el.carouselCfg.increment*0.1 * el.carouselCfg.speed / Math.abs(el.carouselCfg.speed);
				return false;
			}
			)
			.bind(
			'mouseout',
			function(e)
			{
				el.carouselCfg.protectRotation = false;
				return false;
			}
			);
			jQuery.iCarousel.positionItems(el);
			el.carouselCfg.speed = el.carouselCfg.increment*0.2;
			el.carouselCfg.rotationTimer = window.setInterval(
			function()
			{
				el.carouselCfg.start += el.carouselCfg.speed;
				if (el.carouselCfg.start > maxRotation)
				el.carouselCfg.start = 0;
				jQuery.iCarousel.positionItems(el);
			},
			20
			);
			jQuery(el)
			.bind(
			'mouseout',
			function()
			{
				el.carouselCfg.speed = el.carouselCfg.increment*0.2 * el.carouselCfg.speed / Math.abs(el.carouselCfg.speed);
			}
			)
			.bind(
			'mousemove',
			function(e)
			{
				if (el.carouselCfg.protectRotation == false) {
					pointer = jQuery.iUtil.getPointer(e);
					mousex =  el.carouselCfg.size.w - pointer.x + el.carouselCfg.position.x;
					el.carouselCfg.speed = el.carouselCfg.rotationSpeed * el.carouselCfg.increment * (el.carouselCfg.size.w/2 - mousex) / (el.carouselCfg.size.w/2);
				}
			}
			);
		}
		);
	},

	positionItems : function(el)
	{
		el.carouselCfg.items.each(
		function (nr)
		{
			angle = el.carouselCfg.start+nr*el.carouselCfg.step;
			x = el.carouselCfg.radiusX*Math.cos(angle);
			y = el.carouselCfg.radiusY*Math.sin(angle) ;
			itemZIndex = parseInt(100*(el.carouselCfg.radiusY+y)/(2*el.carouselCfg.radiusY));
			parte = (el.carouselCfg.radiusY+y)/(2*el.carouselCfg.radiusY);

			width = parseInt((el.carouselCfg.itemWidth - el.carouselCfg.itemMinWidth) * parte + el.carouselCfg.itemMinWidth);
			height = parseInt(width * el.carouselCfg.itemHeight / el.carouselCfg.itemWidth);
			this.style.top = el.carouselCfg.paddingY + y - height/2 + "px";
			this.style.left = el.carouselCfg.paddingX + x - width/2 + "px";
			this.style.width = width + "px";
			this.style.height = height + "px";
			this.style.zIndex = itemZIndex;
			el.carouselCfg.reflections[nr].style.top = parseInt(el.carouselCfg.paddingY + y + height - 1 - height/2) + "px";
			el.carouselCfg.reflections[nr].style.left = parseInt(el.carouselCfg.paddingX + x - width/2) + "px";
			el.carouselCfg.reflections[nr].style.width = width + "px";
			el.carouselCfg.reflections[nr].style.height = parseInt(height * el.carouselCfg.reflectionSize) + "px";
		}
		);
	}
};
jQuery.fn.Carousel = jQuery.iCarousel.build;
