var glossary = {};
// Allows not parsing the glossary unnecessarily, when AJAX is involved.
var glossaryWordList = "";
// Used to perform consecutive replacements, when needed.
var glossarizationCount = 0;
// These are used in return value, as well as comparisons, to avoid duplication:
var replacedSentinelBefore = "onmouseout=\"hideTerm(this,event)\">";
var replacedSentinelAfter = "</span>";
var msie = navigator.appVersion.indexOf("MSIE") != -1 && !window.opera;

/**
 * Replaces glossarizable term with its glossarized equivalent. Detects previously glossarized occurences, 
 * or places where glossarization is inapplicable and returns them as is.
 */
function replacer(match,$1,$2,$3,pos) {
  	if (
  				($1 == (!msie ? replacedSentinelBefore : replacedSentinelBefore.replace(/"/g, "")) 
  					&& $3.toLowerCase().indexOf(replacedSentinelAfter) == 0
  				)  
  					|| $3.toLowerCase().indexOf("</option>") > -1
  					|| $3.toLowerCase().indexOf("</textarea>") > -1
			)
  		return match;
  	else
  		glossarizationCount++;
  	
	return $1+ "<span id=\"" 
  			+glossary[$2.toLowerCase()]+ "_" 
  			+pos+ 
  			"\" class=\"term\" onmouseover=\"showTerm(this,event)\" " +replacedSentinelBefore
  			+$2+ replacedSentinelAfter +$3;
}

/**
 * Glossarizes certain pre-defined terms.
 *
 * @param element	element to glossarize under (optional). If not passed in, default elements will be used.
 */
function glossaryize(element) {
    glossaryDivs = document.getElementById("glossary");
    if(glossaryDivs) {
   		if (element == undefined) { 
	        // If on Future Vehicles pages, can only update a portion; otherwise, the flash gets broken.
	        element = document.getElementById("fv_left");
	        if (element == null) {
	            element = document.getElementById("maincontent");
	        }
        }
    	if (glossaryWordList.length < 1) {// build word list only once
	        for(var i=0; i<glossaryDivs.childNodes.length; i++) {
	            if(glossaryDivs.childNodes[i].tagName == "DIV") {
	                var div = glossaryDivs.childNodes[i];
	                var keys = div.title.split(",");
	                for(var j=0; j<keys.length; j++) {
	                    var key = trim(keys[j]).toLowerCase();
	                    glossary[key] = div.id; 
	                    glossaryWordList += "|" +key;
	                }
	            }
	        }
        }
        var regex = new RegExp("([\\S]+\>[^\<]*)\\b(" +glossaryWordList.substring(1)+ ")\\b([^\>]*\<[\\S]+)", "gi");
        element.innerHTML = element.innerHTML.replace(regex, replacer);
        // When 2 glossary words are side by side, only one is replaced, unless we invoke replace again, 
        // so to ensure nothing is missed, invoke w/ the assumption that each replacement could have missed 
        // a replaceable nearby:
        for (var i = 0; i < glossarizationCount; i++)
        	element.innerHTML = element.innerHTML.replace(regex, replacer);
       	glossarizationCount = 0; // reset back
    }
}

function showTerm(ref, e) {
    var term;
    if(typeof ref == "string") term = ref;
    else term = ref.innerHTML;
    
	var elem = getTerm(ref);
	var def = elem.innerHTML;
	//def = def.replace(/<\/?p>/g, "");
	//alert(def);
    showGlossaryWindow(term, def, e);
}
function hideTerm(ref, e) {
	//if(typeof ref == "string") return;
    hideGlossaryWindow(e);
}
function getTerm(ref) {
    var id;
    if(typeof ref == "string") {
        id = glossary[trim(ref).toLowerCase()];
    } else {
        var index = ref.id.lastIndexOf("_");
        id = ref.id.substring(0, index);
    }
    return document.getElementById(id);
}
function trim(text) {
    if (text) return text.replace(/(^\s*|\s*$)/g,"");
    else return text;
}
glossaryize();
