/** 
  * DHTML Tooltip class with fading in and out effects. 
  * There can be only one popup at a time. 
  * 
  * @author Ivars Veksins (ivarsv@gmail.com) 
  */

function DHTML_Tooltip()
{
	
}

// implement garbage which will call dispose method on unload 
// we can release our globals and any other references 
IMPLEMENT_GARBAGE(DHTML_Tooltip); 

/** 
  * Called by garbage collector. 
  */ 
DHTML_Tooltip.dispose = function() 
{ 
	// delete references
	DHTML_Tooltip.hWnd = null;
	DHTML_Tooltip.header = null;
	DHTML_Tooltip.footer = null;
	DHTML_Tooltip.content = null;
	
	DHTML_Tooltip.DELAY = null; 
	DHTML_Tooltip.OPACITY = null; 
	DHTML_Tooltip.PADDING = null; 
	DHTML_Tooltip.FORCE_HIDE = null; 	
	
	DHTML_Tooltip.ABSOLUTE = null; 
	DHTML_Tooltip.NULL = null; 
}

// main dom reference 
DHTML_Tooltip.hWnd = null;

// reference to footer, header and content 
DHTML_Tooltip.header = null;
DHTML_Tooltip.footer = null;
DHTML_Tooltip.content = null;

DHTML_Tooltip.DELAY = 30; 
DHTML_Tooltip.OPACITY = "0.0";
DHTML_Tooltip.PADDING = 10; 
// do now allow showing again 
DHTML_Tooltip.FORCE_HIDE = false; 

// styles 
DHTML_Tooltip.ABSOLUTE = 1; 
DHTML_Tooltip.NULL = 0; 

/** 
  * Attaches tooltip to an element. Can use styles to attach in different ways 
  * @argument name of element id in the document 
  * @argument text tooltip will contain 
  * @argument styles (uses bitwise operations to extract information) 
  */
DHTML_Tooltip.attach = function (element_name, text, styles, baloonPosition, baloonDirection) 
{ 
	var element = document.getElementById(element_name); 
	
	if (!element) 
		return false; 
		
	// set styles to element 
	element.$styles = styles; 
	element.$text = text; 

	// remove all tags 
	DHTML_Tooltip.remove_alt_tags(element); 
	
	// creates tooltip
	if (DHTML_Tooltip.hWnd == null) 
		DHTML_Tooltip.create(); 
	
	
	if (!baloonPosition) // Added by KH
		baloonPosition = "0";
		
	element.$baloonPosition = baloonPosition;// Added by KH

	if (!baloonDirection) // Added by KH
		baloonDirection = "right";
		
	element.$baloonDirection = baloonDirection;// Added by KH
	

	Effects.set_opacity(DHTML_Tooltip.hWnd,"0.0");		
	DHTML_Tooltip.OPACITY = "0.0"; 
		
	// install events
	event_install(element,"onclick", DHTML_Tooltip.mouse_click_element); 
	
	event_install(element,"onmouseover", DHTML_Tooltip.mouse_over_element); 
	event_install(element,"onmouseout",  DHTML_Tooltip.mouse_out_element); 
	
	
	event_install(DHTML_Tooltip.hWnd,"onmouseover", DHTML_Tooltip.force_hide);	
	// delete reference 
	element = null; 

	return true; 
}

/** 
  * Creates a dom element with header, footer, content areas 
  */
DHTML_Tooltip.create = function() 
{ 
	
	// create main wrapper
	DHTML_Tooltip.hWnd = document.createElement("DIV"); 
	// apply attributes
	DHTML_Tooltip.hWnd.setAttribute("id","jstooltip"); 
	DHTML_Tooltip.hWnd.className = "jstooltip"; 
	
	// create header 
	DHTML_Tooltip.header = document.createElement("DIV")
	DHTML_Tooltip.header.className = "jstooltip_header"; 
	
	// create content 
	DHTML_Tooltip.content = document.createElement("DIV")
	DHTML_Tooltip.content.className = "jstooltip_content"; 
	
	// create footer 
	DHTML_Tooltip.footer = document.createElement("DIV")
	DHTML_Tooltip.footer.className = "jstooltip_footer"; 
	
	
	DHTML_Tooltip.hWnd.appendChild(DHTML_Tooltip.header); 
	DHTML_Tooltip.hWnd.appendChild(DHTML_Tooltip.content); 
	DHTML_Tooltip.hWnd.appendChild(DHTML_Tooltip.footer); 	
	
}

/**  
 * Mouse over event handler. 
 */
DHTML_Tooltip.mouse_over_element = function() 
{
	var tooltip = DHTML_Tooltip.hWnd; 
	
	if (!tooltip) 
		return; 

	// check if forced to hide 
	if (DHTML_Tooltip.FORCE_HIDE && DHTML_Tooltip.OPACITY  != "0.0") {
		return; 
	} else { 
		DHTML_Tooltip.FORCE_HIDE = false; 
	}
	
	// check if the same element 
	if (tooltip.parentNode && this.id != tooltip.parentNode.id) {
		DHTML_Tooltip.clean(); 
		tooltip.parentNode.removeChild(tooltip); 
	} 

	if (this.$styles & DHTML_Tooltip.ABSOLUTE) { 
		document.body.appendChild(tooltip); 
	} else { 
		this.appendChild(tooltip); 

	}
	
	if (DHTML_Tooltip.TIMER) 
		clearTimeout(DHTML_Tooltip.TIMER); 

	tooltip.style.left = '0px'; 
	
	DHTML_Tooltip.content.innerHTML = this.$text; 
	tooltip.style.display = 'block';  
	
	
	DHTML_Tooltip.footer.innerHTML = '<div class="jstooltip_baloon_' + this.$baloonDirection + '"  style="margin-left: ' + this.$baloonPosition + 'px;"></div>';

	
	pos = Placement.get_tl_pos(this); 
	
	//	 position 
	if (this.$styles & DHTML_Tooltip.ABSOLUTE) { 
		tooltip.style.top = (pos[1] - tooltip.clientHeight - 10) + 'px';
		tooltip.style.left = pos[0] + 'px';
	} else { 
		
		//tooltip.style.top = '-' + (pos[1] - tooltip.clientHeight - 10) + 'px';
		tooltip.style.top = '-' + (tooltip.clientHeight + 10) + 'px'; 
		tooltip.style.left = '-2px';
	}
	
	DHTML_Tooltip.DELAY.TIMER = setTimeout('DHTML_Tooltip.show()', DHTML_Tooltip.DELAY); 
}

/** 
  * Mouse out event handler. Forces tooltip to fade out
  */
DHTML_Tooltip.mouse_out_element = function() 
{ 
	if (DHTML_Tooltip.TIMER) 
		clearTimeout(DHTML_Tooltip.TIMER); 

	DHTML_Tooltip.TIMER = setTimeout('DHTML_Tooltip.hide()', DHTML_Tooltip.DELAY); 
}




/** 
  * Handles event when user clicks 
  * item which is not absolute
  */
DHTML_Tooltip.mouse_click_element = function() 
{ 
	DHTML_Tooltip.clean (); 
			
	if (this.$styles & DHTML_Tooltip.ABSOLUTE)
		DHTML_Tooltip.hWnd.parentNode.removeChild(DHTML_Tooltip.hWnd); 
}

/** 
  * Forces tooltip to be hidden 
  */
DHTML_Tooltip.force_hide = function() 
{
	DHTML_Tooltip.FORCE_HIDE = true; 
}


/** 
  * Removes opacity 
  */
DHTML_Tooltip.clean = function()
{	
	Effects.set_opacity(DHTML_Tooltip.hWnd,"0.0");		
	DHTML_Tooltip.OPACITY = "0.0"; 
}

/** 
  * Makes tooltip visible to user. 
  * 
  */ 
DHTML_Tooltip.show = function() 
{ 
	var tooltip = DHTML_Tooltip.hWnd; 
	
	if (!tooltip) 
		return; 

	// stop when hiding 
	if (DHTML_Tooltip.OPACITY != "0.0") 
		clearTimeout(DHTML_Tooltip.TIMER); 

	if (DHTML_Tooltip.OPACITY != "1.0") { 
		var tooltip_split = DHTML_Tooltip.OPACITY.split("."); 
		DHTML_Tooltip.OPACITY = ( tooltip_split[1] < 9)  ? "0." + (eval(tooltip_split[1])  + 1) : "1.0"; 
		
		Effects.set_opacity(tooltip, DHTML_Tooltip.OPACITY);
		DHTML_Tooltip.TIMER = setTimeout('DHTML_Tooltip.show()',DHTML_Tooltip.DELAY); 
	} else { 
		DHTML_Tooltip.OPACITY = "1.0"; 
	}
	
	tooltip = null; 
}

/** 
  * Make tooltip invisible
  */
DHTML_Tooltip.hide = function() { 
	var tooltip = DHTML_Tooltip.hWnd; 
		
	if (!tooltip) 
		return; 


	// clear timer if still in middle of showing 
	if (DHTML_Tooltip.OPACITY != "1.0") 
		clearTimeout(DHTML_Tooltip.TIMER); 

	if (DHTML_Tooltip.OPACITY >  "0.0") { 
		
		var tooltip_split = DHTML_Tooltip.OPACITY.split("."); 
		DHTML_Tooltip.OPACITY = ( tooltip_split[0] == "1")  ? "0.9"  : "0." + (eval(tooltip_split[1])  - 1); 
		
		Effects.set_opacity(tooltip, DHTML_Tooltip.OPACITY);		
			
		DHTML_Tooltip.TIMER = setTimeout('DHTML_Tooltip.hide()',DHTML_Tooltip.DELAY); 
		
	} else { 
		DHTML_Tooltip.OPACITY = "0.0"; 
		
		if (tooltip.parentNode) { 
			tooltip.parentNode.removeChild(tooltip); 
		}

		DHTML_Tooltip.FORCE_HIDE = false; 
	} 
}

/** 
  * Removes alt and title tags from the element and its sub elements
  * @argument element in document 
  */
DHTML_Tooltip.remove_alt_tags = function (element) 
{ 
	// get all children 
	var children = element.childNodes; 
	
	for (var i = 0; i < children.length; i++) 
	{
		
		var node = children[i]; 
		
		// remove alt tag 
		if (node.alt) 
			node.alt = ""; 
		
		// remove title tag 
		if (node.title) 
			node.title = ""; 
		
		// check if node has childnodes
		if (node.childNodes.length > 0) 
			DHTML_Tooltip.remove_alt_tags(node); 
	
	}
	
}



// effects 
function Effects()
{
}


/** 
  * Sets opacity for DOM element. 
  * @argument DOM element 
  * @argument opacity as string e.g. "0.6"; 
  */
Effects.set_opacity = function(element, opacity) 
{

	if (!element) 
		return false; 
	
	// W3C
	element.style.opacity = opacity; 
	
	// IE 
	element.style.filter = 'alpha(opacity=' + eval(opacity)	 * 100+ ')';
		
	return true; 
}



// placement 
/** 
  * Placement class consists of functions which help to 
  * locate elments on document 
  */
function Placement() 
{ 
}


/** 
  * Gets top left position of an element 
  * @argument element reference in document 
  * @return array containing x and y
  */
Placement.get_tl_pos = function (element) 
{ 
	// initialise x and y positions 
	var x = 0; 
	var y = 0; 
	
	do { 
		y += element.offsetTop || 0;
		x += element.offsetLeft || 0;
		
		element = element.offsetParent;
	} while (element); 
	
	// returns values 
	return [x,y]; 
}

