﻿/*****************************************************
 *	Begin Tooltip functions							 *
 *  Some of the functionality here should probably	 *
 *  to the server side at some point				 *
 ****************************************************/
 
 //TODO:  Make this a little better
window.onload = PrepareTooltips;
 
//Variable:		MIN_TOOLTIP_WIDTH
//Description:	Minimum width to enforce for tool tips that appear 
//				close to the right edge of the screen
var MIN_TOOLTIP_WIDTH = 100;

//Variable:		ELEMENT_TAGNAME
//Description:	Name of the tag containing defined words and their
//				definitions.
var ELEMENT_TAGNAME = 'define';

//Variable:		ELEMENT_NAMESPACE
//Description:	Namespace of defined element tags.  Leave blank if not
//				using a tag in a custom namespace.
var ELEMENT_NAMESPACE = 'prezza';

//Variable:		WORD_ATTRIBUTE_NAME
//Description:	Name of attributes containing defined words
var WORD_ATTRIBUTE_NAME = 'word';

//Variable:     IMG_ATTRIBUTE_NAME
//Description:  Name of attribute containing image url
var IMG_ATTRIBUTE_NAME = 'image';

//Variable:		TOOLTIP_DIV_ID
//Description:	ID of the div to contain the tooltip text
var TOOLTIP_DIV_ID = 'tooltip_div';

//Variable:		DEFINED_WORD_CSS_NAME
//Description:	CSS class to use for defined words
var DEFINED_WORD_CSS_NAME = 'DefinedWord';

//Variable:		Texts
//Description:	Stores the tool tip texts.  The related words are the 
//				indexes to the array
var Texts = new Array();

//////////////////////////////////////////////////////////////////////
//	Function	:	PrepareTooltips()								//
//	Description	:	Load and store definitions, add visual cues for	//
//				:	defined words, and add event handlers to cause	//
//				:	tooltips to be displayed.						//
//////////////////////////////////////////////////////////////////////
function PrepareTooltips()
{
	var tipText;
	var img;
	var definedWord;
	//Step 1:  Find all of the tags
	//Internet Explorer does not treat custom tags like regular tags 
	//	unless they are part of a defined namespace.  For a tag such 
	//	as <prezza:define />, IE considers the tag name to be 'define'
	//  when using getElementsByTagName whereas Mozilla expects 
	//	prezza:define.
	var definitionElements = document.getElementsByTagName(ELEMENT_TAGNAME);
	
	if(definitionElements.length == 0 && ELEMENT_NAMESPACE.length > 0)
	{
		definitionElements = document.getElementsByTagName(ELEMENT_NAMESPACE + ':' + ELEMENT_TAGNAME);
	}
	
	//Step 2:  Store all of the display texts in an array indexed by
	//		   the defined words.
	for(i = 0; i < definitionElements.length; i++)
	{
		tipText = '';
		definedWord = '';
		
		//Get the definition text.  IE uses the non-compliant 
		//	innerText property and Mozilla uses DOM level 3 
		//	property textContent
		tipText = definitionElements[i].innerHTML;
		/*if(definitionElements[i].innerText)
			tipText = definitionElements[i].innerHTML;
		else if(definitionElements[i].textContent)
			tipText = definitionElements[i].textContent;*/
			
		//Get the word, which is stored as the 'word' attribute on the
		//	define node
		definedWord = definitionElements[i].getAttributeNode(WORD_ATTRIBUTE_NAME).value;
		
		if(definitionElements[i].getAttributeNode(IMG_ATTRIBUTE_NAME))
		{
		    img = definitionElements[i].getAttributeNode(IMG_ATTRIBUTE_NAME).value;
        }
        else
        {
            img = '';
        }
        
		//Store word and definition
		if(definedWord.length > 0)
		{
			Texts[definedWord] = tipText;
			
			//In the define tag, replace the text, which is currently
			// the definition of the word, with the word itself.
			if(img.length > 0)
			{
			    definitionElements[i].innerHTML = '<img ' + WORD_ATTRIBUTE_NAME + '= "' + definedWord + '" src="' + img + '" />';
			}
			else
			{
                //Set the display style so there is a visual indicator of an available tooltip
			    definitionElements[i].className = DEFINED_WORD_CSS_NAME;
			    
			    definitionElements[i].innerHTML = definedWord;

			    /*if(definitionElements[i].innerText)
			    {
				    definitionElements[i].innerText = definedWord;
                }
			    else if(definitionElements[i].textContent)
			    {
				    definitionElements[i].textContent = definedWord;
                }*/
			}
			
			//Set events hook to show and hide the tooltip on mouse
			// over and mouse out.
			definitionElements[i].onmouseover = ShowToolTip;
			definitionElements[i].onmouseout = HideToolTip;
			
		}
	}
}
//////////////////////////////////////////////////////////////////////
//	Function	:	ShowTooltip(e)									//
//	Description	:	Show the tooltip associated with the element	//
//				:	firing the onmouseover event.					//
//	Inputs		:	e -- Event args (Mozilla only)					//
//////////////////////////////////////////////////////////////////////		
function ShowToolTip(e)
{
	var toolTipDiv;			//Div to put tooltip text into
	var targetElement;		//Event target, should be an element with
							// tag = ELEMENT_TAGNAME
	var definedWord;		//Word to display defnition of
	
	var windowWidth;		//Width of the client browser window
	var windowHeight;		//Height of the client browser window
	
	var divWidth;			//Width of tooltip div
	var divHeight;			//Height of tooltip div
	
	var	posX;				//'Left' position of the tooltip div
	var posY;				//'Top' position of the tooltip div
	
	var diffX;				//Used when calculating how close the
							//tooltip is to the right browser edge
	var diffY;				//Used when calculating how close the
							//tooltip is to the bottom browser edge
	
	//Get the tooltip div
	toolTipDiv = document.getElementById(TOOLTIP_DIV_ID);
	
	//Get the word (custom element is the event target) to display the
	//definition for.
	
	//Use the event object to get the mouse coordinates and event target
	//Some browsers (IE?) don't pass the object as an argument so it may
	//have to be retrieved.
	if(!e)
		e = window.event;
	if(e.srcElement)
		targetElement = e.srcElement;
	else if(e.target)
		targetElement = e.target;

	definedWord = targetElement.getAttributeNode(WORD_ATTRIBUTE_NAME).nodeValue;

	//Set the text of the div.  The text is set here because the size
	//of the div can be determined once it is populated with text
	if(toolTipDiv.textContent)
	{
    	toolTipDiv.textContent = Texts[definedWord];
    }
	else
	{
	    toolTipDiv.innerText = Texts[definedWord];
    }
		
	//Position the tooltip
	// 1. Get the current position of the mouse to use as
	//	  the guideline for positioning the text
	if (e.pageX || e.pageY)
	{
		posX = e.pageX;
		posY = e.pageY;
	}
	else if (e.clientX || e.clientY)
	{
		posX = e.clientX + document.body.scrollLeft;
		posY = e.clientY + document.body.scrollTop;
	}
	
	//If we're so close to the edge of the screen (bottom or right 
	//side) that the tooltip would cause scrolling or be squished,
	//adjust the position.
	
	// Use the greater of the scroll width/height or the client width/
	// height.  This ensures the right height/width is used to
	// determine if tooltip text wouldn't fit on page.
	if(document.body.scrollWidth > document.body.clientWidth)
		windowWidth = document.body.scrollWidth;
	else
		windowWidth = document.body.clientWidth;
		
	if(document.body.scrollHeight > document.body.clientHeight)
		windowHeight = document.body.scrollHeight;
	else
		windowHeight = document.body.clientHeight;
	
	//Make div visible, do it now because it won't have a scrollWidth 
	//or scrollHeight until display style is block or inline.  Since 
	//this will be absolute-positioned, we'll use block display
	toolTipDiv.style.display = 'block';

	//Move the div to the intermediate location.  Now the browser will
	//render the div and if it's close to a screen edge, may compress
	//it, making the text difficult to read.
	toolTipDiv.style.top = posY;
	toolTipDiv.style.left = posX;

	//Enforce a minimum width for pleasant display.
	divWidth = toolTipDiv.scrollWidth;
	
	if(divWidth < MIN_TOOLTIP_WIDTH)
		divWidth = MIN_TOOLTIP_WIDTH;

	//Figure out how close the right edge of the div is to the right
	//edge of the browser window.					
	diffX = windowWidth - (posX + divWidth);

	//If we're really close, that probably means that we're not
	//the minimum size, so set the width			
	if(diffX < 20)
	{
		toolTipDiv.style.width = divWidth;

		//Instead of using the mouse position as the left edge, use
		//it as the right edge (i.e. show the tip to the left of the
		//mouse position rather than the right)
		posX = posX - divWidth;
	}

	divHeight = toolTipDiv.scrollHeight;
	diffY = windowHeight - (posY + divHeight);

	//If we're too close to the bottom, use the mouse position as the
	//bottom of the tooltip div instead of the top.		
	if(diffY < 20)
	{
		//Set the bottom edge to be the mouse location
		posY = posY - divHeight;
	}

	//Move the tooltip div to it's final location			
	toolTipDiv.style.top = posY;
	toolTipDiv.style.left = posX;
	
}

//////////////////////////////////////////////////////////////////////
//	Function	:	HideToolTip(e)									//
//	Description	:	When the mouse exits the region defined by the	//
//				:	defined word element, this function is called	//
//				:	to hide the tooltip.							//
//////////////////////////////////////////////////////////////////////
function HideToolTip(e)
{
	//Get the tooltip div
	var	toolTipDiv = document.getElementById(TOOLTIP_DIV_ID);
	
	//Hide the div
	toolTipDiv.style.display = 'none';
	
	//Reset the width so that it will be recalculated when the div is
	//populated with text.  Failing to do this causes the div to
	//always have the same width (because we set it in ShowToolTip)
	//as the first displayed tooltip.
	toolTipDiv.style.width = '';
}
