var animDur = 700;
var animEasingHide = 'easeInQuint';
var animEasingShow = 'easeOutQuint';
var thePopup, theHider, theLoading, theClose, thePrev, theNext;



/**
 * @abstract	Funzione per animare la comparsa di un elemento.
 * @param		DOMelement:		l'elemento da nascondere
 *				theCallback:	è una funzione, opzionale, che se dichiarata viene eseguita dopo che il popup è comparso a video
 * 
 * @since		20110804
 * @param		doImmediate: definisce che l'animazione di comparsa deve essere immediata (duration 1)
 *
 */
var doShowAnimation = function ( DOMelement, theCallback, doImmediate ) {
	var theDur = animDur;
	
	if( doImmediate == true ) {
		theDur = 1;
	}
	
	DOMelement.animate({opacity: 'show'}, theDur, animEasingShow, function(){
		if( typeof theCallback == 'function' ) {
			theCallback.call();
		}
	})
}



/**
 * @abstract	Funzione per animare la scomparsa di un elemento.
 * @param		DOMelement:		l'elemento da nascondere
 *				theCallback:	è una funzione, opzionale, che se dichiarata viene eseguita dopo che il popup è comparso a video
 *
 */
var doHideAnimation = function ( DOMelement, theCallback ) {
	DOMelement.animate({opacity: 'hide'}, animDur, animEasingHide, function(){
		if( typeof theCallback == 'function' ) {
			theCallback.call();
		}
	})
}



/**
 * @abstract	Funzione che nasconde l'icona di Loading.
 * @param		theCallback: è una funzione, opzionale, che se dichiarata viene eseguita dopo che il popup è comparso a video
 *
 */
var doHideLoading = function ( theCallback ) {
	if( thePopup.is(':visible') ) {
		/* Controllo di sicurezza */
		theLoading.hide();
		
		doHideAnimation(thePopup, function(){
			doHideAnimation(theHider, theCallback);
		})
		
	} else {
		doHideAnimation(theLoading, function(){
			doHideAnimation(theHider, theCallback);
		})
	}
}



/**
 * @abstract	Funzione che visualizza l'icona di Loading. Si occupa di stabilire se Hider e/o Loading sono già aperti o chiusi, in caso li apre.
 * @param		theCallback: è una funzione, opzionale, che se dichiarata viene eseguita dopo che il popup è comparso a video
 * 
 * @since		20110804
 * @param		doImmediate: definisce che l'animazione di comparsa deve essere immediata (duration 1)
 *
 */
var doShowLoading = function ( theCallback, doImmediate ) {
	if( theHider.is(':hidden') ) {
		doShowAnimation(theHider, null, doImmediate);
		doShowAnimation(theLoading, theCallback, doImmediate);
		
	} else {
		if( thePopup.is(':visible') ) {
			doHideAnimation(thePopup, function(){
				doShowAnimation(theLoading, theCallback, doImmediate);
			})
		
		} else {
			doShowAnimation(theLoading, theCallback, doImmediate);
		}
	}
}



/**
 * @abstract	Funzione per riposizionare il popup.
 *
 */
var doPositionPopup = function () {
	var popLeft, popTop, closeLeft, closeTop, prevLeft, prevTop, nextLeft, nextTop;

	var iconDim = 30;
	var popBottomMargin = 20;
	
	var winW = $(window).width();
	var winH = $(window).height();
	var popW = thePopup.width();
	var popH = thePopup.height();
	
	
	/* Positioning the Popup */
	if( popW < winW ) {
		popLeft = Math.floor((winW / 2) - (popW / 2));
	} else {
		popLeft = 0;
	}

	if( popH < winH ) {
		popTop = Math.floor((winH / 2) - (popH / 2));
	} else {
		popTop = iconDim;
	}

	closeLeft = popLeft + popW + (iconDim / 2);
	closeTop = popTop - (iconDim + (iconDim / 2));

	nextLeft = closeLeft;
	nextTop = popTop + popH + popBottomMargin + (iconDim / 2);

	prevLeft = nextLeft - (iconDim * 1.5);
	prevTop = nextTop;

	thePopup.css({
		left: popLeft,
		top: popTop
	})

	theClose.css({
		left: closeLeft,
		top: closeTop
	})

	thePrev.css({
		left: prevLeft,
		top: prevTop
	})

	theNext.css({
		left: nextLeft,
		top: nextTop
	})
}



/**
 * @abstract	Prepara le immagini per la Gallery
 * @param		contents:	è l'attributo href dell'anchor dell'immagine
 *
 */
var doPrepareGallery = function ( contents ) {
	var allImages = $('a[rel="real_images"]');
	var totalImages = $('a[rel="real_images"]').length;
	var resVal = {prev: contents, next: contents, prevTitle: '', nextTitle: ''};

	if( totalImages == 1 ) {
		allImages.each(function(){
			theImg = $(this);
			
			resVal.prev = theImg.attr('href');
			resVal.next = theImg.attr('href');
			resVal.nextTitle = theImg.attr('title');
			resVal.prevTitle = theImg.attr('title');
		})
		
		return resVal;
		
	} else if ( totalImages == 2 ) {
		allImages.each(function(){
			theImg = $(this);
			
			if( theImg.attr('href') != contents ) {
				resVal.prev = theImg.attr('href');
				resVal.next = theImg.attr('href');
				resVal.nextTitle = theImg.attr('title');
				resVal.prevTitle = theImg.attr('title');
			}
		})
		
		return resVal;
		
	} else {
		var prevImg, nextImg;
		var found = false;

		if( $(allImages[0]).attr('href') == contents ) {
			resVal.prev = $(allImages[totalImages - 1]).attr('href');
			resVal.next = $(allImages[1]).attr('href');
			resVal.prevTitle = $(allImages[totalImages - 1]).attr('title');
			resVal.nextTitle = $(allImages[1]).attr('title');
			
		} else if ( $(allImages[totalImages - 1]).attr('href') == contents ) {
			resVal.prev = $(allImages[totalImages - 2]).attr('href');
			resVal.next = $(allImages[0]).attr('href');
			resVal.prevTitle = $(allImages[totalImages - 2]).attr('title');
			resVal.nextTitle = $(allImages[0]).attr('title');
			
		} else {
			allImages.each(function(index){
				if( found !== -1 ) {
					theImg = $(this);

					if( (theImg.attr('href') == contents) ) {
						resVal.prev = prevImg.attr('href');
						resVal.prevTitle = prevImg.attr('title');
						found = true;

					} else if ( found === true ) {
						/* contents è stato trovato nel ciclo precedente */
						resVal.next = theImg.attr('href');
						resVal.nextTitle = theImg.attr('title');
						found = -1;

					} else {
						/* contents ancora non è stato trovato */
						prevImg = theImg;
					}
				}
			})
		}
		
		return resVal;
	}
}



/**
 * @abstract	Funzione per aprire il popup. La funzione fa partire anche doShowLoading, che si occupa di stabilire se Hider e/o Loading sono già aperti e in caso li chiude.
 * @param		contents:	Contenuto del popup; se isGallery è true, contents contiene l'attributo href dell'anchor dell'immagine
 *				title:		Titolo del popup
 *				isGallery:	Se isGallery è true, il popup viene utilizzato per mostrare una galleria di immagini
 *				theCallback: è una funzione, opzionale, che se dichiarata viene eseguita dopo che il popup è comparso a video
 *
 */
var doOpenPopup = function ( contents, title, isGallery, theCallback ) {
	var performOpening = function () {
		/* Positioning the Popup */
		doPositionPopup();
		
		
		/* Showing the Popup */
		doHideAnimation(theLoading, function(){
			doShowAnimation(thePopup, function(){
				/* Positioning the Popup */
				doPositionPopup();
		
				/* Show Navigation buttons if isGallery is true */
				if( isGallery ) {
					doShowAnimation(theNext);
					doShowAnimation(thePrev);
				}
				
				/* Show Close button */
				doShowAnimation(theClose, function(){
					if( typeof theCallback == 'function' ) {
						theCallback.call();
					}
				})
			})
		})
	}
	
	
	doShowLoading(function(){
		if( (isGallery == null) || (isGallery == undefined) || (isGallery == '') ) {
			isGallery = false;
		} else {
			isGallery = true;
		}
		
		
		/* Managing Gallery */
		if( isGallery ) {
			navLinks = doPrepareGallery( contents );

			theNext.mouseup(function(){
				doClosePopup(function(){
					doOpenPopup(navLinks.next, navLinks.nextTitle, true, theCallback);
				})
			})
			
			thePrev.mouseup(function(){
				doClosePopup(function(){
					doOpenPopup(navLinks.prev, navLinks.prevTitle, true, theCallback);
				})
			})
		}
		
		
		/* Putting the Contents to Popup */
		if( !isGallery ) {
			contents = ( (title != null) && (title != undefined) && (title != '') ) ? ('<div id="popup_title">'+ title +'</div>' + contents) : contents;
			thePopup.html(contents);
			
			performOpening();
			
		} else {
			thePopup.html('');
			$('<img src="'+ contents +'" />')
				.appendTo(thePopup)
				.load(function(){
					if( (title != null) && (title != undefined) && (title != '') ) {
						thePopup.prepend('<div id="popup_title">'+ title +'</div>');
					}
					
					performOpening();
				})
		}
	})
}



/**
 * @abstract	Funzione per chiudere il popup. Se theCallback non è una Funzione, viene chiuso anche Hider. Altrimenti viene nascosto solo il popup e viene poi eseguita theCallback
 * @param		theCallback: è una funzione, opzionale, che se dichiarata viene eseguita dopo che il popup è comparso a video
 *
 */
var doClosePopup = function ( theCallback ) {
	theLoading.hide();
	doHideAnimation(thePrev);
	doHideAnimation(theNext);
	doHideAnimation(theClose);
	doHideAnimation(thePopup, function(){
		if( typeof theCallback == 'function' ) {
			theCallback.call();
		} else {
			doHideAnimation(theHider);
		}
	})
}



$(document).ready(function(){
	var popupElements = '<div id="popup_loading" /><div id="hider" /><div id="popup_close" /><div id="popup_prev" /><div id="popup_next" /><div id="popup" />';
	
	$(popupElements).prependTo('body');
	
	theLoading	= $('#popup_loading');
	theHider	= $('#hider');
	theClose	= $('#popup_close');
	thePrev		= $('#popup_prev');
	theNext		= $('#popup_next');
	thePopup	= $('#popup');
	
	theClose.live('mouseup', function(){
		doClosePopup(function(){
			doHideAnimation(theHider);
		})
	})
	
	$(document).keyup(function(e) {
		if (e.keyCode == 27) { // ESC
			doClosePopup(function(){
				doHideAnimation(theHider);
			})
		}
	})
	
	$('a[rel="do_popup"]').click(function(e){
		e.preventDefault();
		
		var thisOne = $(this);
		
		$.getJSON(thisOne.attr('href'), function(resVal){
			if( resVal.error == 0 ) {
				doOpenPopup(resVal.html, thisOne.attr('title'), false);
			} else {
				doOpenPopup('Si è verificato un errore imprevisto. Ci scusiamo per il disagio. <a href="/home.html">Clicca qui</a> per tornare alla Homepage. Grazie.', 'Errore!', false);
			}
		})
	})
	
	$('a[rel="real_images"]').click(function(e){
		e.preventDefault();
		
		doOpenPopup($(this).attr('href'), $(this).attr('title'), true);
	})
})



$(window).load(function(){

})



$(window).resize(function(){
	doPositionPopup();
})
