/*!*
 * SizeUp
 * @description: SizeUp is a combination of lightbox and slideshow, developt for G2 emea
 * @author: hst
 *
 * @usage:
 *  //JS-Code
 *  myset = new SizeUp("setname");
 *
 *  myset.slideshow = true; //optional (true, false)
 *  myset.timer = 5000; //optional (int in ms)
 *  myset.anchorpoint = "top-left"; //optional (top-left, top-right, bottom-left, bottom-right)
 *
 *  myset.add("img/image1.jpg");
 *  myset.add("img/image2.jpg");
 *  myset.init();
 *
 *  //HTML-Code
 *  //use the sizeup.css as stylesheet
 *  <a href="#" class="sizeup" rel="setname"><img src="img/image1-thumb.jpg" width="100" height="100" alt=""/></a>
 *
 */
 
function SizeUp(setname) {
	//(@public) Slideshow aktivieren
	this.slideshow = false;
	
	//(@public) Slideshow-Timer (in ms)
	this.timer = 5000;
	
	//(@public) Ankerpunkt der Viewing-Box (top-left, top-right, bottom-left, bottom-right)
	this.anchorpoint = "top-left";	
	
	//Referenz auf sich selbst
	var self = this;
	
	//Name des Bilder-Sets
	var setname = setname;
	
	//Interval für den Timer speichern
	var interval;
	
	//Elemente die Angezeigt werden sollen
	var elements = new Array();
	
	//Aktuell angezeigtes Element
	var currentelement;
	
	//Sprachstrings
	var lang = {
		close: "Close",
		prev: "Prev",
		next: "Next",
		slideshow: "Slideshow",
		yes:"yes",
		no:"no",
		on:"on",
		off:"off"
	};
	
	//ID der Viewing-Box
	var vbid = "size_"+setname;
	
	//Höhe des Menüs
	var menuheight = 0;
	
	//Ist SizeUp gerade aufgerufen wurden und zeigt das erste Bild an?
	var startup = true;
	
	/**
	 * Initialisiern 
	 */
	this.init = function() {
		clickOpenLink();
		resetSettings();
	}
	
	/**
	 * Einstellungen zurücksetzen
	 */
	var resetSettings = function() {
		currentelement = 0;
	}
	
	/**
	 * Neues Element hinzufügen
	 */
	this.add = function(src) {
		elements.push(src); 
	}
	
	/**
	 * Öffnen Link suchen und onClick hinzufügen
	 */
	var clickOpenLink = function() {
		$("a.sizeup[@rel^="+setname+"]").click(function() {
			//Einstellungen zurücksetzen
			resetSettings();
			
			//Nur hinzufügen, wenn noch nicht vorhanden
			if($("body:has(div#"+vbid+")").size() == 0) {
				addViewingBox();
						
				positionViewingBox();
				
				//1. Element laden
				showElement(currentelement);
			}
			return false;
		});
		$("a.sizeup[@rel^="+setname+"] img").after('<span class="plus"></span>');
		//Noch ein bisschen nach unten schieben (ausser im Safari)
		if($.browser.msie || $.browser.mozilla || $.browser.opera) {
			$("a.sizeup[@rel^="+setname+"] .plus").css('margin-bottom', '3px');
		}
	}
	
	/**
	 * Funktionalität des Schließen-Links
	 * Nach dem Ausfaden, Div-Layer entfernen
	 */
	var clickCloseLink = function() {
		$("div#"+vbid+" .close a").click(function() {
			$("div#"+vbid).fadeOut("normal", function() { removeViewingBox(); });
			//Wenn die Slideshow aktiviert wurde, dann den Timer löschen
			if(self.slideshow == true) { deactivateTimer(); }
			return false;
		});
	}
	
	/**
	 * Erstellt die Viewing-Box und fügt diese dem Seitenbaum hinzu
	 */ 
	var addViewingBox = function() {
		$("body").append("<div class=\"sizeup\" id=\""+vbid+"\"></div>");
		$("div#"+vbid).html("<div class=\"content\"></div>");
		$("div#"+vbid+" .content").after("<p class=\"close\"><a href=\"#\">"+lang.close+"</a></p>");
		$("div#"+vbid+" .content").after("<div class=\"menu\"></div>");
		$("div#"+vbid+" .menu").html("<p class=\"next\"><a href=\"#\">"+lang.next+"</a></p>");
		$("div#"+vbid+" .menu .next").after("<ul class=\"numbers\"></ul>");
		$("div#"+vbid+" .menu .numbers").after("<p class=\"prev\"><a href=\"#\">"+lang.prev+"</a></p>");
		
		//Slideshow-Button hinzufügen, wenn mehr als 1 Element vorhanden
		if(elements.length > 1) {
			$("div#"+vbid+" .next").after("<p class=\"slideshow\">"+lang.slideshow+": <a href=\"#\">"+((self.slideshow) ? lang.on : lang.off)+"</a></p>");
			$("div#"+vbid+" .slideshow a").click(function() {
				self.slideshow = !self.slideshow;
				
				if(self.slideshow == true) {
					activateTimer();
					$(this).text(lang.on);
				} else {
					deactivateTimer();
					$(this).text(lang.off);
				}
				return false;
			});
		}
		
		//Menühöhe gleich auslesen
		menuheight = parseInt($("div#"+vbid+" .menu").height()) + 20;
		
		//Gleich verstecken, damit sie auch eingeblendet werden kann
		$("div#"+vbid).hide();
		$("div#"+vbid).css("width", "0px");
		$("div#"+vbid).css("height", "0px");
		
		$("div#"+vbid+" .next").hide();
		$("div#"+vbid+" .prev").hide();
		
		clickCloseLink();
		generateNavigation();
	}
	
	/**
	 * Entfernt die Viewing-Box wieder aus dem Seitenbaum
	 */
	var removeViewingBox = function() {
		$("div#"+vbid).remove();
		startup = true;
	}
	
	/**
	 * Navigation erstellen
	 */
	var generateNavigation = function() {
		//Nummern-Navigation erstellen
		/*if(elements.length > 1) {
			for(var i=0;i<elements.length; i++) {
				$("div#"+vbid+" .numbers").append("<li><a href=\"#\">"+(i+1)+"</a></li>");
				$("div#"+vbid+" .numbers li:eq("+ i +") a").click(function() {
					currentelement = parseInt($(this).text())-1;
					hideElement(function(){showElement(currentelement);});
					return false;
				});
			}
		}*/
		
		//Rückwärts-Link
		$("div#"+vbid+" .prev a").click(function() {
			if(hasElement(currentelement-1)) {
				currentelement--;
				hideElement(function(){showElement(currentelement);});
			}
			return false;
		});
		
		//Vorwärts-Link
		$("div#"+vbid+" .next a").click(function() {
			if(hasElement(currentelement+1)) {
				currentelement++;
				hideElement(function(){showElement(currentelement);});
			}
			return false;
		});
	}
	
	var changeActiveNumber = function(newactive) {
		$("div#"+vbid+" .numbers li.active").removeClass("active");
		$("div#"+vbid+" .numbers li:eq("+newactive+")").addClass("active");
	}
		
	var checkNavigation = function() {
		if(hasElement(currentelement+1)) {
			$("div#"+vbid+" .prev").removeClass('spacer');
			//Beim Startup einfach einblenden und nicht einfaden
			if(startup == true) {
				$("div#"+vbid+" .next").show();
			} else {
				$("div#"+vbid+" .next").fadeIn("fast");
			}
		} else {
			if(startup == true) {
				$("div#"+vbid+" .next").hide();
			} else {
				$("div#"+vbid+" .next").fadeOut("fast", function() {$("div#"+vbid+" .prev").addClass('spacer');});
			}
		}
		if(hasElement(currentelement-1)) {
			if(startup == true) {
				$("div#"+vbid+" .prev").show();
			} else {
				$("div#"+vbid+" .prev").fadeIn("fast");
			}
		} else {
			if(startup == true) {
				$("div#"+vbid+" .prev").hide();
			} else {
				$("div#"+vbid+" .prev").fadeOut("fast");
			}
		}
	}
	
	/**
	 * Element an einer bestimmten Stelle zeigen
	 */
	var showElement = function(index) {
		imgPreloader = new Image();
		//Funktion, wenn das Bild geladen wurde
		var fncOnLoad = function(evt, mywidth, myheight){
			imgPreloader.onload = null;
			
			width = (mywidth == undefined) ? imgPreloader.width : mywidth;
			height = (myheight == undefined) ? imgPreloader.height : myheight;
			
			$("div#"+vbid+" .content").html(imgPreloader);
			$("div#"+vbid+" .content img").hide();
			
			//Kurz auf die Bildgrößen warten, da sonst im Safari keine Werte vorhanden sind
			//var waitforimgsize = window.setInterval (function() {
			//	window.clearInterval(waitforimgsize);
				//Erst die Viewing-Box-Größe verändern, dann das Bild wieder einblenden
				resizeViewingBox(width, height, function() {
					if(startup == true) {
						checkNavigation();
					}
					
					//Slideshow-Modus aktiviert?
					if(self.slideshow == true) {
						$("div#"+vbid+" .content img").fadeIn("normal", activateTimer);
						
					} else {
						$("div#"+vbid+" .content img").fadeIn("normal");
					}
					$("div#"+vbid+" .content img").attr("width", width);
					$("div#"+vbid+" .content img").attr("height", height);
					$("div#"+vbid).removeClass('loading');
					
					//Das erste Bild wurde geladen
					startup = false;
				});
			//}, 5);
			
			
			//Navigation checken und ändern
			//changeActiveNumber(currentelement);
			
			//Beim ersten Start erst checken, wenn resizeViewingBox ausgeführt wurde 
			if(startup == false) {
				checkNavigation();
			}			
		}
		//Beim ersten Bild erst später anzeigen
		if(startup == true) {
			var loadinginterval = window.setInterval (function() {
				window.clearInterval(loadinginterval);
				$("div#"+vbid).addClass('loading');
			}, 700);
		} else {
			$("div#"+vbid).addClass('loading');
		}
		
		//Für alle Browser aus Opera und Safari das onload benutzen
		if(jQuery.browser.opera == false && jQuery.browser.safari == false) {
			imgPreloader.onload = fncOnLoad;
		}
		
		//Laden durch das setzen der URL starten
		imgPreloader.src = elements[index];
		
		//Für Opera und Safari auf img.complete prüfen. (siehe http://forum.mootools.net/topic.php?id=4678 und http://www.buymeasoda.com/dev/issues/image_onload/image_onload_workaround.html)
		if(jQuery.browser.opera == true || jQuery.browser.safari == true) {
			//Kurz auf die Bildgrößen warten, da sonst im Opera undSafari kein img.complete vorhanden ist
			var waitforimgsize = window.setInterval (function() {
				if(imgPreloader.complete) {
					window.clearInterval(waitforimgsize);
					//debug('complete fired: '+imgPreloader.width+' - '+imgPreloader.height);
					fncOnLoad(null, imgPreloader.width, imgPreloader.height);
				} else {
					//debug('waiting for complete fired'); 
				}
			}, 300);
		}
	}
	
	/**
	 * Element ausblenden
	 */
	var hideElement = function(callback) {
		//Wenn Slideshow Modus, dann Timer deaktivieren
		if(self.slideshow == true) {
			deactivateTimer();
		}
		
		$("div#"+vbid+" .content img").fadeOut("normal", callback);
	}
	
	/**
	 * Skaliert die Größe der ViewingBox
	 */
	var resizeViewingBox = function(width, height, callback) {
		if(callback == undefined) callback = null;
		
		//Höhe des Menüs dazu addieren
		//height += menuheight;
		
		//Animieren, wenn die Größe wirklich unterschiedlich ist
		if(parseInt($("div#"+vbid).css("height")) != height || parseInt($("div#"+vbid).css("width")) != width) {
			$("div#"+vbid).animate( { height:height+"px"}, { queue:false, duration:500, "easing": "swing"} ).animate({ width:width+"px"} , {duration:500, "easing": "swing", complete:callback});
			
		//sonst nur den Callback aufrufen
		} else {
			callback();
		}
	}

	/**
	 * Animiert das Öffnen des divs, dass für die Anzeige da ist
	 */
	var positionViewingBox = function() {		
		//Thumbnail oder nur den Link nutzen, wenn kein Bild vorhanden
		var child = ($("a.sizeup[@rel^="+setname+"] img").length) ? $("a.sizeup[@rel^="+setname+"] img") : $("a.sizeup[@rel^="+setname+"]");
		
		var top = child.offset().top;
		var bottom = (getH() - child.offset().top - child.height() - 10);
		var left = child.offset().left;
		var right = (getW() - child.offset().left - child.width() - 10);
		
		//alternative Berechnung für IE6 ,...
		if(jQuery.browser.msie == true && jQuery.browser.version.substr(0,1)=="6") {
			bottom = getPageSizeWithScroll()[1] - top - child.height() - 2;
		//Opera ...
		} else if(jQuery.browser.opera == true) {
			bottom -= 40;
		//und Safari
		} else if(jQuery.browser.safari == true) {
			bottom += 50;
		}
		
		//Positionieren
		$("div#"+vbid).css("position", "absolute");
		
		//bottom-right
		if(self.anchorpoint == "bottom-right") {
			$("div#"+vbid).css("bottom", bottom + "px");
			$("div#"+vbid).css("right", right+"px");
			
		//bottom-left
		} else if(self.anchorpoint == "bottom-left") {
			$("div#"+vbid).css("bottom", bottom + "px");
			$("div#"+vbid).css("left", left + "px");
			
		//top-right
		} else if(self.anchorpoint == "top-right") {
			$("div#"+vbid).css("top", top + "px");
			$("div#"+vbid).css("right", right+"px");
			
		//top-left
		} else {
			$("div#"+vbid).css("top", top + "px");
			$("div#"+vbid).css("left", left + "px");
		}
		
		//Window-Resize-Listener hinzufügen
		$(window).resize(positionViewingBox);
	}
	
	/**
	 * Innere-Fensterbreite (Angezeigter Bereich) bekommen
	 */
	function getW(){
		var w;
		if(document.innerWidth){ w=document.innerWidth;
		} else if(document.documentElement.clientWidth){ w=document.documentElement.clientWidth;
		} else if(document.body){ w=document.body.clientWidth; }
		return w;
	}
	/**
	 * Innere-Fensterhöhe (Angezeigter Bereich) bekommen
	 */
	function getH(){
		var h;
		if(document.innerHeight){ h=document.innerHeight;
		} else if(document.documentElement.clientHeight){ h=document.documentElement.clientHeight;
		} else if(document.body){ h=document.body.clientHeight; }
		return h;
	}
	
	/**
	 * Länge der Seite
	 */
	function getPageSizeWithScroll(){
		if (window.innerHeight && window.scrollMaxY) {// Firefox
			yWithScroll = window.innerHeight + window.scrollMaxY;
			xWithScroll = window.innerWidth + window.scrollMaxX;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			yWithScroll = document.body.scrollHeight;
			xWithScroll = document.body.scrollWidth;
		} else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
			yWithScroll = document.body.offsetHeight;
			xWithScroll = document.body.offsetWidth;
	  	}
		arrayPageSizeWithScroll = new Array(xWithScroll,yWithScroll);
		//alert( 'The height is ' + yWithScroll + ' and the width is ' + xWithScroll );
		return arrayPageSizeWithScroll;
	}
	
	/**
	 * Ist ein Element an einer bestimmten Stelle vorhanden
	 */
	var hasElement = function(index) {
		return (elements[index] != undefined);
	}
	
	/**
	 * Timer für die Slideshow aktivieren
	 */
	var activateTimer = function() {
		interval = window.setInterval (function() {
			if(hasElement(currentelement+1)) {
				currentelement++;
			} else {
				currentelement = 0;
			}
			hideElement(function(){showElement(currentelement);});
		}, self.timer);
	}
	
	/**
	 * Timer löschen und nächstes Bild
	 */
	var deactivateTimer = function() {
		window.clearInterval(interval);
	}
	
	/**
	 * Debuggen auf Console des Browsers
	  */
	function debug(text) {
		((window.console && console.log) ||
		(window.opera && opera.postError) ||
		window.alert).call(this, text);
	}
}