/*
 * jQuery Carousel Plugin - Custom version for www.fillstudio.com
 * version: 2.0.2 (2011/12/01)
 * 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,
		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,
				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,
				useArrowKeys : false
		};
		
		
		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();
					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.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()
			{
				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);
						
						var link = $(dummyLinkArray[i]).attr('title')
						link = link.replace(/^\s*/, "").replace(/\s*$/, "");
						
						if(link.length > 0)
						{
							this.linkArray.push(link);
						}
					}
				}
				else
				{
					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;
					this.options['showPrevNext'] = false;
					
					$('a', '.carousel_item_container').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.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];
				
				//	CHROME NO CACHE
				if($.browser.webkit)
				{
					this.loadImage();
					return;
				}
				//	END CHROME NO CACHE
				else
				{	
					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;
							
							if(!this.IE)
							{
								this.newImage.width = $('#' + this.parseUrl(imgUrl)).attr('width');
								this.newImage.height = $('#' + this.parseUrl(imgUrl)).attr('height');
							}
							
							this.newImage.src = $('#' + 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()
			{
				//	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'))
				});
				
				//	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 class='share_project'>"+
			        		"<p>Condividi: <a class='facebookShare' href='"+this.getSingleDataArray('url')[this.counter]+"'>Facebook</a>, <a class='twitterShare' title='"+this.getSingleDataArray('titolo')[this.counter]+"' href='"+this.getSingleDataArray('url')[this.counter]+"'>Twitter</a></p>"+
			        	"</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(
				{
					'float':'right',
					'margin-right':"10px",
					
					'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 imageContainer = $(this.newImage).parent();
				var delayTime = (this.first == false) ? this.options['delayBetweenTransitions'] : 0;

				var infoProject = $('.info_project', imageContainer.parent());
				
				//	BG FADE
				$(this.instance).delay(delayTime).animate({backgroundColor:String(this.getSingleDataArray('esadecimale')[this.counter] ? this.getSingleDataArray('esadecimale')[this.counter] : '#0F0F0F')},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')
				{
					infoProject.hide();
					infoProject.delay(delayTime).fadeIn( this.options['easeInTime']);
					
					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();
				}
				
				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')
				{
					infoProject.animate({"opacity":0},this.options['easeOutTime'], this.options['easeOut']);
					
					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', '.carousel_item_container');
				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.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 );
