 /* client-side hash that contains previously retrieved suggestions
 for any previous queries */
var cache = new Array();
var xmlhttp = false;
var curr_query = "";
var last_query = "";
var curr_target = "";
var page = "";

//var debug = "";

/* add event to home page search box */
function initSH() {
	// exclude safari 412.2 (buggy) and sun hardware (crashes mozilla)
	if(!(navigator.userAgent.indexOf("Safari") >= 0 && navigator.userAgent.indexOf("412.2") >= 0)) {
		if(navigator.userAgent.indexOf("SunOS sun4u") == -1){
			// only add event handling if modern browser
			if (window.addEventListener || window.attachEvent) {
				page = "home";
				addEvent(document.searchForm.q, "keyup", suggestKeyUpHandler, false);
				addEvent(document.searchForm.q, "blur", clearSuggHandler, false);
				if (getCookie("beSuggest")) {
					hideSuggestions();
				}
				xmlhttp = getXmlHttp();
				requestLoop();
			}
		}
	}
	//debug = document.getElementById("debug");
}


// gets top search box
function getTsb() {
	if (page == 'research') {
		return document.getElementById("rtsb");
	} else {
		return document.getElementById("stsb");
	}
	return;
}



function getId(id) {
	if (id.length == 4) {
		return id.substring(1);
	}
	return id;
}

/* handle key up event for alphanumeric chars, back space and space */
function suggestKeyUpHandler(event) {
	var key = getEventKeyCode(event);
	var target = getEventTarget(event);
	
	if ((key >= 49 && key <= 221) || key == 8 || key == 32) { /* alphanumeric,back space, space bar */
		setRequestData(target.value, getId(target.getAttribute("id")));
		return; 
	}
}

// stores the current query and target search box
function setRequestData(query, target) {
	curr_query = query;
	curr_target = target;
}

// every 10 miliseconds checks to see if current query has changed
// if it has, it sends a request
function requestLoop() {
	if (curr_query != "") {
		if (curr_query != last_query) {
			getSuggestions(curr_query, curr_target);
			last_query = curr_query;
		}
	}
	setTimeout("requestLoop()", 10);
}

/* get suggestions for new query from cache or server */
function getSuggestions(query, id) {
	var q = cleanSuggQuery(query);
	// if exact query is in cache, read from cache
	if (typeof cache[q] != 'undefined') {  
		suggest(q, id, cache[q]);
	} else {
		// if a substring for this query has zero results, then return from cache
		var subStr = substrSuggCache(q);
		if (subStr != "") {   /* read from cache */
			suggest(q, id, cache[subStr]);
		// otherwise send a request to the server
		} else {
			var src;
			if (page == "shop") { src = "s"; } else { src = "r"; } 
			
			var fHref = "/SmartSearch/q.asp?q=" + escape(q);
			if (xmlhttp) {
				xmlLoadData(query, id, fHref);
			} else {
				window.hframe.location.replace(fHref);
			}
		}
	}
}






/* lowercase and remove leading punctuation and spaces */
function cleanSuggQuery(query) {
	var q = query.toLowerCase();
	var index = 0;
	var alphaNum = new RegExp("[a-z0-9]");
	for (var i=0; i<q.length; i++) {
		if (alphaNum.exec(q.charAt(i))) {
			index = i;
			break;
		}
	}
	q = q.substring(i);
	return q;
}

/* look for a substring of q that has zero suggestions
   if exists, return substring, otherwise return "" */
function substrSuggCache(q) {
	for (var i=q.length - 1; i>0; i--) {
		if (cache[q.substring(0, i)] == null) {
			/*return q.substring(0, i);*/
		}
	}
	return "";
}

function suggest(query, id, suggestions) {
	cache[query] = suggestions;
	if (suggestions == null) {
		zeroSuggs(id);
		return;
	}
	
	if (id == "tsb") {
		// make overlay visible
		var dscontainer = document.getElementById("sSmart_Box");
		dscontainer.style.visibility = "visible";
	}
	
	if (id == "tsb" && !(document.getElementById("sSmart_" + id))) { 
		/* populate overlay with new row */
	 	var table = createSuggestTable(id, suggestions);
	 	dscontainer.appendChild(table);
	}
	
	/* HWL 8/22/2006 added for new home page */
	if (id =="hsb"){
		var dscontainer = document.getElementById("sSmart_Box");
		dscontainer.style.visibility = "visible";
	}
	if (id == "hsb" && !(document.getElementById("sSmart_" + id))) {
		var table = createSuggestTable(id, suggestions);
		dscontainer.appendChild(table);
	}
	
	/*update table rows*/
	var dsrow = createSuggestHtml(id, suggestions);
	var dstb = document.getElementById("SmartTitleTB_" + id);
	var old_dsrow = document.getElementById("dsrow_" + id);
	dstb.replaceChild(dsrow, old_dsrow);
	
	/* make sure everything is visible */
	var dstable = document.getElementById("sSmart_" + id);
	dstable.style.visibility = "visible";
	var dstitle = document.getElementById("sSmartTitle_" + id);
	dstitle.style.visibility = "visible";
}


function createSuggestHtml(id, suggestions) {
	var cols = getNumSuggCols(id, suggestions);
	var dsrow = document.createElement("tr");
	dsrow.setAttribute("id", "dsrow_" + id);
	dsrow.className = "sSmartRow";
	for (var i=1; i<=cols; i++) {
		var start = (suggestions.length > (i-1)*4) ? (i-1)*4 : 0;
		var end = (suggestions.length > (i-1)*4) ? (suggestions.length >= ((i-1)*4)+4)? ((i-1)*4)+4 : suggestions.length : 0;
		var td = createSuggCol(suggestions, start, end, id, i);
		dsrow.appendChild(td);
	}
	dsrow.style.visibility = "visible";
	return dsrow;
}

/* returns the number of columsn to dispay based on the following factors: 
   id (different display for diff. search boxes, average length of suggestions, 
   length of any one suggestion */
function getNumSuggCols(id, suggestions) {
	var numLong = 0;
	var sum = 0;
	var LONG_LEN = 18;
	var SUM_LEN = 12;
	var numCols;
	
	for (var i=0; i<suggestions.length; i++) {
		if(suggestions[i]){
			if (suggestions[i].length > LONG_LEN) {
				numLong++;
			}
			sum += suggestions[i].length;
		}
	}
	numCols = (numLong >= 3) ? 2 : (numLong > 0) ? 3 : 4;  
	numCols = (sum/suggestions.length > SUM_LEN) ? 2 : numCols; 
	return numCols;
}

/* returns a table cell that contains a list of suggestions from index
   start up to but not including index end */
function createSuggCol(suggestions, start, end, id, col) {
	var td = document.createElement("td");
	td.className = "dscol";
	var ul = document.createElement("ul");
	for (var i=start; i<end; i++) {
		var li = document.createElement("li");
		var a = document.createElement("a");
		var t = getTValue(id);
		var service;
		if (page == "research") { service = "research"; } else { service = "shop";}
		var url = "/QueryProcessor.asp?p=1&action=R&q=" + escape(suggestions[i]);
		a.className = "dslink";
		a.setAttribute("href", url);
		a.setAttribute("id", id + i);
		addEvent(a, "mousedown", urlHandler, false);
		var text = document.createTextNode(suggestions[i]);
		a.appendChild(text);
		li.appendChild(a);
		ul.appendChild(li);
	}
	td.appendChild(ul);
	return td;
}

function getTValue(id) {
	if (id == "hsb") {
		return "hs";
	}
	if (id == "tsb") {
		return "ts";
	}
	if (id == "bsb") {
		return "bs";
	}
	return;
}

function urlHandler(e) {
	var t = getEventTarget(e);
	while(t.nodeName != "A") {
		t = t.parentNode;
	}
	var id = t.getAttribute("id").substring(0,3);
	var loc; 
	if (id == "bsb") { loc = "footer"; } else { loc = "header"; }
	
	//remove blur event so link sticks around 
	var tsb = getTsb();
	if (tsb) {
		removeEvent(tsb, "blur", clearSuggHandler, false);
	} 
	
	
	
	var url = t.getAttribute("href");
	location.href = url;
	return false;
}


/* remove all suggestions */
function zeroSuggs(id) {
	var dsuggs = document.getElementById("sSmart_" + id);
	if (dsuggs) {
		dsuggs.style.visibility = "hidden";
	}
	var dstitle = document.getElementById("sSmartTitle_" + id);
	if (dstitle) {
		dstitle.style.visibility = "hidden";
	}
	var dsrow = document.getElementById("dsrow_" + id);
	if (dsrow) {
		dsrow.style.visibility = "hidden";
	}
	var sSmart_Box = document.getElementById("sSmart_Box");
	if (sSmart_Box) {
		sSmart_Box.style.visibility = "hidden";
	}
	return true;
}

function clearSuggHandler(event) {
	var target = getEventTarget(event);
	zeroSuggs(getId(target.getAttribute("id")));
}

function showSuggestions(e) {
	var ids = new Array('hsb', 'rbsb', 'sbsb', 'rtsb', 'stsb');
	
	for (var n=0; n<ids.length; n++) {
		var sbox = document.getElementById(ids[n]);
		if (sbox) {
		
			/* show dsrow with updated suggestions */
			var dsrow = document.createElement("tr");
			dsrow.setAttribute("id", "dsrow_" + getId(ids[n]));
			dsrow.className = "sSmartRow";
			var dstb = document.getElementById("SmartTitleTB_" + getId(ids[n]));
			if (dstb) {
				dstb.appendChild(dsrow);
				var query = sbox.value;
				if(query != curr_query){
					setRequestData(query, getId(ids[n]));
				}else{
					getSuggestions(query, getId(ids[n]));
				}
			}
			
			/* add events */
			addEvent(sbox, "keyup", suggestKeyUpHandler, false);
			if (getId(ids[n]) == 'tsb') {
				addEvent(sbox, "blur", clearSuggHandler, false);
			}
			
			/* flip links */			
			if (getId(ids[n]) != 'tsb' && ids[n] != 'hsb') {
				var parent = document.getElementById("sSmartHL_" + getId(ids[n]));
				var link = document.getElementById("dsshowsl_" + getId(ids[n]));
				var nLink = document.createElement("a");
				nLink.setAttribute("href", "/");
				nLink.setAttribute("id", "dshidesl_" + getId(ids[n]));
				nLink.onclick = hideSuggestions; 
				var linkText = document.createTextNode("Hide Smart Search");
				nLink.appendChild(linkText);
				parent.replaceChild(nLink, link);
			}
		}
	}
	
	setCookie("beSuggest", "0", -1);
	return false;
}

function showHomeSuggestions(){
	var sbox = document.getElementById('hsb');
	
	/* show dsrow with updated suggestions */
	var dsrow = document.createElement("tr");
	dsrow.setAttribute("id", "dsrow_hsb");
	dsrow.className = "sSmartRow";
	var dstb = document.getElementById("SmartTitleTB_hsb");
	if (dstb) {
		dstb.appendChild(dsrow);
	}
	
	/* add events */
	document.getElementById("dssh_hsb").innerHTML = '';
	document.getElementById("dssh_hsb").className = 'sSmart_SSB_hide';
	setCookie("beSuggest", "0", -1);
	showHomeSuggestionDelay(sbox.value);
	document.searchForm.q.focus();
	return false;
}

function showHomeSuggestionDelay(query){
	if(xmlhttp.readyState == 4 || xmlhttp.readyState == 0){
		if(query != curr_query){
			setRequestData(query, 'hsb');
		}else{
			getSuggestions(query, 'hsb');
		}
		var sbox = document.getElementById('hsb');
		addEvent(sbox, "keyup", suggestKeyUpHandler, false);
		addEvent(sbox, "blur", clearSuggHandler, false);
	}else{
		xmlhttp.abort();
		setTimeout("showHomeSuggestionDelay('" + query + "')", 500);
	}
}

// returns the event target
function getEventTarget(e) {
	if (window.event) {
		return window.event.srcElement;
	} else {
		return e.target;
	}
	return;
}

// returns the related target
// the element you came from in the case of a mouseover event
// the element you moved to in the case of a mouseout event
function getEventRelatedTarget(e) {
	if (window.event) {
		if (window.event.type == 'mouseover') {
			return window.event.fromElement;
		}
		if (window.event.type == 'mouseout') {
			return window.event.toElement;
		}
		return;
	} else {
		return e.relatedTarget;
	}
	return;
}

// returns the keycode of the key pressed to trigger a key event
function getEventKeyCode(e) {
	var key;
	if (window.event) {
		key = window.event.keyCode;
	} else {
		key = e.keyCode;
	}
	return key;
}

// adds an event listener to an object
function addEvent(obj, eType, func, capt) {
	/*W3 DOM */
	if (obj.addEventListener) {
		obj.addEventListener(eType, func, capt);
	} else if (obj.attachEvent) { /*Win IE*/
		obj.attachEvent("on" + eType, func);
	} else { /* Mac IE and older browsers */
		//eval("obj.on" + eType + "=func;");
		// remooved for now because mac IE has too many problems
	}
}

// removes an event listener from an object
function removeEvent(obj, eType, func, capt) {
	/*W3 DOM*/
	if (obj.removeEventListener) {
		obj.removeEventListener(eType, func, capt);
	} else {  /* MS IE */
		obj.detachEvent("on" + eType, func);
	}
}

// checks to see if parent is child's parent
function isChild(parent, child) {
	var node = child; 
	if (node) {
		while (node != parent) {
			if (node.nodeName == 'BODY' || node.nodeName == 'HTML') {
				return false;
			}
			node = node.parentNode; 
		}
		return true;
	} 
	return false;
}

// initializes a new xmlHttpRequest object if the browser supports it
// if not browser support, then returns false
function getXmlHttp() {
	var xmlhttp = false;
 	try {
  		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 	} catch (e) {
  		try {
   			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  		} catch (E) {
   			xmlhttp = false;
  		}
	}
	if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  		xmlhttp = new XMLHttpRequest();
	}
	return xmlhttp;
}

// tracking
function becomeTracking(page) {
	if(document.getElementById("urchin")) {
		urchinTracker(page);
	}
	return true;
}


// object that supports getting request arguments
function QueryString(){var querystring=location.search.substring(1,location.search.length);var args=querystring.split('&');for(var i=0;i<args.length;i++){var pair=args[i].split('=');temp=unescape(pair[0]).split('+');name=temp.join(' ');temp=unescape(pair[1]).split('+');value=temp.join(' ');this[name]=value;}this.get=QueryString_get;}
function QueryString_get(strKey,strDefault){var value=this[strKey];if(value==null){value=strDefault;}return value;}

// cookie helper functions
function getCookie(name){var dc=document.cookie;var prefix=name+"=";var begin=dc.indexOf("; "+prefix);if(begin==-1){begin=dc.indexOf(prefix);if(begin!=0){return null;}}else{begin+=2;}var end=document.cookie.indexOf(";", begin);if(end==-1){end=dc.length;}return unescape(dc.substring(begin+prefix.length,end));}
function setCookie(name,value,duration){cookiestring=name+"="+escape(value)+";EXPIRES="+getExpiryDate(duration);document.cookie=cookiestring;if(!getCookie(name)){return false;}}
function getExpiryDate(nodays){var UTCstring;Today=new Date();nomilli=Date.parse(Today);Today.setTime(nomilli+nodays*24*60*60*1000);UTCstring=Today.toUTCString();return UTCstring;}

// string functions
String.prototype.trim = function(){return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,"");}