bubbleHelp = {
	holderId : "bubbleHolder",
	positionStates : [ 
		["topleft",	170,	10],	// className, x-correction, y-correction
		["topright",	20,	10],	
		["bottomleft",	170,	-10],	
		["bottomright",	20,	-10]	
	],
	divClassNames : [ "", "bottom", "middle", "content"], // one required!
	width : 195, 		// pixels
	hideTimeout : 200,	// miliseconds
	

	// USER LEVEL FUNCTIONS
		
	init : function() {
		// create holder element
		bubbleHelp.holder = document.createElement("div");
		bubbleHelp.holder.id = bubbleHelp.holderId;
		document.body.appendChild(bubbleHelp.holder);
		
		bubbleHelp.holder.style.position = "absolute";
		bubbleHelp.holder.style.visibility = "hidden";	
		bubbleHelp.holder.style.width = bubbleHelp.width + "px";	
		
		// create stylestate element
		bubbleHelp.stateHolder = document.createElement("div");
		bubbleHelp.stateHolder.className = bubbleHelp.positionStates[0][0];
		bubbleHelp.holder.appendChild(bubbleHelp.stateHolder);
		
		// create other nested divs for styling purposes
		var tmp = new Array();		
		tmp[-1] = bubbleHelp.stateHolder;
		
		for (var i=0; i < bubbleHelp.divClassNames.length; i++) {
			tmp[i] = document.createElement("div");
			tmp[i].className = bubbleHelp.divClassNames[i];			
			tmp[i-1].appendChild(tmp[i]);			
		}		
		bubbleHelp.contentHolder = tmp[i-1];
	
		// setup bubbleHelp holder
		bubbleHelp.currentX = bubbleHelp.currentY = 0;		
		bubbleHelp.currentWidth = bubbleHelp.width;
		bubbleHelp.currentHeight = 50;

		bubbleHelp.positionState = 1;
				
		bubbleHelp.getBrowserArea();
		
		evt.add(document.body, "mousemove", bubbleHelp.getCoords);
		evt.add(window, "resize", bubbleHelp.getBrowserArea);				
		
		window.setInterval(bubbleHelp.refresh, 10);
					
		return true;
	},
	
	// attach bubbleHelp message on element
	attach : function(elm, message) {
		elm.message = message;
		evt.add(elm, "mouseover", bubbleHelp.show);
		evt.add(elm, "mouseout", bubbleHelp.triggerHide);
		
		return true;
	},


	// LOW LEVEL FUNCTIONS

	show : function(e) {
		e = evt.fix(e);
		window.clearInterval(bubbleHelp.intervalId);

		bubbleHelp.contentHolder.innerHTML = e.target.message;
		bubbleHelp.getCoords(e);

		bubbleHelp.holder.style.visibility = "visible";

		bubbleHelp.currentWidth = bubbleHelp.holder.offsetWidth;
		bubbleHelp.currentHeight = bubbleHelp.holder.offsetHeight;
	
		bubbleHelp.holder.style.visibility = "visible";

		return true;
	},
	
	triggerHide : function() { 
		bubbleHelp.intervalId = window.setInterval(bubbleHelp.hide, bubbleHelp.hideTimeout);

		return true;		
	},

	hide : function() {
		bubbleHelp.holder.style.visibility = "hidden";
		bubbleHelp.holder.style.left = -bubbleHelp.width + "px";

		window.clearInterval(bubbleHelp.intervalId);

		return true;		
	},
	
	getCoords : function(e) {
		// damn browser sniffing
		var scrollX = (document.all) ? document.body.scrollLeft : window.scrollX;
		var scrollY = (document.all) ? document.body.scrollTop : window.scrollY;

		var targetX = e.clientX;
		var targetY = e.clientY;
		
		var posY = "t"; // default position is top right
		var posX = "r";
		
		if(targetY-bubbleHelp.currentHeight-bubbleHelp.positionStates[0][2] <= 0) posY = "b";
			else if(targetY+bubbleHelp.currentHeight >= bubbleHelp.browserH) posY = "t";

		if(targetX <= 0) posX = "r";
			else if(targetX+bubbleHelp.currentWidth-bubbleHelp.positionStates[1][1] >= bubbleHelp.browserW) posX = "l"; 
				
		switch (posY+posX) {
			case "tl": bubbleHelp.positionState = 0; break;
			case "tr": bubbleHelp.positionState = 1; break;
			case "bl": bubbleHelp.positionState = 2; break;
			case "br": bubbleHelp.positionState = 3; break;
		}
		bubbleHelp.currentX = targetX+scrollX;
		bubbleHelp.currentY = targetY+scrollY;
	},
	
	getBrowserArea : function() {
		bubbleHelp.browserW = document.body.clientWidth;
		bubbleHelp.browserH = document.body.clientHeight;
	},
	
	refresh : function() {
		var Xcorr = 0;
		var Ycorr = 0;
		
		switch (bubbleHelp.positionState) {
			case 0:
				Xcorr = -bubbleHelp.positionStates[bubbleHelp.positionState][1];
				Ycorr = -bubbleHelp.positionStates[bubbleHelp.positionState][2] - bubbleHelp.currentHeight;
				break;
			case 1:
				Xcorr = -bubbleHelp.positionStates[bubbleHelp.positionState][1];
				Ycorr = -bubbleHelp.positionStates[bubbleHelp.positionState][2] - bubbleHelp.currentHeight;
				break;
			case 2:
			case 3:
				Xcorr = -bubbleHelp.positionStates[bubbleHelp.positionState][1];
				Ycorr = -bubbleHelp.positionStates[bubbleHelp.positionState][2];
				break;				
		}
	
		if (bubbleHelp.holder.style.visibility == "visible") {
			if (bubbleHelp.stateHolder.className != bubbleHelp.positionStates[bubbleHelp.positionState][0])
				bubbleHelp.stateHolder.className = bubbleHelp.positionStates[bubbleHelp.positionState][0];

			bubbleHelp.holder.style.left = bubbleHelp.currentX + Xcorr + "px";	
			bubbleHelp.holder.style.top = bubbleHelp.currentY + Ycorr + "px";
		}
	}

}

evt.add(window, "load", bubbleHelp.init);	
