/**
 * Bubble Helper Class
 *
 * example usage
 * Bubble.init("externalURL", function (D) {
 *   return D.href + '<br /><img src="easy-coding-logo.png">';
 * });
 *
 * @author      Torben Brodt <easy-coding.de>
 * @url		http://trac.easy-coding.de/trac/wcf/wiki/Thumbshots
 * @license	GNU Lesser General Public License <http://opensource.org/licenses/lgpl-3.0.html>
 */
var Bubble = {
	Cursor: {
		x: 0,
		y: 0
	},
	Offset: {
		x: 0,
		y: 0
	},
	blacklist : {},
	div: document.getElementById("BubbleDiv"),
	init: function (ParentID, showRef) {
		Bubble.create();
		Bubble.addEvent(window, "mousemove", Bubble.getCurPos);
		Bubble.addEvent(window, "resize", Bubble.getOffset);
		Bubble.addEvent(window, "scroll", Bubble.getOffset);
		var B = Bubble.getElementsByClassName(ParentID), A = B.length;
		for (i = 0; i < A; i++) {
			if(Bubble.blacklist.href && !B[i].href.match(Bubble.blacklist.href)) {
				Bubble.addEvent(B[i], "mouseover", function () {
					Bubble.show(this, showRef);
				});
				Bubble.addEvent(B[i], "mouseout", function () {
					Bubble.hide();
				});
			}
		}
	},
	/**
	 * currently only href is supported
	 */
	disallow: function (attr, str) {
		Bubble.blacklist.href = str;
	},
	show: function (D, showRef) {
		Bubble.div.style.display = "block";
		Bubble.div.innerHTML = showRef(D);
		Bubble.getCurPos();
		Bubble.getOffset();
		Bubble.div.style.left = (Bubble.Cursor.x + Bubble.Offset.x) + "px";
		Bubble.div.style.top = (Bubble.Cursor.y + Bubble.Offset.y) + "px";
	},
	hide: function () {
		Bubble.div.innerHTML = "";
		Bubble.div.style.display = "none";
	},
	create: function () {
		Bubble.div = document.createElement("div");
		Bubble.div.id = "BubbleDiv";
		document.getElementsByTagName("body")[0].appendChild(Bubble.div);
		Bubble.div.style.position = 'absolute';
	},
	getOffset: function () {
		var Px = 10, Py = 20;
		var Cx = Bubble.Cursor.x, Cy = Bubble.Cursor.y;
		var w = Bubble.div.clientWidth || 150, h = Bubble.div.clientHeight || 150;
		
		var Ww, Wh, Wx, Wy;

		var E = window;
		if (typeof(E.innerWidth) === "number") {
			Ww = E.innerWidth;
			Wh = E.innerHeight;
			Wx = E.pageXOffset;
			Wy = E.pageYOffset;
		} else if (document.documentElement) {
			F = document.documentElement;
			if (F.clientWidth || F.clientHeight) {
				Ww = F.clientWidth;
				Wh = F.clientHeight;
				Wx = F.scrollLeft;
				Wy = F.scrollTop;
			}
		}

		// top right
		if ((Cx - Wx) > (Ww / 2) && (Cy - Wy) < h) {
			Px = -w - Px;
		}
		// bottom left
		else if ((Cx - Wx) < (Ww / 2) && (Cy - Wy) > (Wh / 2)) {
			Py = -h - Py;
		}
		// bottom right
		else if ((Cx - Wx) > (Ww / 2) && (Cy - Wy) > (Wh / 2)) {
			Px = -w - Px;
			Py = -h - Py;
		}
		
		Bubble.Offset = {
			x: Px,
			y: Py
		};
	},
	getCurPos: function (C) {
		C = C ? C : window.event;
		if (C && typeof(C.pageX) !== "number" && typeof(C.clientX) === "number") {
			C.pageX = C.clientX;
			C.pageY = C.clientY;
			if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
				C.pageX += document.body.scrollLeft;
				C.pageY += document.body.scrollTop;
			} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
				C.pageX += document.documentElement.scrollLeft;
				C.pageY += document.documentElement.scrollTop;
			}
		}
		if(C) {
			Bubble.Cursor = {
				x: C.pageX,
				y: C.pageY
			};
		}
	},
	addEvent: function( obj, type, fn ) {
		if ( window.addEventListener ) {
			obj.addEventListener( type, fn, false );
		} else {
			obj['e'+type+fn] = fn;
			obj[type+fn] = function() { 
				obj['e'+type+fn]( window.event );
			};
			obj.attachEvent( 'on'+type, obj[type+fn] );
		}
	},
	getElementsByClassName: function (searchClass) {
		var classElements = [], i, j, els, pattern;

		els = document.getElementsByTagName('*');
		pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
		for (i = 0, j = 0; i < els.length; i += 1) {
			if (pattern.test(els[i].className)) {
				classElements[j] = els[i];
				j += 1;
			}
		}
		return classElements;
	}
};

