/**
 * IonasTag - Hervorhebung deklarierter Schlüsselwörter
 */

window.ionasTag = {
	el: null,
	data: null,
	xhr: false, // ob ein XHR aktiv ist
	cache: {},
	show: function(el) {
		// el kann auch null sein, falls Auslöser ein onmouseover auf dem Popup war
		if (!el || el == ionasTag.el) return; // nichts zu tun
		if (ionasTag.xhr) {
			// fremder XHR -> nochmal warten... wir wollen den Server nicht überlasten
			ionasTag.setVisibleDelayed(true, el);
			return;
		}
		
		// was auch immer gerade aktiv ist: abbrechen
		if (ionasTag.interval != null) clearInterval(ionasTag.interval);
		
		ionasTag.el = el;
		ionasTag.offset = 0;
		ionasTag.tag = el.innerHTML;
		var rect = el.getBoundingClientRect();
		var totalheight = window.innerHeight || document.body && document.body.clientHeight || document.documentElement.clientHeight;
		var scroll = document.body && document.body.scrollTop || document.documentElement.scrollTop;
		
		var div = document.getElementById("ionasTagPopup");
		div.style.left = rect.left + "px";
		div.style.display = "";
		if (div.style.opacity != null) div.style.opacity = 0; else div.style.filter = "alpha(opacity=0)";
		div.style.maxHeight = 0;
		div.style.top = "";
		div.style.bottom = "";
		div.style.height = "0px";
		div.scrollTop = "0";
		var maxHeight = Math.max(rect.top, totalheight-rect.bottom) - div.offsetHeight;
		div.style.height = "";
		if (rect.top+rect.bottom > totalheight) {
			div.style.bottom = 0;
			div.style.bottom = div.getBoundingClientRect().bottom - rect.top + "px";
		} else {
			div.style.top = scroll + rect.bottom + "px";
		}
		var table = document.getElementById("ionasTagPopupTable");
		while (table.rows.length > 0) {
			table.deleteRow(table.rows.length-1);
		}
		
		ionasTag.loaded = false;
		var time = (new Date()).getTime();
		var fading = false;
		ionasTag.interval = setInterval(function(){
			var elapsed = (new Date()).getTime() - time;
			if (!ionasTag.loaded) {
				elapsed /= 500;
				var c = Math.floor(Math.floor(elapsed)*(1-Math.floor(elapsed))*1023);
				el.style.borderColor = "rgb("+c+","+c+","+c+")";
			} else if (!fading) {
				fading = true;
				time = (new Date()).getTime();
				el.style.borderColor = "";
			} else {
				elapsed /= 200;
				if (elapsed >= 1) {
					if (div.style.opacity != null) div.style.opacity = ""; else div.style.filter = "";
					clearInterval(ionasTag.interval);
					div.style.maxHeight = maxHeight + "px";
					div.style.overflowY = "auto";
				} else {
					if (div.style.opacity != null) div.style.opacity = elapsed; else div.style.filter = "alpha(opacity=" + (elapsed*100) + ")";
					div.style.maxHeight = Math.min(maxHeight, Math.pow(elapsed,3)*1000) + "px";
					div.style.overflowY = "hidden";
				}
			}
		}, 20);
		
		this.loadMore();
	},
	render: function(json){
		if (!json) return;
		var s = "";

		var $e = function(name, _) {
			var el = document.createElement(name);
			for (var i = 1; i < arguments.length; i++) {
				var a = arguments[i];
				if (a.nodeType) el.appendChild(a); else for (var j in a) el[j] = a[j];
			}
			return el;
		}
		var $t = function(text) {
			return document.createTextNode(text);
		}
		
		var table = document.getElementById("ionasTagPopupTable");
		for (var i = 0; i < json.docs.length; i++) {
			var tr = table.insertRow(-1);
			var doc = json.docs[i];
			if (doc.teaserImage != null) {
				var src = doc.teaserImage.match("//") || doc.teaserImage.match("^/") ? doc.teaserImage : ionasTag.data.script.replace(/[^\/]*([\?#].*)?$/,"") + doc.teaserImage;
				tr.appendChild($e("td", {className: "img"}, $e("img", {src: src, className: doc.defaultTeaserImage ? "default":""})));
			}
			var text = doc.teaserText + " ";
			// Text beschneiden, damit wir mit etwas Glück schon jetzt keinen Überlauf mehr haben
			
			if (ionasTag.data.charsPerLine && ionasTag.data.lines && text.length > ionasTag.data.charsPerLine*ionasTag.data.lines+1) {
				var p = text.lastIndexOf(" ", ionasTag.data.charsPerLine*ionasTag.data.lines);
				if (p != -1) {
					text = text.substring(0, p) + "... ";
				}
			}

			var teaserText, tn;
			var href = "?DAV-UUID=" + doc.uuid;
			tr.appendChild($e("td", {className: "text"},
				$e("h1", $e("a", {href: href, title: doc.headline}, $t(doc.headline))),
				$e("p", teaserText = $e("span", tn = $t(text), $e("a", {href: href}, $t(ionasTag.data.more))))
			));
			
			if (ionasTag.data.charsPerLine && ionasTag.data.lines) {
				while (teaserText.getClientRects().length > ionasTag.data.lines) {
					// Zu viel Teasertext... so lange Wörter abschneiden, bis da nichts mehr umbricht
					var p = text.lastIndexOf(' ', text.length-2);
					if (p == -1) break;
					tn.nodeValue = text = text.substring(0, p) + "... ";
				}
			}
		}
		if (json.more) {
			document.getElementById("ionasTagPopupMore").style.display = "";
		}
		var descEl = document.getElementById("ionasTagPopupDescription");
		if (json.description) {
			descEl.style.display = "";
			descEl.innerHTML = json.description.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&/g,"&amp;").replace(/\n/g,"<br/>");
		} else {
			descEl.style.display = "none";
		}
	},
	loadMore: function() {
		if (!ionasTag.el) return;
		document.getElementById("ionasTagPopupMore").style.display = "none";
		var key = ionasTag.offset+","+ionasTag.tag;
		if (ionasTag.cache[key] != null) {
			ionasTag.render(eval("("+ionasTag.cache[key]+")"));
			ionasTag.loaded = true;
		} else {
			var xhr = new XMLHttpRequest();
			xhr.onreadystatechange = function() {
				if (xhr.readyState != 4) return;
				ionasTag.xhr = false;
				ionasTag.cache[key] = xhr.responseText; 
				
				ionasTag.render(eval("("+xhr.responseText+")"));
				
				ionasTag.loaded = true;
			}
			
			xhr.open("GET", ionasTag.data.script + "?tag=" + encodeURIComponent(ionasTag.tag) + "&offset=" + ionasTag.offset + "&skip=" + ionasTag.data.uuid, true);
			ionasTag.xhr = true;
			xhr.send(null);
		}
		ionasTag.offset++;
	},
	hiding: false,
	hide: function() {
		if (!ionasTag.el) return;
		var div = document.getElementById("ionasTagPopup");
		if (ionasTag.interval != null) clearInterval(ionasTag.interval);
		ionasTag.el = null;
		
		var time = (new Date()).getTime();
		ionasTag.interval = setInterval(function(){
			var elapsed = ((new Date()).getTime() - time)/300;
			if (elapsed >= 1) {
				clearInterval(ionasTag.interval);
				div.style.display = "none";
			} else {
				if (div.style.opacity != null) div.style.opacity = 1-elapsed; else div.style.filter = "alpha(opacity=" + (1-elapsed)*100 + ")";
			}
		}, 30);
	},
	init: function(data) {
		this.data = data;
		if (window.addEventListener) {
			window.addEventListener("load", ionasTag.init2, false);
		} else {
			window.attachEvent("onload", ionasTag.init2);
		}
	},
	init2: function() {
		var l = document.getElementsByTagName("span");
		var set = {}, list = [];
		for (var i = 0; i < l.length; i++) {
			if (l[i].className == "ionastag" && l[i].firstChild && l[i].firstChild == l[i].lastChild && l[i].firstChild.nodeType == 3) {
				// toLowerCase erfolgt erst javaseitig
				var s = l[i].firstChild.nodeValue.replace(/^\s+/,"").replace(/\s+$/,"");
				if (set[s] == undefined) {
					set[s] = list.length;
					list.push("&tag=" + encodeURIComponent(s));
				}
			}
		}
		if (!list.length) return;
		var xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function() {
			if (xhr.readyState != 4) return;
			var json = eval(xhr.responseText);
			if (json) {
				for (var i = 0; i < l.length; i++) {
					if (l[i].className == "ionastag" && l[i].firstChild && l[i].firstChild == l[i].lastChild && l[i].firstChild.nodeType == 3) {
						var index = set[l[i].firstChild.nodeValue.replace(/^\s+/,"").replace(/\s+$/,"")];
						if (index != undefined && json[index]) {
							l[i].className = "ionastagactive";
							l[i].onmouseover = function() {
								ionasTag.setVisibleDelayed(true, this);
							};
							l[i].onmouseout = function() {
								ionasTag.setVisibleDelayed(false);
							};
						}
					}
				}
			}
		};
		xhr.open("GET", ionasTag.data.script + "?mode=enum&skip=" + ionasTag.data.uuid + list.join(""), true);
		xhr.send(null);
	},
	timeout: null,
	setVisibleDelayed: function(show, el) {
		if (ionasTag.timeout != null) {
			clearTimeout(ionasTag.timeout);
		}
		ionasTag.timeout = setTimeout(function(){ ionasTag.timeout = null; show ? ionasTag.show(el) : ionasTag.hide(); }, 500);
	}
};
