/*
 * jQuery Carousel Plugin - Custom version for www.fillstudio.com
 * version: 2.0.0 (2010/12/14)
 * Author: Emanuele Tortolone
 * http://www.fillstudio.com
 
 Usage:
	$('__ELEMENT__').carousel(
	{
		dataArray:__somedata__,
		showDescription:true,
		linkPosition : 'bottom',
		removeLinks : false,
		autoPlay : true,
		transitionType : 'horizontal',
		shuffle : false,
		showPrevNext : false,
		slideShowTime:3000,
		delayBetweenTransitions:200,
		easeIn:'easeInOutQuart',
		easeInTime:1500,
		easeOut:'easeInOutQuart',
		easeOutTime:1500
	});
	
	//	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,
				showDescription:true,
				imgArray: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,
				backgroundColor : '#0f0f0f'
		};
		
		
		this.options = $.extend(this.defaults, opts);
		
		this.instance = $(element);
		this.carouselLoading = null;
		this.carouselImagesContainer = null;
		this.carouselItemContainer = null;
		this.previousBtn = null;
		this.nextBtn = null;
		
		this.imgArray = null; 
		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.first = true;
		
		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;
					if(this.options.dataArray.length <= 1)
					{
						this.options['removeLinks'] = true;
					}
					this.initialized = true;
					this.createWrappers();
					this.checkTransitionsTime();
					this.createLoading();
					this.setDefaultStyle();
					this.initImgArray();
					this.initPrevNextBtn();
					this.checkImageLoaded();			
			},
			
			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.carouselItemContainer = $('.carousel_item_container', this.instance);
				this.carouselImagesContainer = $('.carousel_images_container', this.instance);
				
				this.instance.append("<div class='carousel_loaded_images_container'></div>");
				this.loadedImagesContainer = $('.carousel_loaded_images_container', this.instance);
			},
			
			createLoading : function()
			{
				this.instance.append("<div class='carousel_loading'></div>");	
				this.carouselLoading = $('.carousel_loading', this.instance);
			},
			
			setDefaultStyle : function()
			{
				this.instance.css({
					'position': 'relative',
					'overflow':'hidden'
				});
				
				$(this.carouselLoading).html('<span>Loading...</span>');
				$(this.carouselLoading).css({
					'z-index':'5',
					'position':'absolute'
				});
				
				$(this.carouselImagesContainer).css(
				{
					'width': "100%",
					'height': "100%"
				});
			},
			
			initImgArray : function()
			{
				this.imgArray = this.getSingleDataArray('immagine');

				for (var i = 0; i < this.imgArray.length; i++)
				{
					$(this.carouselItemContainer).append('<a></a>');
					
					var links = $('a', '.carousel_item_container');
					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;
					$('a', $('.carousel_item_container',this.instance)).css({
						'display':'none'
					})
				}
				
				if(this.options['shuffle'] == true) 
				{
					this.shuffleImgArray();
				}
			},
			
			shuffleImgArray : function()
			{
				for (var j = 0; j < this.imgArray.length; j++)
				{
					var tmp = this.options['dataArray'][j];
					var randomNum = Math.round(Math.random() * (this.options['dataArray'].length-1));
					this.options['dataArray'][j] = this.options['dataArray'][randomNum];
					this.options['dataArray'][randomNum] = tmp;
				}
				this.imgArray = this.getSingleDataArray('immagine');
				
				return this.imgArray; 
			},
			
			initPrevNextBtn : function()
			{
				if(this.options['showPrevNext'] == true)
				{
					this.createPreviousBtn();
					this.createNextBtn();
				}
			},
			
			createPreviousBtn : function()
			{
				this.instance.append("<div class='carousel_previous'></div>");
				this.previousBtn = $('.carousel_previous');
				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.click(function(){ this.prevImage(); } );
				}
			},
			
			createNextBtn : function()
			{
				this.instance.append("<div class='carousel_next'></div>");
				this.nextBtn = $('.carousel_next');
				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.click(function(){ this.nextImage(); });
				}
			},
			
			showLoading : function()
			{
				this.carouselLoading.fadeIn();
			},
			
			hideLoading : function()
			{
				this.carouselLoading.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(this.loadedImagesContainer.children().length > 0)
				{
					if($('#' + this.parseUrl(imgUrl),  this.loadedImagesContainer).attr('id'))
					{
						this.resetTimer();
						this.canLoadAnother = false;
						
						this.newImage = new Image();
						this.newImage.id = $('#' + this.parseUrl(imgUrl)).attr('id');
						this.newImage.rel = this.counter;
						this.newImage.width = $('#' + this.parseUrl(imgUrl)).attr('width');
						this.newImage.height = $('#' + this.parseUrl(imgUrl)).attr('height');
						this.newImage.onLoad = null;
						this.newImage.src = $('#' + this.parseUrl(imgUrl)).attr('src');
						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()
			{
				//	IMAGE/BACKGROUND WRAPPER
				var currentContainerName = String('carousel_item_' + this.counter);
				$(this.carouselImagesContainer).append("<div class='" + currentContainerName + " carousel_image_wrapper'></div>");
				
				var currentContainer = $(String("."+currentContainerName), this.instance);
				$(currentContainer).css(
				{
					'margin':'0px',
					'padding':'0px',
					'overflow':'hidden',
					'position':'absolute',
					'width': String($(this.carouselImagesContainer).css('width')),
					'height': String($(this.carouselImagesContainer).css('height'))
				});
				
				if(this.getSingleDataArray('url')[this.counter]){
					var link = '<a href="'+this.getSingleDataArray('url')[this.counter]+'" target="'+(this.getSingleDataArray('link_esterno')[this.counter] && this.getSingleDataArray('link_esterno')[this.counter] == '1' ? '_blank' : '_self')+'"></a>';
				}
				
				$(currentContainer).append(link);
				$('a',currentContainer).css({
					'width':String(this.newImage.width +"px"),
					'height':String(this.newImage.height +"px"),
					'display':'block',
					'background-color':'#FFFFFF',
					'opacity':'0',
					'position':'absolute',
					'z-index':'100'
				})
				//	DESCRIPTION
				if(this.options['showDescription'] == true)
				{
					var abstract = "<div class='info_project'>"+
						"<div class='abstract'>"+
							"<div>"+
								"<h3>"+this.getSingleDataArray('titolo')[this.counter]+"</h3>"+
								"<p>"+this.getSingleDataArray('testo')[this.counter]+"</p>"+
							"</div>"+
						"</div>"+
		        	"</div>";
					
					var border_color = this.getSingleDataArray('esadecimale')[this.counter] ? this.getSingleDataArray('esadecimale')[this.counter] : '#0F0F0F';
					$(currentContainer).append(abstract);
					//initShare('News di FillStudio:');
					//$('.abstract', currentContainer).css({
						//'border-bottom':String('3px solid ' + border_color)
					//});
					
				}
				
				//	IMAGE BACKGROUND
				$(currentContainer).append("<div class='carousel_item_image_background'></div>");
				var imageBackground = $(".carousel_item_image_background", $(currentContainer));
				imageBackground.css(
				{
					'width':String(this.newImage.width +"px"),
					'height':String(this.newImage.height +"px")
				});
				imageBackground.append(this.newImage);
				
				this.showImage();
				
			},

			showImage : function()
			{
				var currentContainerName = String('carousel_item_' + this.counter);
				var currentContainer = $(String("."+currentContainerName), this.instance);
				
				var $this = this;
				var delayTime = (this.first == false) ? this.options['delayBetweenTransitions'] : 0;

				var infoProject = $('.info_project', currentContainer);
				
				//	BG FADE
				//$(this.instance).delay(delayTime).animate({backgroundColor:String(this.getSingleDataArray('esadecimale')[this.counter] ? this.getSingleDataArray('esadecimale')[this.counter] : this.options['backgroundColor'])},this.options['easeInTime'], 'easeInOutQuart');
				
				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;
					}
					$(currentContainer).css("margin-left",startX);
					$(currentContainer).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')
				{
					if(this.first == true)
					{
						$(this.newImage).hide();
						$(this.newImage).delay(delayTime).fadeIn( this.options['easeInTime'], function()
						{
							$this.oldImage = $this.newImage;
							$this.canLoadAnother = true;
							$this.disableItem();
							$this.checkAutoPlay();
						});
					}
					else
					{
						var startY;
						var bottom;
						switch (this.direction)
						{
							case this.down:
								startY = String(this.height);
								bottom = String("-" + infoProject.height() + "px");
							break;
							
							case this.up:
								startY = String("-" + this.height);
								bottom = String(infoProject.height() + "px");
							break;
						}
						
						$(currentContainer).css("margin-top", startY);
						$(currentContainer).delay(delayTime).animate({"margin-top":"0px"}, this.options['easeInTime'], this.options['easeIn'], function()
						{
							$this.oldImage = $this.newImage;
							$this.canLoadAnother = true;
							$this.disableItem();
							$this.checkAutoPlay();
						});
						
						var infoFinalPosition = infoProject.css('bottom');
						infoProject.css(
						{
							'bottom': bottom
						});
						infoProject.delay(delayTime * 2).animate({'bottom': infoFinalPosition}, this.options['easeInTime'], this.options['easeIn']);
					}
				}
				else if(this.options['transitionType'] == 'alpha')
				{
					$(currentContainer).hide();
					$(currentContainer).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();
				}
				
				this.first = false;
				//	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 = $(".carousel_image_wrapper:first", this.instance);
				var infoProject = $('.info_project', oldContainer);
				
				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);
							bottom = String(infoProject.height() + "px");
						break;
						
						case this.up:
							endY = String(this.height);
							bottom = String("-" + infoProject.height() + "px");
						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;
					});
					
					$('.info_project', oldContainer).animate({'bottom': String(bottom)}, this.options['easeInTime'], this.options['easeIn']);
				}
				else if(this.options['transitionType'] == 'alpha')
				{
					$(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', $('.carousel_item_container',this.instance));
				for (var 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");
					}
					else
					{
						$(linkArray[this.counter]).unbind('click', this.changeImage);
						$(linkArray[this.counter]).css({'cursor':'default'})
						$(linkArray[this.counter]).addClass("carousel_link_selected");
					}
				}
			},
			
			checkAutoPlay : function()
			{
				var $this = this;
				if(this.options['autoPlay'] == true)
				{
					this.timer = setTimeout(
							function(){ $this.nextImage(); }, 
							this.getSingleDataArray('time')[this.counter] ? this.getSingleDataArray('time')[this.counter] : $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(/\//g, "-").replace(/\./g, "-");
			}
			
	};
	/*
	$.event.special.load = {
		add: function (callBack) 
		{
			if ( this.nodeType === 1 && this.tagName.toLowerCase() === 'img' && this.src !== '' ) 
			{
				if ( this.readyState === 'uninitialized' && this.src.indexOf('data:') === 0 ) 
				{
					//alert("ERROR");
					$(this).trigger('error');
					return;
				}
				else if ( this.complete || this.readyState === 4 ) 
				{
					//alert("ALREADY LOADED");
					$(this).unbind('load', callBack.handler);
					callBack.handler.apply(this);
					return;
				}
				else 
				{
					//alert("FIRST TIME LOADED");
					$(this).trigger('load');
					return;
				}
			}
		}
	};
	*/
	$.fn.carousel = function(options) 
	{
		if(this.length) 
		{
			this.each(function() 
			{
				var new_carousel = new Carousel(this, options);
				new_carousel.init();
			});
		}
		
	};
	
	

})( jQuery );
