//<script>
var arrGlossary = new Array();
//glossary object
function GlossaryObject(arr, div, bQuote)
{
	try{
		this.entryID = 0;
		this.entryCount = 0;
		this.arr = arr;
		this.str = "";
		this.div = div;
		this.quote = bQuote;
		return this;
	}catch(e){getError(e);}
}
//Utilities:
//get event element 
function getEventElement(evt)
{
	try{
		evt = Compat.getEvent(evt);
		var oElement = evt.target;
		return oElement;
	}catch(e){getError(e);}
}
//check if there is empty string
function isEmpty(str)
{
	try{
		if (str.match(/\S/))
			return false;
		return true;	
	}catch(e){getError(e);}
}
//get entry id
function getEntryId(sElementID, iEntryID)
{
	try{
		return ("div" + sElementID + "_e" + iEntryID);
	}catch(e){getError(e);}
}
//get error message
function getError(e)
{
	alert(e.description);
}

//Events :
//onblur event
function onBlurEvent(evt)
{
	try{
		var oElement = getEventElement(evt);
		if(this.id == arrGlossary[oElement.id].div.id)
			oElement.focus();
		else
			hideGlossary(oElement);

	}catch(e){getError(e);}
}
//onpaste event
function onPasteEvent(evt)
{
	try{
		evt = Compat.getEvent(evt);
		var oElement = evt.target;
		oElement.value = window.clipboardData.getData("Text");
		evt.stopPropagation();
		evt.preventDefault();
		onKeyupEvent(evt);
	}catch(e){getError(e);}
}
//onkeyup event
function onKeyupEvent(evt)
{
	try{
		var oElement = getEventElement(evt);
		var keyCode = evt.keyCode;
		arrGlossary[oElement.id].str = oElement.value;
		if (keyCode==32 || keyCode==189 || keyCode==8 || keyCode==16 || keyCode==46 || keyCode==45 || keyCode==188 || (keyCode>=48 && keyCode<=57) || (keyCode>=65 && keyCode<=90))
		{	
			cleanGlossary(oElement); 
			if (isEmpty(arrGlossary[oElement.id].str))
				hideGlossary(oElement);
			else
				fillGlossary(oElement);
		}
		if (keyCode == 38 || keyCode == 40) //up or down key
			arrowKeys(oElement,keyCode);
	}catch(e){getError(e);}
}
//onfocus event --> show the glossary div if there is a value in the input
function onFocusEvent(evt)
{
	try{
		var oElement = getEventElement(evt);
		var oDiv = arrGlossary[oElement.id].div;
		var iEntryCount = arrGlossary[oElement.id].entryCount;
	
		if (!isEmpty(oElement.value) && iEntryCount > 0)
			oDiv.style.display = "inline";
	}catch(e){//getError(e);
	}
}
//onkeydown event --> keyboard handler
function onKeydownEvent(evt)
{
	try{
		evt = Compat.getEvent(evt);
		var oElement = evt.target;
		var oDiv = arrGlossary[oElement.id].div;
		var keyCode = evt.keyCode;
		var iEntryID = arrGlossary[oElement.id].entryID;
		switch(keyCode)
		{
			case 27 ://esc
				hideGlossary(oElement);
				evt.stopPropagation();
				evt.preventDefault();
				return false;
				break;
			case 9: //tab
			case 13 ://enter
				if (oDiv.style.display == "inline")
				{
					if(iEntryID != 0)
						onEntryClick(oElement);
					evt.stopPropagation();
					evt.preventDefault();
					return false;
				}
				break;
		}
	}catch(e){getError(e);}
}
//onMouseDown Event on entry:
function onEntryClick(oElement)
{
	try{
		var sEntryID = getEntryId(oElement.id, arrGlossary[oElement.id].entryID)  
		var oEntry = document.getElementById(sEntryID);

		if (oEntry != null)
		{
			var s = oEntry.innerText;
			s = s.replace(/&nbsp;/g, " ");
			if (arrGlossary[oElement.id].quote)
				s = "[" + s + "]";
			oElement.value = s;
		}
		hideGlossary(oElement);
	}catch(e){getError(e);}
}
// keyboard arrow keys handlers
function arrowKeys(oElement, iKeyCode)
{
	try{
		var oDiv = arrGlossary[oElement.id].div;
		var iEntryCount = arrGlossary[oElement.id].entryCount;

		if (oDiv.style.display == "none" || iEntryCount == 0) 
			return;

		var sID = arrGlossary[oElement.id].entryID; 

		switch(iKeyCode)
		{
			case 38 : //arrow up	
				if (sID - 1 <= 0)
					sID = iEntryCount + 1;
				(--sID);
				break;
			case 40 : //arrow down
				if (sID + 1 > iEntryCount) 
					sID = 0;
				(++sID);
				break;
		}
	
		var sEntryID = getEntryId(oElement.id, sID);
		var oEntry = document.getElementById(sEntryID);
		setHover(true, oEntry);

		scrollIntoViewGlossary(oDiv, oEntry);
	}catch(e){getError(e);}
}

//scrollintoview
function scrollIntoViewGlossary(oDiv, oEntry)
{
	try{
		var iEntryOffsetTop =  oEntry.offsetTop;
		var iEntryOffsetHeight =  oEntry.offsetHeight;
		var iScrollTop = oDiv.scrollTop;
		var iHeight = oDiv.offsetHeight - iEntryOffsetHeight + iScrollTop;	
		if(iEntryOffsetTop < iScrollTop)
			oEntry.scrollIntoView(true);
		else if (iEntryOffsetTop > iHeight)
			oEntry.scrollIntoView(false);
	}catch(e){getError(e);}
}
//onmouseover Event
function setHover(bOn, oElement)
{
	try{
		if (!oElement) return;
		var sID = oElement.id.replace(/^div([^_]+)_e\d+/i,"$1")
		var iEntryID = arrGlossary[sID].entryID;
		if (iEntryID > 0)
		{
			document.getElementById(oElement.id.replace(/_e\d+$/i, "_e" + iEntryID)).className = 'entry';
			arrGlossary[sID].entryID = 0;
		}

		if (bOn)
		{
			if((/_e(\d+)$/i).exec(oElement.id))
				arrGlossary[sID].entryID = Number(RegExp.$1);
			oElement.className = "entryOn";
		}
	}catch(e){getError(e);}
}

//Div glossary function
//hide glossary
function hideGlossary(oElement)
{
	try{
		var oDiv = arrGlossary[oElement.id].div;
		oDiv.style.display = "none";
	}catch(e){getError(e);}
}
//clean glossary
function cleanGlossary(oElement)
{
	try{
		var oDiv = arrGlossary[oElement.id].div;
		oDiv.innerHTML = "";

		arrGlossary[oElement.id].entryCount = 0;
		arrGlossary[oElement.id].entryID = 0;
	}catch(e){getError(e);}
}
//fill glossary
function fillGlossary(oElement) 
{
	try{
		var oDiv = arrGlossary[oElement.id].div;
		var sValue = oElement.value.replace(/^"/,"").replace(/"$/,"");
		if (isEmpty(sValue))
		{
			hideGlossary(oElement);
			cleanGlossary(oElement);
			return;
		}
		var oReg = new RegExp();
		sValue = sValue.replace(/\?|\!|\*|\.|\/|\\|\-|\(|\)|\[|\]/g,"\\$&");
		oReg.compile(sValue, "i");
		var arr = arrGlossary[oElement.id].arr;
		for (var i=0; i<arr.length && arrGlossary[oElement.id].entryCount < 200; i++)
			if (oReg.test(arr[i].toString()))
					addEntry(arr[i],oElement);

		if(arrGlossary[oElement.id].entryCount > 0)
			oDiv.style.display = "inline";
		else
			oDiv.style.display = "none";
	}catch(e){getError(e);}
}
//add entry to the glossary
function addEntry(text, oElement)
{
	try{
		var oEntry = document.createElement("div");
		var oDiv = arrGlossary[oElement.id].div;
		var sValue = oElement.value.replace(/^"/,"").replace(/"$/,"");
		oEntry.id = getEntryId(oElement.id, (++arrGlossary[oElement.id].entryCount));
		oEntry.title = text;
		oEntry.className = "entry";
		var iIndex = text.toLowerCase().indexOf(sValue.toLowerCase());
		var sText = text.slice(0, iIndex)+'<b>'+ sValue + '</b>' + text.slice(iIndex+ sValue.length);
		oEntry.innerHTML = sText;
		if (oEntry.addEventListener)
		{
			oEntry.addEventListener("mouseover",function(){setHover(true,oEntry)}, false);
			oEntry.addEventListener("mouseout",function(){setHover(false,oEntry)}, false);
			oEntry.addEventListener("mousedown",function(){onEntryClick(oElement)}, false);
		}
		else
		{
			oEntry.attachEvent("onmouseover",function(){setHover(true,oEntry)});
			oEntry.attachEvent("onmouseout",function(){setHover(false,oEntry)});
			oEntry.attachEvent("onmousedown",function(){onEntryClick(oElement)});
		}
		oDiv.appendChild(oEntry);
	}catch(e){getError(e);}
}
