/*
 * jQuery Carousel Plugin
 * version: 2.0.3 (2011/12/12)
 * Author: Emanuele Tortolone
 * http://www.fillstudio.com
 
 Usage:
	$('__ELEMENT__').carousel(
	{
		dataArray:__somedata__,
		linkPosition : 'bottom',
		removeLinks : false,
		autoPlay : true,
		transitionType : 'alpha',
		shuffle : false,
		showPrevNext : false,
		slideShowTime:7000,
		delayBetweenTransitions:500,
		easeIn:'easeInOutQuart',
		easeInTime:1500,
		easeOut:'easeInOutQuart',
		easeOutTime:900,
		useArrowKeys:true
	});
	
	//	EVENT HANDLERS
	$('__ELEMENT__').bind('LOADING', function(event){});
	$('__ELEMENT__').bind('LOAD_COMPLETE', function(event){});
	$('__ELEMENT__').bind('NEW_IMAGE', function(event, [current_id, total_image]){});
*/

(function( $ ){
	function Carousel(element, opts){
		this.defaults = {
				dataArray:null,
				image_width : 0,
				image_height : 0,
				linkPosition : 'bottom',
				removeLinks : false,
				autoPlay : true,
				transitionType : 'horizontal',
				shuffle : false,
				showPrevNext : false,
				slideShowTime : 5000,
				delayBetweenTransitions : 0,
				easeIn : 'easeInOutQuart',
				easeInTime : 1500,
				easeOut : 'easeInOutQuart',
				easeOutTime : 1200,
				useArrowKeys : false
		};
		
		this.options = $.extend(this.defaults, opts);
		this.instance = $(element);
		this.loading = null;
		this.imagesContainer = null;
		this.itemContainer = null;
		this.loadedImagesContainer = null;
		this.previousBtn = null;
		this.nextBtn = null;
		this.imgArray = new Array(); 
		this.linkArray = new Array(); 
		this.width = this.instance.css('width');
		this.height = this.instance.css('height');
		this.left = 'left';
		this.right = 'right';
		this.up = 'up';
		this.down = 'down';
		this.direction = null;
		this.counter = 0;
		this.oldCounter = 0;
		this.newImage = null;
		this.oldImage = null;
		this.timer = null;
		this.itemSelected = null;
		this.canLoadAnother = null;
		this.timer = null;
		this.IE = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
		this.IEversion = this.IE ? (new Number(RegExp.$1)) : null;
		this.IEminversion = 7;
	};
	
	Carousel.prototype = {
			init : function(){
					this.direction = (this.options['transitionType'] == 'horizontal') ? this.right : this.down;
					this.initialized = true;
					this.createWrappers();
					this.checkTransitionsTime();
					this.createLoading();
					this.setDefaultStyle();
					this.initImgArray();
					this.initPrevNextBtn();
					this.checkImageLoaded();
					this.initArrowKeys();
			},
			
			initArrowKeys : function(){
				var $this = this;
				if(this.options['useArrowKeys'] == true)
				{
					$(document).unbind("keydown").bind("keydown", function(event){
						 if (event.keyCode == '37') {
							 $this.prevImage();
						 }else if  (event.keyCode == '39') {
							 $this.nextImage();
						 }
						 event.preventDefault(); 
					});
				}
			},
			
			createWrappers : function(){
				if(this.options['linkPosition'] == 'bottom'){
					this.instance.append("<div class='carousel_images_container'></div>");
					this.instance.append("<div class='carousel_item_container'></div>");
				}else{
					this.instance.append("<div class='carousel_item_container'></div>");
					this.instance.append("<div class='carousel_images_container'></div>");
				}
				this.itemContainer = $('.carousel_item_container', this.instance);
				this.imagesContainer = $('.carousel_images_container', this.instance);
				
				this.instance.append("<div class='carousel_loaded_images_container'></div>");
				this.loadedImagesContainer = $('.carousel_loaded_images_container', this.instance);
				this.loadedImagesContainer.css({'display':'none'});
			},
			
			createLoading : function(){
				this.instance.append("<div class='carousel_loading'></div>");	
				this.loading = $('.carousel_loading', this.instance);
				this.loading.hide();
			},
			
			setDefaultStyle : function(){
				//	CONTAINER
				this.instance.css({
					'position': 'relative',
					'overflow':'hidden'
				});
				
				//	LOADING
				$(this.loading).html('<span>Loading...</span>');
				$(this.loading).css({
					'z-index':'5',
					'position':'absolute'
				});
				
				//	IMAGES CONTAINER
				$(this.imagesContainer).css({
					'width': (this.options['image_width'] > 0) ? String(this.options['image_width'] + "px") :  String(this.width),
					'height': (this.options['image_height'] > 0) ? String(this.options['image_height'] + "px") :  String(this.height)
				});
			},
			
			initImgArray : function(){
				if(this.options['dataArray'] === null){
					var dummyLinkArray = $('a', this.instance);
					for (i = 0; i < dummyLinkArray.length; i++){
						this.imgArray.push($(dummyLinkArray[i]).attr('href'));
						
						$(dummyLinkArray[i]).attr('rel', i);
						$(dummyLinkArray[i]).bind('click', {instance:this}, this.changeImage);
						$(dummyLinkArray[i]).attr('href', 'javascript:void(0);');
						
						$(this.itemContainer).append(dummyLinkArray[i]);
						
						var link = $(dummyLinkArray[i]).attr('title')
						if(link != undefined && link.length > 0){
							link = link.replace(/^\s*/, "").replace(/\s*$/, "");
							this.linkArray.push(link);
						}
					}
				}
				else
				{
					this.imgArray = this.getSingleDataArray('immagine');
					for (var i = 0; i < this.imgArray.length; i++){
						
						$(this.itemContainer).append('<a></a>');
						
						var links = $('a', this.itemContainer);
						for(var k = 0; k < links.length; k++){
							$(links[k]).attr('href', 'javascript:void(0);');
							$(links[k]).attr('rel', k);
							$(links[k]).bind('click', {instance:this}, this.changeImage);
						}
					}
					this.linkArray = links;
				}
				

				if(this.imgArray.length <= 1){
					this.options['autoPlay'] = false;
					this.options['showPrevNext'] = false;
					
					$('a', this.itemContainer).css({
						'display':'none'
					})
				}
				
				
				if(this.options['removeLinks'] == true){
					$('a',this.instance).remove();
				}
				
				
				if(this.options['shuffle'] == true){
					this.shuffleImgArray();
				}
			},
			
			shuffleImgArray : function(){
				for (var j = 0; j < this.imgArray.length; j++){
					var tmp = this.imgArray[j];
					var randomNum = Math.round(Math.random() * (this.imgArray.length-1));
					this.imgArray[j] = this.imgArray[randomNum];
					this.imgArray[randomNum] = tmp;
				}
				return this.imgArray; 
			},
			
			initPrevNextBtn : function(){
				if(this.options['showPrevNext'] == true)
				{
					this.createPreviousBtn();
					this.createNextBtn();
				}
			},
			
			createPreviousBtn : function()
			{
				var $this = this;
				this.instance.append("<div class='carousel_previous'></div>");
				this.previousBtn = $('.carousel_previous', this.instance);
				this.previousBtn.html('<span>Previous</span>');
				this.previousBtn.css({
					'margin':'0px',
					'padding':'0px',
					'position':'absolute',
					'cursor':'pointer',
					'z-index':'10'
				});
				
				if(this.imgArray.length > 1){
					this.previousBtn.bind('click',  {instance:this}, this.prevBtnHandler);
				}
			},
			
			createNextBtn : function()
			{
				var $this = this;
				this.instance.append("<div class='carousel_next'></div>");
				this.nextBtn = $('.carousel_next', this.instance);
				this.nextBtn.html('<span>Next</span>');
				this.nextBtn.css({
					'margin':'0',
					'padding':'0',
					'position':'absolute',
					'cursor':'pointer',
					'z-index':'10'
				});
				
				if(this.imgArray.length > 1){
					this.nextBtn.bind('click',  {instance:this}, this.nextBtnHandler);
				}
			},
			
			prevBtnHandler : function(event){
				var $this = event.data.instance;
				$this.prevImage();
			},
			
			nextBtnHandler : function(event){
				var $this = event.data.instance;
				$this.nextImage();
			},
			
			showLoading : function(){
				this.loading.fadeIn();
			},
			
			hideLoading : function(){
				this.loading.fadeOut();
			},
			
			nextImage : function(){
				if(this.canLoadAnother == true){
					if(this.hasNext()){
						this.counter++;
					}else{
						this.counter = 0;
					}
					
					this.direction = (this.options['transitionType'] == 'horizontal') ? this.right : this.down;
					this.checkImageLoaded();
				}
			},
						
			prevImage : function(){
				if(this.canLoadAnother == true){
					if(this.hasPrevious()){
						this.counter--;
					}
					else{
						this.counter = this.imgArray.length-1;
					}

					this.direction = (this.options['transitionType'] == 'horizontal') ? this.left : this.up;
					this.checkImageLoaded();
				}	
			},
			
			checkImageLoaded : function(){
				var imgUrl = this.imgArray[this.counter];
				if(imgUrl === undefined || imgUrl === ''){
					return;
				}
				
				//	CHROME NO CACHE
				if($.browser.webkit){
					this.loadImage();
					return;
				//	END CHROME NO CACHE
				}else{	
					if(this.loadedImagesContainer.children().length > 0){

						if($(String('#' + this.parseUrl(imgUrl)),  this.loadedImagesContainer).attr('id')){
							this.resetTimer();
							this.canLoadAnother = false;
							
							this.newImage = new Image();
							this.newImage.id = $(String('#' + this.parseUrl(imgUrl))).attr('id');
							this.newImage.rel = this.counter;
							
							this.newImage.src = $(String('#' + this.parseUrl(imgUrl))).attr('src');
							this.newImage.onload = null; 
	
							this.initNewImage();
						}else{
							this.loadImage();
						}	
					}else{
						this.loadImage();
					}
				}
			},
			
			changeImage:function(event){
				var $this = event.data.instance;
				if($this.canLoadAnother == true){
					$this.itemSelected = event.currentTarget;
					$this.counter = $(event.currentTarget).attr('rel');
					
					$this.checkDirection();
					$this.checkImageLoaded();
				}
			},
			
			loadImage:function(){
				var $this = this;
				this.resetTimer();
				this.canLoadAnother = false;
				
				this.instance.trigger('LOADING');
				this.showLoading();
				
				var loadUrl = String(this.imgArray[this.counter]);
				var urlNoCache = this.IE ? String("?" + Math.random() * Math.random()) : '';
				
				if(this.newImage != null) this.newImage = null;
				this.newImage = new Image();
				$(this.newImage).attr('id', this.parseUrl(loadUrl));
				$(this.newImage).attr('src', String(loadUrl + urlNoCache));
				$(this.newImage).attr('rel', this.counter);
				$(this.newImage).load(function(){
					$($this.newImage).clone().prependTo($this.loadedImagesContainer);
					
					$this.initNewImage();
					$this.hideLoading();
					$this.instance.trigger('LOAD_COMPLETE');
				});
			},

			initNewImage:function(){
				var currentContainerName = String('carousel_item_' + this.counter);
				$(this.imagesContainer).append("<div class=" + currentContainerName + "></div>");
				
				var currentContainer = $(String("."+currentContainerName), this.instance);
				
				$(currentContainer).css({
					'margin':'0px',
					'padding':'0px',
					'overflow':'hidden',
					'position':'absolute',
					'text-align':'center',
					'width': String($(this.imagesContainer).css('width')),
					'height': String($(this.imagesContainer).css('height')),
					'display':'block'
				});
					
				$(this.newImage).css({
					'position':'absolute',
					'left':String(Math.round($(currentContainer).width() - this.newImage.width)/2)+"px",
					'top':String(Math.round($(currentContainer).height() - this.newImage.height)/2)+"px",
					'display':'block'
				});

				if(this.linkArray[this.counter]){
					$(this.newImage).css({
						'cursor':'pointer'
					});
					
					$(this.newImage).bind('click', function(){
						document.location = this.linkArray[this.counter];
					});
				}
				
				$(currentContainer).append(this.newImage);
				this.showImage();
			},

			showImage : function()
			{
				var $this = this;
				var imageContainer = $(this.newImage).parent();
				var delayTime = (this.oldImage != null) ? this.options['delayBetweenTransitions'] : 0;
				if(this.options['transitionType'] == 'horizontal'){
					var startX;
					switch (this.direction){
						case this.right:
							startX = String(this.width);
						break;
						
						case this.left:
							startX = String("-" + this.width);
						break;
					}
					$(imageContainer).css("margin-left",startX);
					$(imageContainer).delay(delayTime).animate({"margin-left":"0px"}, this.options['easeInTime'], this.options['easeIn'], function(){
						$this.oldImage = $this.newImage;
						$this.canLoadAnother = true;
						$this.disableItem();
						$this.checkAutoPlay();
					});
				} else if(this.options['transitionType'] == 'vertical') {
					var startY;
					switch (this.direction){
						case this.down:
							startY = String(this.height);
						break;
						
						case this.up:
							startY = String("-" + this.height);
						break;
					}
					$(imageContainer).css("margin-top", startY);
					$(imageContainer).delay(delayTime).animate({"margin-top":"0px"}, this.options['easeInTime'], this.options['easeIn'], function(){
						$this.oldImage = $this.newImage;
						$this.canLoadAnother = true;
						$this.disableItem();
						$this.checkAutoPlay();
					});
				}
				else if(this.options['transitionType'] == 'alpha'){
					if(this.IE && this.IEversion && this.IEversion >= this.IEminversion){
						$($this.newImage).hide();
						$($this.newImage).delay(delayTime).fadeIn( this.options['easeInTime'], function(){
							$this.oldImage = $this.newImage;
							$this.canLoadAnother = true;
							$this.disableItem();
							$this.checkAutoPlay();
						});
					}else{
						$(imageContainer).hide();
						$(imageContainer).delay(delayTime).fadeIn( this.options['easeInTime'], function()
						{
							$this.oldImage = $this.newImage;
							$this.canLoadAnother = true;
							$this.disableItem();
							$this.checkAutoPlay();
						});
					}
				}
				else{
					alert("SET A VALID TRANSITION TYPE ('vertical' ||  'horizontal' || 'alpha')");
				}
				
				//	HIDE OLD IMAGE
				if(this.oldImage != null){
					this.hideImage();
				}
				
				//	DISPATCH EVENT NEW IMAGE
				this.instance.trigger('NEW_IMAGE', [this.counter, this.imgArray.length]);
			},
			
			resetTimer : function()
			{
				if(this.options['autoPlay'] == true){
					if(this.timer != null) clearTimeout(this.timer);
				}
			},
			
			hideImage : function()
			{
				var $this = this;
				
				var oldContainer = $(this.oldImage).parent();
				if(this.options['transitionType'] == 'horizontal'){
					var endX;
					switch (this.direction){
						case this.right:
							endX = String("-" + this.width);
						break;
						
						case this.left:
							endX = String(this.width);
						break;
					}
					
					$(oldContainer).animate({"margin-left":endX}, this.options['easeOutTime'], this.options['easeOut'], function(){
						$(oldContainer).remove();
						$this.oldImage = null;
					});
				}
				else if(this.options['transitionType'] == 'vertical'){
					var endY;
					switch (this.direction){
						case this.down:
							endY = String("-" + this.height);
						break;
						
						case this.up:
							endY = String(this.height);
						break;
						
						default:
							alert(this.direction + " IS NOT A VERTICAL DIRECTION");
						break;
					}
					
					$(oldContainer).animate({"margin-top":endY}, this.options['easeOutTime'], this.options['easeOut'], function(){
						$(oldContainer).remove();
						$this.oldImage = null;
					});
					
				} else if(this.options['transitionType'] == 'alpha'){
					if(this.IE && this.IEversion && this.IEversion >= this.IEminversion){
						$($this.oldImage).animate({"opacity":0},this.options['easeOutTime'], this.options['easeOut'], function(){
							$this.oldImage = null;
							oldContainer.remove();
						});
					}
					else{
						$(oldContainer).animate({"opacity":0},this.options['easeOutTime'], this.options['easeOut'], function(){
							$this.oldImage = null;
							oldContainer.remove();
						});
					}
				}else{
					alert("SET A VALID TRANSITION TYPE ('slide' or 'alpha')");
				}
				
			},
			
			disableItem:function(){
				var linkArray = $('a', this.instance);
				$('a', this.instance).unbind('click', this.changeImage);
				$('a', this.instance).css({'cursor':'default'})
				$('a', this.instance).addClass("carousel_link_selected");
				for (i = 0; i < linkArray.length; i++){
					if( i != this.counter){
						 $(linkArray[i]).bind('click',  {instance:this}, this.changeImage);
						 $(linkArray[i]).css({'cursor':'pointer'});
						 $(linkArray[i]).removeClass("carousel_link_selected");
					}
				}
			},
			
			checkAutoPlay : function(){
				var $this = this;
				if(this.options['autoPlay'] == true){
					this.timer = setTimeout(
							function(){ $this.nextImage(); }, 
							$this.options['slideShowTime']);
				}
			},
			
			checkTransitionsTime : function(){
				if(this.options['easeOutTime'] >= this.options['easeInTime']){
					this.options['easeOutTime'] -= 10;
				}
			},
			
			checkDirection : function(){
				if(this.options['transitionType'] == 'horizontal'){
					this.direction = (this.counter >= this.oldCounter) ? this.right : this.left;
				}
				else if(this.options['transitionType'] == 'vertical'){
					this.direction = (this.counter >= this.oldCounter) ? this.down : this.up;
				}
				this.oldCounter = this.counter;
			},
			
			
			hasNext : function (){
				return Boolean( this.counter < this.imgArray.length-1);
			},
			
			
			hasPrevious : function(){
				return Boolean( this.counter > 0);
			},
			

			setNewImgArray : function(newImgArray){
				this.width = this.instance.css('width');
				this.height = this.instance.css('height');
				
				if(this.oldImage != null) $(this.oldImage).parent().remove();
				if(this.newImage != null) $(this.newImage).parent().remove();
				
				this.imgArray = newImgArray;
				
				if(this.options['shuffle'] == true){
					this.shuffleImgArray();
				}
				
				this.checkImageLoaded();
			},
			
			getSingleDataArray:function(property){
				var singleArray = new Array();
				for(var i = 0; i < this.options['dataArray'].length; i++){
					singleArray.push(this.options['dataArray'][i][property]);		
				}
				return singleArray;
			},
			
			parseUrl : function(url){
				return url.replace("http://", "").replace(/\//g, "-").replace(/\./g, "-");
			}
			
	};
	
	
	$.fn.carousel = function(options) 
	{
		if(this.length) {
			this.each(function() {
				var new_carousel = new Carousel(this, options);
				new_carousel.init();
			});
		}
	};
	
})( jQuery );
