/*
* Banner:
* classedi un singolo banner
* 21 novembre 2011
* versione 1.1
*/

var Banner = function(options){
	//Private members
	/*
	* uso self come riferimento a this
	* lo imposto in init
	* in questo modo evito di usare call o apply
	*
	*/
	var self = this; //imposto self per mantenere lo scope
	var $target;
	var gruppi = [];
	var $coda = $({});
	
	
	/*
	* hideElement nasconde gli elementi fuori dal container
	*/
	var hideElement = function($element,position){
		var css;
		var height = $element.outerHeight();
		var width = $element.outerWidth();
		switch(position){
			case 'top':
				css = {top: -height};
				break;
			case 'left':
				css = {left: -width};
				break;
			case 'bottom':
				css = {bottom: -height};
				break;
			case 'right':
				css = {right: -width};
				break;
			default:
				break;
		}
		$element.css(css);
		$.extend($element.data('start'),css);
	}
	
	this.show = function(){
		/*
		* gestisce l'ordine delle animazioni nei gruppi
		*/
		
		var animazioneGruppi = function(){
			var dfd = new $.Deferred();
			var pending = gruppi.length;
			var $coda = $({});
			for(var i in gruppi){
				var gruppo = gruppi[i];
				$coda.queue('fx',function(next){
					$.when(anima(gruppo)).done(function(){
						if(--pending==0){
							dfd.resolve('fine animazione gruppi');
						}
						next();
					});
				});
			}
			return dfd.promise();
		};
		/*
		* gestisce l'animazione del singolo elemento
		*/
		var anima = function(gruppo){
			var dfd = new $.Deferred();
			var pending = gruppo.length;
			for(var i in gruppo){
				var $element = gruppo[i];
				var effects = $element.data('end');
				var duration = $element.data('duration');
				$element.animate(effects,duration,function(){
					if(--pending==0){
						dfd.resolve('fine animazione elemento');
					}
				});
			}
			return dfd.promise();
		};
		
		var dfd = new $.Deferred();
		$.when(self.img.fadeIn(500)).done(function(status){
			$.when(animazioneGruppi()).done(function(status){
				self.container.trigger('visible',{banner:self}); //insieme all'evento imposto un riferimento all'oggetto Banner
				dfd.resolve('banner visibile');
			});
		});
		return dfd.promise();
	};
	
	this.hide = function(){
		var animazione = function(){
			var dfd = new $.Deferred();
			var contatore = self.elements.length;
			self.img.fadeOut(500);
			for(var i in self.elements){
				var $element = self.elements[i];
				var effects = $element.data('start');
				/*
				* elimino elementi non numerici per bug su IE8-IE7
				*/
				for (var i in effects){
					if(isNaN(effects[i])){
						delete effects[i];
					}
				}

				var duration = $element.data('duration');
				$element.animate(effects,duration,function(){
					//risolvo il deferred quando finisce l'ultima animazione
					if(--contatore==0){
						dfd.resolve('done animazione hide');
					}
				});
			}
			return dfd.promise();
		};
		
		var dfd = new $.Deferred();
		$.when(animazione()).done(function(status){
			self.container.trigger('hidden',{banner:self}); //insieme all'evento imposto un riferimento all'oggetto Banner
			dfd.resolve('banner nascosto');
		});
		return dfd.promise();
	};
	
	/*
	* precarica tutte le immagini presenti nelle collezioni
	*/
	var precaricaImmagini = function($element){
		var dfd = $.Deferred();
		try{
			var immagini = [];
			var $immagini = $('img',$element);
			if($immagini.length>0){
				$immagini.css({display:'none'}); //prima del caricamento nascondo le immagini
				$immagini.each(function(index,element){
					var srcImmagine = $(element).attr('src'); //img nel Banner è un oggetto jQuery
					var imageCache = new Image();
					immagini.push(imageCache);
					imageCache.onload = function(){
						immagini.pop();
						if(immagini.length==0){
							$immagini.css({display:'inline'}); //mostro le immagini quando sono state caricate tutte
							dfd.resolve("immagini caricate");
						}
					};
					imageCache.src = srcImmagine;
				});
			}else{
				dfd.resolve("nessuna immagine da caricare");
			}
		}catch(e){
			alert(e);
			dfd.reject(e);
		}
		return dfd.promise(); //compatibile con $.when
	};
	
	var init = function(){
		$target = $(options.target || 'body');
		self.container = $('<div/>').addClass('banner').css({position:'absolute',overflow:'hidden',zIndex:1});
		self.container.appendTo($target);
		self.delay = options.delay || 1500; //durata di visibilità del banner
		var link = options.link || "#";
		self.container.click(function(event){
			location.href = link;
		});
		
		var img_src = options.img || '';
		self.img = $('<img/>',{src:img_src})
		.css({position:'relative',top:0,left:0,display:'none'})
		.bind('load',function(event){
			var imgHeight =$(this).height();
			self.container.height(imgHeight);
		})
		.appendTo(self.container);
		//self.img.css({width:900}); //forza la larghezza dell'immagine
		//self.container.height(self.img.height());
		var elements = options.elements || {};
		self.elements = [];
		/* 
		* uso un array temporaneo per memorizzare
		* in quello definitivo solo valori defined
		*/
		var tempGruppi = [];
		for(var i in elements){
			var element = elements[i];
			if(element.html!=''){ //non uso elementi senza testo
				var order = element.order || 0; //ordine di esecuzione
				var $element = $(element.tag)
					.addClass(i)
					.css(element.start_attributes)
					.appendTo(self.container)
					.html(element.html)
					.data('order',order)
					.data('start',element.start_attributes)
					.data('end',element.end_attributes)
					.data('duration',element.duration);
				/*$.when(
					precaricaImmagini($element)
				).done(
					function(status){
						if(element.hide){
							hideElement($element,element.hide);
						}
					}
				);*/
				if(element.hide){
							hideElement($element,element.hide);
						}
				if(typeof(tempGruppi[order])=='undefined'){
					tempGruppi[order] = [];
				}
				tempGruppi[order].push($element);
				self.elements.push($element);
			}
		}
		for(var i in tempGruppi){
			gruppi.push(tempGruppi[i]);
		}
	}();
	
	//init(options);
};
