/**
 * @author Robert Kunze
 *
 * This script will enable the user to add help signs (question marks) to any position of the page and assign it a tooltip.
 *
 *
 */
// first initialize the basic framework
_ = {};
(function() {
	this.$break = {
		"name": "Break Exception"
	};
	this.each = function(array, func) {
		if (!Array.prototype.forEach) {
			for (var i = 0, length = array.length; i < length; i++) {
				try {
					func(array[i], i);
				} catch (e) {
					break;
				};
							}
		} else {
			array.forEach(func);
		}
	};
	this.has = function(array, item) {
		var found = false;
		each(array, function(el) {
			if (el == item) {
				found = true;
				throw $break;
			}
		});
		return found;
	};
	this.$ = function(id) {
		return document.getElementById(id);
	};
	this.$$ = function(className) {
		var elements = [];
		each(document.getElementsByTagName("*"), function(item) {
			if (has(item.className.split(" "), className)) {
				elements.push(item);
			}
		});
		return elements;
	};
	this.create = function(name, attr) {
		var el = document.createElement(name);
		for (var each in attr) {
			el.setAttribute(each, attr[each]);
		}
		return el;
	};
	this.remove = function(element) {
		element.parentNode.removeChild(element);
	};
	this.update = function(element, content) {
		if (typeof(content) == "string") {
			element.innerHTML = content;
		} else if (typeof(content) == "object" && !content.ELEMENT_NODE) {
			each(content, function(item) {
				update(element, item);
			});
		} else {
			element.appendChild(content);
		}
		return element;
	};
	this.listen = function(element, event, func, context) {
		if (element.addEventListener) {
			element.addEventListener(event, function(event) {
				if (func.apply((context != null ? context : this), [event]) === false) {
					event.cancelBubble = true;
					try {
						event.stopPropagation();
					} catch (e){};
					try {
						event.preventDefault();
					} catch (e) {};
					event.returnValue = false;
					return false;
				}
			}, false);
		} else if (element.attachEvent) {
			element.attachEvent("on" + event, function(event) {
				if (func.apply((context != null ? context : this), [event]) === false) {
					event.cancelBubble = true;
					try {
						event.stopPropagation();
					} catch (e){};
					try {
						event.preventDefault();
					} catch (e) {};
					event.returnValue = false;
					return false;
				}
			});
		} else {
			var old = element["on"+event];
			element["on" + event] = function(event) {
				if ((typeof(old) == "function" && old.apply(element, [event])) || typeof(old) != "function") {
					if (func.apply((context != null ? context : this), [event]) === false) {
						event.cancelBubble = true;
						try {
							event.stopPropagation();
						} catch (e){};
						try {
							event.preventDefault();
						} catch (e) {};
						event.returnValue = false;
						return false;
					}
				}
			};
		}
	};
	this.findAtPos = function(x, y) {
		var l=[];
		var f = 9999999999999;
		$$("div,li,td,span,b,em").each(function(item) {
			if (item.hasClassName("qw_dynamic_tooltip")) return;
			var xy = item.cumulativeOffset();
			if(xy[0] <= x && xy[1] <= y && item.clientWidth + xy[0] >= x && item.clientHeight + xy[1] >= y) {
				var A = item.clientWidth * item.clientHeight;
				if(A < f) {
					f = A; 
					l = item;
				}
			}
		});
		console.log(l);
		return l;
	};
	this.collectTags = function(obj) {
		var path = "";
		var idx = function(el){
			var c = 1;
			for (var s = el.previousSibling; s; s = s.previousSibling) {
				if (s.nodeType == 1 && s.tagName == el.tagName) c++;
			}
			return c;
		};
		for (;obj && obj.nodeType == 1; obj = obj.parentNode) {
			var xname = obj.tagName;
			var xi = idx(obj);
			if (xi > 1) xname += "["+xi+"]";
			path = "/" + xname + path;
		}
		return path;
	};
	this.selectCollectedTag = function(xpath) {
		var tags = xpath.split("/");
		tags.splice(0, 1);
		var root = document;
		var reg = /[a-zA-Z]\[([0-9]+)\]/;
		this.each(tags, function(tag){
			var num = 0;
			if (reg.exec(tag)) {
				num = parseInt(RegExp.$1) - 1;
				tag = tag.replace(/\[[0-9]+\]/, "");
			} 
			for (var i = 0, c = 0, len = root.childNodes.length; i < len; i++) {
				var node = root.childNodes[i];
				if (node.tagName == tag && node.nodeType == 1) {
					if (c == num) {
						root = node;
						break;
					}
					c++;
				}
			}
		});
		return root;
	};
}).apply(_);

// running the actual code
(function(_) {
	var data = MD5(location.href);
	var file = "cache/help/"+data+".json";
	var renderHelp = function(txt) {
		var list = eval(txt);
		_.each(list, function(tip){
			var qm = _.update(_.create("a", {"class": "qw_dynamic_tooltip_loaded tooltip", href: "javascript:;", style: "text-decoration:none;color:#666;line-height:1em;font-size:13px;height:15px;font-family:Arial,Helvetica,sans-serif;position:absolute;left:"+tip.settings.x+"px;top:"+tip.settings.y+"px;z-index:10000000;cursor:pointer;background-color: #efefef;border: 1px solid #ccc;-moz-border-radius:16px;-webkit-border-radius:16px;"}), "&nbsp;?&nbsp;");
			qm.id = "__qm_"+tip.help_id;
			var parent = _.selectCollectedTag(tip.settings.path);
			_.update(parent, qm);
			qm.tip = tip.settings.hint;
			_.listen(qm, "click", function(event){
				if (this.tooltip != null) {
					_.remove(this.tooltip);
				}
				var content = this.tip;
				var x = event.clientX;
				var y = (event.clientY + 20);
				var owidth = document.body.clientWidth * 1.0;
				var ccontainer = _.create("div", {"class": "tooltip", style: "position:absolute;left:"+x+"px;top:"+y+"px;"});
				ccontainer.innerHTML = content+"<br/><a href='' onclick='this.parentNode.parentNode.removeChild(this.parentNode);return false;' style='display:block;margin-top:10px;font-size:11px;'>click here to close</div>";
				document.body.appendChild(ccontainer);
				if (ccontainer.clientWidth + x > owidth) {
					ccontainer.style.left = (owidth - ((x + ccontainer.clientWidth) - owidth) - (ccontainer.clientWidth - ((x + ccontainer.clientWidth) - owidth)) - 5)+"px;";
				}
				return false;
			}, qm);
			_.listen(qm, "mouseover", function(event){
				var content = this.tip;
				var x = event.clientX;
				var y = (event.clientY + 20);
				var owidth = document.body.clientWidth * 1.0;
				var ccontainer = _.create("div", {"class": "tooltip", style: "position: absolute; left: "+x+"px; top: "+y+"px;"});
				ccontainer.innerHTML = content + "<br/><div style='margin-top:10px;font-size:11px;'>click to focus</div>";
				this.tooltip = ccontainer;
				document.body.appendChild(ccontainer);
				if (this.tooltip.clientWidth + x > owidth) {
					this.tooltip.style.left = (owidth - ((x + this.tooltip.clientWidth) - owidth) - (this.tooltip.clientWidth - ((x + this.tooltip.clientWidth) - owidth)) - 5)+"px;";
				}
				return false;
			}, qm);
			_.listen(qm, "mouseout", function(event){
				if (this.tooltip != null) {
					_.remove(this.tooltip);
				}
			}, qm);
			if (!parent.style.position || parent.style.position == "fixed") {
				parent.style.position = "relative";
			}
		});
	};
	new Ajax.Request(file, {
		onSuccess: function(req) {
			renderHelp(req.responseText);
		}
	})
})(_);