/*
* BannerRotator:
* classe per gestire i banner
* 22 novembre 2011
* versione 1.5
*/

var BannerRotator = function(options){
	//Private members
	/*
	* uso self come riferimento a this
	* in questo modo evito di usare call o apply
	*
	*/
	
	var self = this; //imposto self per mantenere lo scope
	var $target;
	var lingua;
	var collezioni = {};
	var banners = [];
	var $loader; //barra per precaricamento immagini
	var $timer;
	var bannerAttivo;
	var contatore = 0;
	var timer; //barra del timer per l'autoplay
	var autoplay = true;
	var isPlaying = false;
	
	/*
	* precarica tutte le immagini presenti nelle collezioni
	* NOTA: metodo vecchio che utilizza "collezioni"
	*/
	var precaricaImmaginiOLD = function(){
		var dfd = $.Deferred();
		$loader = $('<img />',{src:'/lib/Banner/ajax-loader-bar.gif'})
			.css({position:'relative',display:'block',width:220,height:19,margin:'130px auto'})
			.appendTo(self.container);
		try{
			var immagini = [];
			for(var i in collezioni){
				var collezione = collezioni[i];
				for(var j in collezione){
					var immagine = collezione[j].immagine;
					var imageCache = new Image();
					immagini.push(imageCache);
					imageCache.onload = function(){
						immagini.pop();
						if(immagini.length==0){			
							$loader.remove();
							dfd.resolve("immagini caricate");
						}
					};
					imageCache.src = immagine;
				}
			}
		}catch(e){
			$loader.remove();
			alert(e);
			dfd.reject(e);
		}
		return dfd.promise(); //compatibile con $.when
	};
	
	/*
	* precarica tutte le immagini presenti nei banner
	*/
	var precaricaImmagini = function(){
		var dfd = $.Deferred();
		$loader = $('<img />',{src:'/lib/Banner/ajax-loader-bar.gif'})
			.css({position:'relative',display:'block',width:220,height:19,margin:'130px auto'})
			.appendTo(self.container);
		try{
			var immagini = [];
			var $immagini = $('img',self.container);
			$immagini.each(function(index,element){
				//console.log(element,index);
				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){			
						$loader.remove();
						dfd.resolve("immagini caricate");
					}
				};
				imageCache.src = srcImmagine;
			});
		}catch(e){
			$loader.remove();
			alert(e);
			dfd.reject(e);
		}
		return dfd.promise(); //compatibile con $.when
	};
	
	/*
	* crea i banner per tipo basandosi sui template
	*/
	var creaBanner = function(tipi){
		for(var i in tipi){
			var tipo= tipi[i];
			var collezione = collezioni[tipo];
			for(var j=0; j<collezione.length;j++){
				var data = collezione[j];
				var template = new self.Template(tipo,lingua);
				if(typeof template.callback == 'function') data = template.callback(data);
				template.target = self.container;
				template.img = data.immagine;
				template.link = data.url;
				if(lingua!='it') template.link = "/"+lingua+template.link;
				/*
				* imposto l'html degli elementi
				*/
				var elements = template.elements;
				for(var k in elements){
					var element = elements[k];
					element.html = data[k];
				}
				var newBanner =  new Banner(template);
				banners.push(newBanner);
			}
		}
		
	};
	
	var mescola = function(){
		bannerShuffled = banners.sort(function() {
		    return Math.random() - 0.5;
		});
	};
	
	var postCarica = function(tipi){
		creaBanner(tipi);
		var shuffle = options.shuffle || false;
		if(shuffle){
			mescola();
		}
		$.when(
			precaricaImmagini()
		).done(
		
			function(status){
				if(autoplay){
					self.go();
				}
			}
		);
	};
	
	//Public members
	
	/*
	* carica dinamicamente le collezioni specificate
	*/
	this.carica = function(tipi){
		/*
		* ajaxLoad: helper function
		* source: il link da dove carica i dati con getBanner
		* tipo: il tipo di collezione caricato
		*/
		var ajaxLoad = function(source,tipo,params){
			params.lingua = lingua;
			return $.ajax({
				url: source,
				type: "POST",
				data: {
					task: 'getBanner',
					params: JSON.stringify(params)
				},
				dataType: 'json',
				cache: false,
				success: function(data, textStatus, jqXHR){
					collezioni[tipo] = data;
				}
			});
		};
		
		var dfd = new $.Deferred();
		var totale = tipi.length;
		/*
		* risolvi_dfd: helper function
		* risolve il deferred dopo che tutti
		* i caricamenti sono eseguiti
		*/
		var risolvi_dfd = function(status){
			if(--totale==0){
				dfd.resolve('caricamento completato');
				postCarica(tipi);
			}
		};
		for(var i in tipi){
			var tipo = tipi[i];
			var myTemplate = new self.Template(tipo,lingua);
			var source = myTemplate.source;
			var params = myTemplate.params;
			$.when(ajaxLoad(source,tipo,params)).done(risolvi_dfd);
		}
		return dfd.promise();
	};
	
	/*
	* inserisce i banner staticamente
	* da usare in alternativa a carica()
	*/
	this.push = function(bannersOptions) {
		var shuffle = options.shuffle || false;
		for(var i in bannersOptions){
			var bannerOptions = bannersOptions[i];
			bannerOptions.target = self.container; //imposto qui il target del banner invece di specificarlo al momento della sua creazione
			var newBanner = new Banner(bannerOptions);
			banners.push(newBanner);
		}
		$.when(
			precaricaImmagini()
		).done(
			function(status){
				if(shuffle){
					mescola();
				}
				if(autoplay){
					self.go();
				}
			}
		);
	};
	
	this.go = function(direction){
		isPlaying = true;
		contatore = (banners.length>contatore)?contatore:0;
		contatore = (contatore<0)?banners.length-1:contatore;
		
		bannerAttivo = banners[contatore]; //imposto globalmente il banner attivo
		bannerAttivo.container
			.detach()
			.appendTo(self.container); //sposto in alto il banner attivo
		$.when(bannerAttivo.show()).done(function(status){
			if(banners.length>1 && autoplay){
				var bannerDelay = bannerAttivo.delay;
				timer.set(bannerDelay);
				timer.start();
			}
		});
	};
	/*
	* mostra il banner precedente
	*/
	this.prev = function(){
		self.pause();
		$.when(bannerAttivo.hide()).done(function(status){
			contatore -= 1;
			self.go();
		});
	};
	
	/*
	* mostra il banner seguente
	*/
	this.next = function(){
		self.pause();
		$.when(bannerAttivo.hide()).done(function(status){
			contatore += 1;
			self.go();
		});
	};
	this.play = function(){
		timer.start();
	};
	this.pause = function(){
		isPlaying = false;
		timer.pause();
	};
	
	var registraEventi = function(){
		$target.click(function(event){
			if(event.ctrlKey){
				event.preventDefault();
				event.stopPropagation();
				(event.shiftKey)?self.prev():self.next();
			}
			if(event.altKey){
				event.preventDefault();
				event.stopPropagation();
				(isPlaying)?self.pause():self.play();
			}
		});
	};
	
	/*
	* init viene eseguito automaticamente, ma deve essere l'ultima function
	*/
	var init = function(){
		$target = $(options.target || 'body');
		var targetHeight = $target.height() || 300;
		//var tipi = options.tipi || [];
		lingua = options.lingua || 'it';
		self.container = $('<div/>',{id:'rotator'})
			.css({position:'relative',width:'100%',overflow:'hidden',height:targetHeight})
			.appendTo($target);
		registraEventi();
			
		timer = new Timer({
			target: self.container,
			callback: self.next
		});
		/*$.when(
			self.carica(tipi)
		).done(
			function(status){
				//console.log(status);
				$.when(
					precaricaImmagini()
				).done(
					function(status){
						//console.log("immagini caricate",status);
						creaBanner(tipi);
						if(shuffle){
							mescola();
						}
						$loader.remove();
						if(autoplay){
							self.go();
						}
					}
				);
			}
		);*/
	}();
};

/*
* templates delle collezioni
*/
BannerRotator.prototype.Template = function(tipo,lingua){

	/*
	* helper function
	*/
	var formattaData = function(data){
		if(!isNaN(data) && data){
			var newData = new Date(data);
			var anno = newData.getFullYear();
			var mese = newData.getMonth()+1;
			var giorno = newData.getDate();
			var arrayData;
			switch (lingua){
				case 'it':
					arrayData = new Array(giorno,mese,anno);
					break;
				case 'en':
					arrayData = new Array(mese,giorno,anno);
					break;
				default:
					arrayData = new Array(mese,giorno,anno);
					break;
			}
			return arrayData.join('-');
		}else {
			return false;
		}
	};
	
	var templates = {
		mostre:{
			//source: "/mostre/dati.php",
			source: "/include/API/Eventi/AJAX-Controller.php",
			params: {Attivo: 1, tipi: ['mostra'], inCorso: true},
			target: '',
			img: '',
			link: '',
			delay: 7000,
			elements: {
				data:{tag:'<div />',html:'mostra.data',order:2,duration:450,hide: 'top',start_attributes:{position:'absolute',right:400, lineHeight:'30px', padding: '0px 30px'},end_attributes:{top:110}},
				museo:{tag:'<div />',html:'mostra.museo',order:1,duration:600,hide:'left',start_attributes:{position:'absolute',top:200,lineHeight:'30px',padding: '0px 30px'},end_attributes:{left:0}},
				titolo:{tag:'<div />',html:'mostra.titolo',order:1,duration:600,hide:'left',start_attributes:{position:'absolute',top:150,width:500,lineHeight:'40px'},end_attributes:{left:0}}
			},
			callback: function(data){
				var labels = {
					prorogata: {
						it:' prorogata al ',
						en:' extended until '
					}
				};
				var altriMusei = function(musei){
					var totale = musei.length;
					var testo = {};
					if(totale>=3){
						testo.it = musei[0]+" e altri "+(totale-1)+" musei";
						testo.en = musei[0]+" and "+(totale-1)+" more museums";
					}else{
						testo.it = testo.en = musei.join(' - ');
					}
					return testo;
				};
				if(data.data_da) data.data_da = formattaData(data.data_da);
				if(data.data_a) data.data_a = formattaData(data.data_a);
				if(data.data_proroga) data.data_proroga = formattaData(data.data_proroga);
				if(data.data_da == data.data_a){
					data.data = data.data_da+" ";
				}
				else{
					data.data = data.data_da+" | "+data.data_a;
				}
				if(data.data_proroga) data.data += labels.prorogata[lingua] + data.data_proroga;
				data.museo = altriMusei(data.museo)[lingua];
				return data;
			}
		},
		eventi:{
			//source: "/mostre/dati.php",
			source: "/include/API/Eventi/AJAX-Controller.php",
			params: {Attivo: 1, tipi: ['evento'], inCorso: true, inProgramma: true},
			target: '',
			img: '',
			link: '',
			delay: 7000,
			elements: {
				data:{tag:'<div />',html:'evento.data',order:2,duration:450,hide: 'top',start_attributes:{position:'absolute',right:400, lineHeight:'30px', padding: '0px 30px'},end_attributes:{top:110}},
				museo:{tag:'<div />',html:'evento.museo',order:1,duration:600,hide:'left',start_attributes:{position:'absolute',top:200,lineHeight:'30px',padding: '0px 30px'},end_attributes:{left:0}},
				titolo:{tag:'<div />',html:'evento.titolo',order:1,duration:600,hide:'left',start_attributes:{position:'absolute',top:150,width:500,lineHeight:'40px'},end_attributes:{left:0}}
			},
			callback: function(data){
				var labels = {
					prorogata: {
						it:' prorogata al ',
						en:' extended until '
					}
				};
				var altriMusei = function(musei){
					var totale = musei.length;
					var testo = {};
					if(totale>=3){
						testo.it = musei[0]+" e altri "+(totale-1)+" musei";
						testo.en = musei[0]+" and "+(totale-1)+" more museums";
					}else{
						testo.it = testo.en = musei.join(' - ');
					}
					return testo;
				};
				if(data.data_da) data.data_da = formattaData(data.data_da);
				if(data.data_a) data.data_a = formattaData(data.data_a);
				if(data.data_proroga) data.data_proroga = formattaData(data.data_proroga);
				if(data.data_da == data.data_a){
					data.data = data.data_da+" ";
				}
				else{
					data.data = data.data_da+" | "+data.data_a;
				}
				if(data.data_proroga) data.data += labels.prorogata[lingua] + data.data_proroga;
				data.museo = altriMusei(data.museo)[lingua];
				return data;
			}
		},
		musei: {
			//source: "/musei/dati_FRA.php",
			source: "/include/API/Musei/AJAX-Controller.php",
			params: {Attivo: 1},
			target: '',
			img: '',
			link: '',
			delay: 7000,
			elements: {
				nome:{tag:'<div />',html:'museo.nome',order:0,duration:500,hide:'left',start_attributes:{position:'absolute',top:150,width:'auto',lineHeight:'40px',padding: '0px 30px'},end_attributes:{left:0}}
			},
			callback: function(data){
				return data;
			}
		},
		custom: {
			source: "/indirizzo/dove/carica/dati.php",
			target: "place holder: valore assegnato in crea banner",
			img: "place holder: valore assegnato in crea banner",
			link: "place holder: valore assegnato in crea banner",
			delay: 5000,
			elements: {
				nome:{tag:'<div />',html:'custom.nome',order:1,duration:600,hide:'left',start_attributes:{position:'absolute',top:200,width:'auto',lineHeight:'30px',padding: '0px 30px'},end_attributes:{left:0}},
				cognome:{tag:'<div />',html:'custom.cognome',order:2,duration:450,hide: 'right',start_attributes:{position:'absolute',left:300, width:200,lineHeight:'30px'},end_attributes:{right:110}},
				data:{tag:'<div />',html:'custom.data',order:3,duration:450,hide: 'bottom',start_attributes:{position:'absolute',left:300, width:200,lineHeight:'30px'},end_attributes:{bottom:250}}
			}
		}
	};
	return templates[tipo];
}

/*
* Timer: helper class
* aggiunge una barra di timeout al BannerRotator
*/
var Timer = function(options){
	var self = this;
	var $bar;
	var callback;
	var startTime;
	var remainingTime;
	var playing;
	
	var reset = function() {
		$bar.css({
			width:'0%'
		});
	};
	
	var init = function(){
		var target = options.target || 'body';
		callback = options.callback || function(){};
		var $box = $('<div/>')
			.css({
				width:'100%',
				height: 2,
				position: 'absolute',
				bottom: 0,
				left: 0,
				zIndex: 9999
			})
			.appendTo(target);
		$bar = $('<div/>')
			.css({
				width:'0%',
				height: '100%',
				position: 'absolute',
				bottom: 0,
				left: 0,
				backgroundColor: '#678CB8',
				//opacity: 0.7,
				opacity: 0.0
			}).appendTo($box);
	}();
	this.set = function(time){
		reset();
		startTime = remainingTime = time;
	};
	this.start = function(){
		playing = true;
		$bar.animate({width:'100%'},{
			duration:remainingTime,
			easing: 'linear',
			step:function(now,fx){
				//aggiorno remainingTime ad ogni step dell'animazione
				remainingTime = startTime - startTime/100*now;
			},
			complete:function(){
				reset();
				callback();
			}
		});
	};
	this.pause = function(){
		if($bar.queue('fx').length>0){
			playing = false;
			$bar.stop(true,false);
		}
	};
	this.toggle = function(){
		if(playing){
			self.pause();
		}else{
			self.start();
		}
	};
	this.stop = function(){
		self.pause();
		reset();
	};
};
