// ---------------------------------------------------------------
// Class NiceTitles
// (C) Copyright by Publicform GmbH (www.publicform.de)
// based on nicetitle.js by Kryogenix (www.kryogenix.org/code/browser/nicetitle/)
//
// Version: 1.0
// Date: 2005-06-02
// Author: Andreas Doelling (doelling@publicform.de)
//
// Creates dynamic message boxes from title attributes of all 
// elements of the types specified on initialization.
// ---------------------------------------------------------------

function NiceTitles(tooltipId) {
	// -----------------------------------------------------
	// Properties
	// -----------------------------------------------------
	this.elementTypes = new Array();
	this.cssClassName = '';
	this.tooltipObj = document.getElementById(tooltipId);
	
	
	// -----------------------------------------------------
	// Method init
	// Searches for elements with title attributes and 
	// converts them to nicetitle attributes.
	// -----------------------------------------------------
	this.init = function(elementTypes) {
		if (!document.createElement || !document.getElementsByTagName) {
			return;
		}
		for(var i=0; i<elementTypes.length; i++) {
			var elements = new Array();
			var classRegExp = new RegExp(this.cssClassName);
			elements = document.getElementsByTagName(elementTypes[i]);
			for (var k=0; k<elements.length; k++) {
				var el = elements[k];
				if (el.title && (this.cssClassName == '' || el.className.match(classRegExp))) {
					el.setAttribute("nicetitle", el.title);
					el.removeAttribute("title");
					el.style.cursor = "help";
				}
			}
		}
	}
	
	
	// -----------------------------------------------------
	// Method setCssClassName
	// Sets the cssClassName property and thus restricts the 
	// display of "nice titles" to elements with that class.
	// Has to be called BEFORE init()!
	// -----------------------------------------------------
	this.setCssClassName = function(className) {
		this.cssClassName = className;
	}
	
	
	// -----------------------------------------------------
	// Method mouseover
	// Handles mouseover events propagated by a Controller object.
	// -----------------------------------------------------
	this.mouseover = function(evt) {
		if(this != arguments.callee.scope){
			if(typeof arguments.callee.apply == "function") {
			  	return arguments.callee.apply(arguments.callee.scope, arguments);
			} else {
		  		return  arguments.callee.scope.mouseover(evt);
			}
	    }
		var srcElement = (evt.srcElement)? evt.srcElement : evt.target;
		if(this.isResponsible(srcElement)) {
			pos = this.getMousePosition(evt);
			srcElement = this.getProperElement(srcElement);
			this.showNiceTitle(srcElement, pos);
			return false;
		} else {
			return true;
		}
	}
	this.mouseover.scope = this;
	
	
	// -----------------------------------------------------
	// Method focus
	// Handles focus events propagated by a Controller object.
	// -----------------------------------------------------
	this.focus = this.mouseover;
	this.focus.scope = this;
	
	// -----------------------------------------------------
	// Method mouseout
	// Handles mouseout events propagated by a Controller object.
	// -----------------------------------------------------
	this.mouseout = function(evt) {
		if(this != arguments.callee.scope){
			if(typeof arguments.callee.apply == "function") {
			  	return arguments.callee.apply(arguments.callee.scope, arguments);
			} else {
		  		return  arguments.callee.scope.mouseout(evt);
			}
	    }
		var srcElement = (evt.srcElement)? evt.srcElement : evt.target;
		if(this.isResponsible(srcElement)) {
			this.hideNiceTitle();
			return false;
		} else {
			return true;
		}
	}
	this.mouseout.scope = this;
	
	
	// -----------------------------------------------------
	// Method blur
	// Handles blur events propagated by a Controller object.
	// -----------------------------------------------------
	this.blur = this.mouseout;
	this.blur.scope = this;
	
	
	// -----------------------------------------------------
	// Method mousemove
	// Handles mousemove events propagated by a Controller object.
	// -----------------------------------------------------
	this.mousemove = function(evt) {
		if(this != arguments.callee.scope){
			if(typeof arguments.callee.apply == "function") {
			  	return arguments.callee.apply(arguments.callee.scope, arguments);
			} else {
		  		return  arguments.callee.scope.mousemove(evt);
			}
	    }
		var srcElement = (evt.srcElement)? evt.srcElement : evt.target;
		if(this.isResponsible(srcElement)) {
			pos = this.getMousePosition(evt);
			this.positionNiceTitle(pos);
			return false;
		} else {
			return true;
		}
	}
	this.mousemove.scope = this;
	
	
	// -----------------------------------------------------
	// Method isResponsible
	// Checks if the current NiceTitle instance is responsible for
	// handling the propagated event, i.e. if the source element
	// is of the allowed element type and has a nicetitle attribute.
	// -----------------------------------------------------
	this.isResponsible = function(srcElement) {
		while(srcElement.tagName != "BODY") {
			if((typeof srcElement.getAttribute == 'function' || typeof srcElement.getAttribute == 'object') && srcElement.getAttribute("nicetitle") != null) {
				return true;
				break;
			}
			srcElement = srcElement.parentNode;
		}
		return false;
	}
	
	
	// -----------------------------------------------------
	// Method getProperElement
	// Looks for the right element which really contains a nicetitle
	// attribute (e.g. returns the A element which wraps a linked 
    // image).
	// -----------------------------------------------------
	this.getProperElement = function(srcElement) {
		while(srcElement.tagName != "BODY") {
			if((typeof srcElement.getAttribute == 'function' || typeof srcElement.getAttribute == 'object') && srcElement.getAttribute("nicetitle") != null) {
				break;
			}
			srcElement = srcElement.parentNode;
		}
		return srcElement;
	}
	
	
	// -----------------------------------------------------
	// Method showNiceTitle
	// Displays the content of the nicetitle attribute as a
	// tooltip.
	// -----------------------------------------------------
	this.showNiceTitle = function(srcElement, pos) {
		posx = pos[0];
		posy = pos[1];
		with(this.tooltipObj) {
			innerHTML = srcElement.getAttribute("nicetitle");
			style.left = (posx + 18) + 'px'
			style.top = (posy + 24) + 'px'
			style.visibility = "visible";
		}
	}
	
	// -----------------------------------------------------
	// Method hideNiceTitle
	// Hides the tooltip.
	// -----------------------------------------------------
	this.hideNiceTitle = function() {
		this.tooltipObj.style.visibility = "hidden";
	}
	
	
	// -----------------------------------------------------
	// Method positionNiceTitle
	// Moves the tooltip to the right place.
	// -----------------------------------------------------
	this.positionNiceTitle = function(pos) {
		posx = pos[0];
		posy = pos[1];
		with(this.tooltipObj) {
			style.left = (posx + 10) + 'px';
			style.top = (posy + 15) + 'px';
		}
	}
	
	
	// -----------------------------------------------------
	// Method getMousePosition
	// Returns the coordinates of the event's mouse position
	// as an array.
	// -----------------------------------------------------
	this.getMousePosition = function(evt) {
		var pos = new Array();
		if (evt.pageX || evt.pageY) {
			pos[0] = parseInt(evt.pageX);
			pos[1] = parseInt(evt.pageY);
		} else if (evt.clientX || evt.clientY) {
			if(document.all && navigator.appVersion.indexOf("MSIE 5.5") != -1) {
				pos[0] = parseInt(evt.clientX) + parseInt(document.body.scrollLeft);
				pos[1] = parseInt(evt.clientY) + parseInt(document.body.scrollTop);
			} else {
				pos[0] = parseInt(evt.clientX) + parseInt(document.documentElement.scrollLeft);
				pos[1] = parseInt(evt.clientY) + parseInt(document.documentElement.scrollTop);
			}
		}
		return pos;
	}
}


