var sOnlyInThisID = '';
function Tooltips(sTemplate, nDelay, nStringMaxLength, nMarginX, nMarginY, sContainerID, sClassName){
	var oTimer;
	var isActive = false;
	var sNameSpaceURI = 'http://www.w3.org/1999/xhtml';
	if(!sTemplate){ sTemplate = 'attr(tooltips)';}
	if(!nDelay || nDelay <= 0){ nDelay = false;}
	if(!nStringMaxLength){ nStringMaxLength = 300; }
	if(!nMarginX){ nMarginX = 15; }
	if(!nMarginY){ nMarginY = 15; }
	if(!sContainerID){ sContainerID = 'tooltipscontainer';}
	if(!sClassName){ sClassName = 'tooltips';}
	var oContainer = document.getElementById(sContainerID);
	if(!oContainer){
		oContainer = document.createElementNS ? document.createElementNS(sNameSpaceURI, 'div') : document.createElement('div');
		oContainer.setAttribute('id', sContainerID);
		oContainer.className = sClassName;
		oContainer.style.display = 'none';
		document.getElementsByTagName('body').item(0).appendChild(oContainer);
	}
	this.addElements = function addElements(collNodes, sAttribute){
		var currentNode, sTitle;
		for(var i = 0; i < collNodes.length; i++){
			currentNode = collNodes[i];
			sTitle = currentNode.getAttribute(sAttribute);
			if(sTitle){
				currentNode.setAttribute('tooltips', sTitle);
				currentNode.removeAttribute(sAttribute);
				addEvent(currentNode, 'mouseover', show);
				addEvent(currentNode, 'mouseout', hide);
				addEvent(currentNode, 'focus', show);
				addEvent(currentNode, 'blur', hide);
			}
		}
	}
	function show(e){
		if(isActive){ hide(); }
		var oNode = window.event ? window.event.srcElement : e.currentTarget;
		if(!oNode.getAttribute('tooltips')){ 
			while(oNode.parentNode){
				oNode = oNode.parentNode;
				if(oNode.getAttribute('tooltips')){ break;}
			}
		}
		var sOutput = parseTemplate(oNode);
		setContainerContent(sOutput);
		var oPosition = getPosition(e, oNode);
		oContainer.style.left = oPosition.x;
		oContainer.style.top = oPosition.y;
		if(nDelay){
			oTimer = setTimeout(function(){oContainer.style.display = 'block';}, nDelay);
		} else {
			oContainer.style.display = 'block';
		}
		isActive = true;
		window.event ? window.event.cancelBubble = true : e.stopPropagation();
	}
	function hide(){
		clearTimeout(oTimer);
		oContainer.style.display = 'none';
		removeContainerContent();
		isActive = false;
	}
	function setContainerContent(sOutput){
		sOutput = sOutput.replace(/&/g, '&amp;');
		if(document.createElementNS && window.DOMParser){
			var oXMLDoc = (new DOMParser()).parseFromString('<root xmlns=\"'+sNameSpaceURI+'\">'+sOutput+'</root>', 'text/xml');
			var oOutputNode = document.importNode(oXMLDoc.documentElement, true);
			var oChild = oOutputNode.firstChild;
			var nextChild;
			while(oChild){
				nextChild = oChild.nextSibling;
				oContainer.appendChild(oChild);
				oChild = nextChild;
			}
		} else {
			oContainer.innerHTML = sOutput;
		}
	}
	function removeContainerContent(){
		var oChild = oContainer.firstChild;
		var nextChild;
		if(!oChild){ return; }
		while(oChild){
			nextChild = oChild.nextSibling;
			oContainer.removeChild(oChild);
			oChild =  nextChild;
		}
	}
	function getPosition(e, oNode){
		var oViewport = getViewport();
		var oCoords;
		var commonEventInterface = window.event ? window.event : e;
		if(commonEventInterface.type == 'focus'){
			oCoords = getNodePosition(oNode);
			oCoords.x += nMarginX;
			oCoords.y += nMarginY;
		} else {
			oCoords = { x : commonEventInterface.clientX + oViewport.x + nMarginX, y : commonEventInterface.clientY + oViewport.y + nMarginY};
		}
		oContainer.style.visiblity = 'hidden';
		oContainer.style.display =  'block';
		var containerWidth = oContainer.offsetWidth;
		var containerHeight = oContainer.offsetHeight;
		oContainer.style.display = 'none';
		oContainer.style.visiblity = 'visible';
		if(oCoords.x + containerWidth + 10 >= oViewport.width + oViewport.x){
			oCoords.x = oViewport.width + oViewport.x - containerWidth - 10;
		}
		if(oCoords.y + containerHeight + 10 >= oViewport.height + oViewport.y){
			oCoords.y = oViewport.height + oViewport.y - containerHeight - oNode.offsetHeight - 10;
		}
		oCoords.x += 'px';
		oCoords.y += 'px';
		return oCoords;
	}
	function parseTemplate(oNode){
		var sAttribute, collOptionalAttributes;
		var oFound = {};
		var sResult = sTemplate;
		if(sResult.match(/content\(\)/)){
			sResult = sResult.replace(/content\(\)/g, getContentOfNode(oNode));
		}
		var collSearch = sResult.split(/attr\(/);
		for(var i = 1; i < collSearch.length; i++){
			sAttribute = collSearch[i].split(')')[0];
			oFound[sAttribute] = oNode.getAttribute(sAttribute);
			if(oFound[sAttribute] && oFound[sAttribute].length > nStringMaxLength){
				oFound[sAttribute] = oFound[sAttribute].substring(0, nStringMaxLength) + '...';
			}
		}
		var collOptional = sResult.split('?')
		for(var i = 1; i < collOptional.length; i += 2){
			collOptionalAttributes = collOptional[i].split('attr(');
			for(var j = 1; j < collOptionalAttributes.length; j++){
				sAttribute = collOptionalAttributes[j].split(')')[0];
				if(!oFound[sAttribute]){
					sResult = sResult.replace(new RegExp('\\?[^\\?]*attr\\('+sAttribute+'\\)[^\\?]*\\?', 'g'), '');
				}
			}
		}
		sResult = sResult.replace(/\?/g, '');
		for(sAttribute in oFound){
			sResult = sResult.replace('attr\('+sAttribute+'\)', oFound[sAttribute]);
		}
		return sResult;
	}	
	function getContentOfNode(oNode){
		var sContent = '';
		var oSearch = oNode.firstChild;
		while(oSearch){
			if(oSearch.nodeType == 3){
				sContent += oSearch.nodeValue;
			} else if(oSearch.nodeType == 1 && oSearch.hasChildNodes){
				sContent += getContentOfNode(oSearch);
			}
			oSearch = oSearch.nextSibling
		}
		return sContent;
	}
	function getNodePosition(oNode){
		var x = 0;
		var y = 0;
		do {
			if(oNode.offsetLeft){ x += oNode.offsetLeft }
			if(oNode.offsetTop){ y += oNode.offsetTop }
		}	while((oNode = oNode.offsetParent) && !document.all)
		return {x : x, y : y}
	}
	function getViewport(){
		var width = 0;
		var height = 0;
		var x = 0;
		var y = 0;
		if(document.documentElement && document.documentElement.clientWidth){
			width = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
			x = document.documentElement.scrollLeft;
			y = document.documentElement.scrollTop;
		} else if(document.body && document.body.clientWidth){
			width = document.body.clientWidth;
			height = document.body.clientHeight;
			x = document.body.scrollLeft;
			y = document.body.scrollTop;
		}
		if(window.innerWidth){ 
			width = window.innerWidth - 18;
			height = window.innerHeight - 18;
		}
		if(window.pageXOffset){
			x = window.pageXOffset;
			y = window.pageYOffset;
		} else if(window.scrollX){
			x = window.scrollX;
			y = window.scrollY;
		}
		return {width : width, height : height, x : x, y : y };
	}
}

function addEvent(obj, evType, fn){
	if(obj.addEventListener){
		obj.addEventListener(evType, fn, false); 
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent('on'+evType, fn);
		return r;
	} else {
		return false;
	}
}

Tooltips.autoCreation = function(){
	if(!document.getElementsByTagName){ return; }
	Tooltips.autoCreated = new Object();
	Tooltips.autoCreated.anchors = new Tooltips("<div class=\"titletext\">attr(tooltips)</div><div class=\"destination\">attr(href)</div>", 600);
	Tooltips.autoCreated.acronyms = new Tooltips("<div class=\"titletext\">content(): attr(tooltips)</div>", 600);
	Tooltips.autoCreated.images = new Tooltips("<div class=\"titletext\">attr(tooltips)</div>", 600);
	if (sOnlyInThisID) {
		oNode = document.getElementById(sOnlyInThisID);
	} else {
		oNode = null;
	}
	if (!oNode) {
		oNode = document;
	}
	Tooltips.autoCreated.images.addElements(oNode.getElementsByTagName("a"), "title");
	Tooltips.autoCreated.acronyms.addElements(oNode.getElementsByTagName("acronym"), "title");
	Tooltips.autoCreated.images.addElements(oNode.getElementsByTagName("img"), "alt"); 
	Tooltips.autoCreated.images.addElements(document.getElementsByTagName("img"), "title"); 
}

addEvent(window, "load", Tooltips.autoCreation);