/*** global variables ***/
var lastSearchUpdate = 0;
var suggestString = '';
var fRow = -1;
var searchKey = false;

function createEventHandlers() {
	var sWord = document.getElementById('searchWord');
	var body = document.getElementsByTagName('body')[0];
	var hTable = document.getElementById('hintsTable');
    var keyword = $('keyword');
	var company = $('companySearch');

	
	addEvent(sWord, 'keyup', searchWordKeyPressed, true);
	addEvent(document, 'click', hideDropDownList, false);
	addEvent(body, 'keyup', hintTableKeyPressed, false);
    addEvent(keyword, 'keyup', searchWordKeyPressed, true);
//	addEvent(company, 'keyup', searchWordKeyPressed, true);
	addEvent(document, 'mousemove', onMouseMove, true);
}

function addEvent(obj, type, fn, useCapture) {
	if (obj.addEventListener) {
		obj.addEventListener(type, fn, useCapture);
		return true;
	} else if (obj.attachEvent) {
		var r = obj.attachEvent("on" + type, fn);				
		return r;
	} else {
		alert('Handler could not be attached');
	}
}

function onMouseMove(e) {
/*  We want to detect when the mouse is moved outside the hints drop-down so we can
*   unhighlight any selected items and reset the fRow variable.
*/

	var cursor = getCursorPosition(e);
    var hints = $('hintsTable');
    var inHints = "";
    
    hintsPos = calcElementPosition(hints);
    var hintsX = hintsPos[0];
    var hintsY = hintsPos[1];
    var hintsW = hints.getDimensions().width;
    var hintsH = hints.getDimensions().height;
     
    var inHints = 
    	(cursor.x > hintsX && cursor.x < (hintsX + hintsW)) && 
    	(cursor.y > hintsY && cursor.y < (hintsY + hintsH)) ? true : false;
    
    if (!inHints) {
    	if (fRow > -1) {
 			setRowColor(fRow, getNormalRowColor());
    		fRow = -1;
    	}
    }
}

function getCursorPosition(e) {
	e = e || window.event;
    var cursor = {x:0, y:0};

    if (e.pageX || e.pageY) {
        cursor.x = e.pageX;
        cursor.y = e.pageY;
    } 
    else {
        var de = document.documentElement;
        var b = document.body;
        cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
        cursor.y = e.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
    }
  
    return cursor;
}

function calcElementPosition(obj) {
	var curleft = curtop = 0;
	
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
		
	return [curleft, curtop];
}		

 function searchWordKeyPressed(event) {
 
	/** cross-browser event check **/
  	if (!event) var event = window.event;
   	/** test for up/downarrow or enter key (will be handled by a different event) **/ 
	if (event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13) return;
	/** move focus out of autosuggest table **/
	fRow = -1;
	
	/*** cross-browser check to get element under the cursor ***/
	if (event.target) target = event.target;
	else if (event.srcElement) target = event.srcElement;
	
	/** set the text the user typed as a global var **/
 	suggestString = target.value;

 	/** make the AJAX call **/
 	if (suggestString != '') {
		var req = newXMLHttpRequest();
 	
		req.onreadystatechange = getReadyStateHandler(req, updateSuggestions);
	 
		req.open("POST", "LookupServlet", true);
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		req.send("hint=" + encodeURIComponent(suggestString) + "&target=" + target.id);
	} else {
		document.getElementById('hints').style.display = 'none';
	}
 }
 
 function hintTableKeyPressed(event) {
/*  
 *  This method handles key events within the drop-down list:
 *  down arrow (keycode=40), up arrow (38) & enter (13).
 *  For the enter key we only handle events that occur while focus
 *  is in the list. Other enter key events will be handled by the 
 *  default submit action of the form.
 *  The variable 'fRow' refers to the row currently in focus. 
 */   
	/** cross-browser event check **/
  	if (!event) var event = window.event;
	var hTable = document.getElementById('hintsTable');
		
	/*** down arrow ***/
  	if (event.keyCode == 40) {
 		if (fRow == hTable.rows.length - 1)return;
 		if (fRow >= 0) setRowColor(fRow, getNormalRowColor());
		
 		fRow++;	
   		setRowColor(fRow, getSelectedRowColor());
		return;
	}
	
	/*** up arrow ***/
	if (event.keyCode == 38) {
		if (fRow == 0) return;
		
		setRowColor(fRow, getNormalRowColor());
		fRow--;	
		setRowColor(fRow, getSelectedRowColor());
		return;
	}
 
 	/*** enter key ***/
 	if (event.keyCode == 13 && fRow > -1) {
		target = $('tr' + fRow).className.split(' ')[1];
		target == 'searchWord' ? doSearch() : fillAdvancedSearchField();
		return;
	}
 }
	
 function updateSuggestions(lookupXML) {
/*  
 *  Gets the XML from the AJAX call and dynamically creates the
 *  the drop-down list. <span> tags are added to the description around the 
 *  characters that match the search string so they can be displayed bold.
 */
 	 var i, a, pre, post, bold, len, span, trElem, tdElem, hTable, div
 	 var categories, items, category, name, lookup, generated, desc
 	 
  	 lookup = lookupXML.getElementsByTagName("search")[0];
	 generated = lookup.getAttribute("generated");
	 
	 if (generated > lastSearchUpdate)  {
		lastSearchUpdate = generated;
	 	div = document.getElementById('hints');
   		hTable = document.getElementById("hintsTable");
		target = lookup.getElementsByTagName("target")[0].getAttribute('name');
		
 	 	if (target == 'searchWord' || target == 'keyword' ) {
			updateSearchWordList(lookup, div, hTable);
		} else {
			updateAdvancedSearchList(lookup, div, hTable);
		}
  	}
 }
 
 function updateSearchWordList(lookup, div, hTable) {
  	var i, a, pre, post, bold, len, span, trElem, tdElem
 	var categories, items, category, name, generated, desc, r
	
	r = -1;
	categories = lookup.getElementsByTagName("category");
	className = 'hintsRow';
	fn = doSearch;
	
	while (hTable.childNodes.length > 0) {
		hTable.removeChild(hTable.firstChild);
	}		
 	
	for (var I = 0 ; I < categories.length ; I++) {
		category = categories[I];
  		name = category.getAttribute('name');	
  		items = category.getElementsByTagName('item');
  		if (name == 'company'){
  			name = 'publisher';
  		}else if (name == 'industry'){
  			name = 'topic';
  		}   		
  		for (var x = 0; x < items.length; x++) {
			desc = items[x].firstChild.nodeValue;
			r++;			
			populateTable(desc, r, className, fn, name);
 		} 
 	}
	setHintTablePosition('searchWord');
}
 
 function updateAdvancedSearchList(lookup, div, hTable) {
 	var target, items, desc, r, tname, className, fn
	
	r = -1;
	target = lookup.getElementsByTagName("target")[0]; 
	tname = target.getAttribute('name');
	className = "hintRow " + tname;
	fn = fillAdvancedSearchField;
	categoryName = '';
	
	while (hTable.childNodes.length > 0) {
		hTable.removeChild(hTable.firstChild);
	}
	
	items = target.getElementsByTagName('item');		
 	
	for (var x = 0; x < items.length; x++) {
		desc = items[x].firstChild.nodeValue;
		r++;
		
		populateTable(desc, r, className, fn, categoryName);
 	}	
	setHintTablePosition(tname);
 }
 
 function populateTable(desc, r, className, fn, categoryName) {

	var len, i, pre, bold, post, span
	
	len = suggestString.length;
	i = desc.toLowerCase().indexOf(suggestString.toLowerCase());

	/******  make the hint string bold  ******/
	pre = desc.substring(0, i);
	bold = desc.substring(i, i+len);
	post = desc.substring(i+len, desc.length);

	span = document.createElement('span');
	span.className = 'searchString';
	span.appendChild(document.createTextNode(bold));
 	
	/******  populate the table  ******/
	hTable = $('hintsTable');
	trElem = hTable.insertRow(hTable.rows.length);
	trElem.id = "tr" + r;
	trElem.className = className;

	/******* item cell *******/
	tdElem = trElem.insertCell(trElem.cells.length);
	tdElem.className = 'item';
	a = document.createElement('a');
	addEvent(tdElem, 'mouseover', handleMouseover, true);
	addEvent(tdElem, 'click', fn, true);
	a.appendChild(document.createTextNode(pre));
	a.appendChild(span);
	a.appendChild(document.createTextNode(post));
	tdElem.appendChild(a);	
	
	/******* category cell *******/
	if (categoryName != '') { 			
		tdElem = trElem.insertCell(trElem.cells.length);
		tdElem.className = "category";
		tdElem.innerHTML = categoryName;
	}
}
 
 function fillSearchWord() {
/*  
 *  Gets the category and description from the current row and concatenates them in the
 *  correct format for the search field. Note that the description contains <span> tags
 *  which 'bold' the characters matching the search string. These tags have to be removed.
 */
	var searchWord, firstIndex, secondIndex, lastIndex, str, category
	var firstWord, secondWord
	
//	if ($('hints').visible() == false) fRow = -1; 
	if (fRow < 0) return;
	
	category = document.getElementById('tr'+ fRow).childNodes[1].innerHTML;
	str = document.getElementById('tr'+ fRow).childNodes[0].childNodes[0].innerHTML;

	firstIndex = str.indexOf('<');
	secondIndex = str.indexOf('>');
	thirdIndex = str.lastIndexOf('<');
	lastIndex = str.lastIndexOf('>');

	firstWord = category + ':';
	secondWord = str.substring(secondIndex+1, thirdIndex) + str.substring(lastIndex+1, str.length);	
    searchWord = category != '' ? firstWord + '"' + secondWord + '"': '"' + secondWord + '"';
	document.getElementById('searchWord').value = removeSpecial(searchWord);
 }
 
 function fillAdvancedSearchField() {
/*  Populate the appropriate search field in the advanced search panel
 *  with the selected value.
 */ 

 	var searchWord, firstIndex, secondIndex, lastIndex, str, row, target

	if (fRow < 0) return;
	row = $('tr' + fRow);
	str = row.childNodes[0].childNodes[0].innerHTML;
	target = row.className.split(' ')[1];

	firstIndex = str.indexOf('<');
	secondIndex = str.indexOf('>');
	thirdIndex = str.lastIndexOf('<');
	lastIndex = str.lastIndexOf('>');

	searchWord = str.substring(secondIndex+1, thirdIndex) + str.substring(lastIndex+1, str.length);
			
	$(target).value = removeSpecial(searchWord);
	$(target).focus();
	fRow = -1;
 }
 
 function handleMouseover(event) {
 	var cell, anchor, span, hTable, target
	hTable = document.getElementById('hintsTable');

	/*** cross-browser check to get element under the cursor ***/
	if (event.target) target = event.target;
	else if (event.srcElement) target = event.srcElement;
	
	/*** highlight the row if the cursor is anywhere in the cell ***/
	for (i = 0; i < hTable.rows.length; i++) {	
		hTable.rows[i].style.backgroundColor = getNormalRowColor();
		cell = hTable.rows[i].firstChild; 
		anchor = hTable.rows[i].firstChild.firstChild;  
		span = hTable.rows[i].firstChild.firstChild.childNodes[1];

		if (target == cell || target == anchor || target == span) {
			hTable.rows[i].style.backgroundColor = getSelectedRowColor();
			fRow = i;
		}
	}
 }
 
 function getNormalRowColor() {
// 	return '#c8e2f7';
	 return '#ffffff';
 }
 
 function getSelectedRowColor() {
  	return '#97c8f9';
 }
 
 function setRowColor(row, color) {
 	document.getElementById('tr' + row).style.backgroundColor = color;
 }
 
 function hideDropDownList() {
   	document.getElementById('hints').style.display = 'none';
//	document.getElementById('searchWord').focus();
//	fRow = -1;
 }
 
 function removeSpecial(str) {
/*  
 *  Removes the special characters that had to be inserted for the XML.
 *  Also checks for spaces in the search word portion of the string
 *  and, if any, quotes the search word.
 */
 	var newStr = str;
  	var s = newStr.search(/\s/);
//alert('string='+newStr);
 	while (newStr.indexOf(';') >= 0) { 
 		var i = newStr.indexOf('&');				
  		var x = newStr.indexOf(';');
 		if (x > i) {
 			var replaceStr = newStr.substring(i, x+1);
 			if (replaceStr == '&amp;') 
 				newStr = newStr.replace(replaceStr, '&');
  			else if (replaceStr == '&lt;')
 				newStr = newStr.replace(replaceStr, '<');
 			else if (replaceStr == '&gt;')
 				newStr = newStr.replace(replaceStr, '>');
 			else if (replaceStr == '&quot;')
 				newStr = newStr.replace(replaceStr, '"');
 		}
 	}
 
 	/** quote the word if spaces exist **/
// 	if (s != -1) {
// 		var c = newStr.indexOf(':');
// 		var category = newStr.substring(0, c+1);
// 		var word = '"'+ newStr.substring(c+1, newStr.length) + '"';
// 		newStr = category + word;
// 	}
 	return newStr;
 }
 			
 function doSearch() {
    fillSearchWord();
	document.forms['searchForm'].submit();
  	fRow = -1;
 }
 
 function submitSearchIfValid() {

    /** captures enter key events when focus is on the search field **/
    fillSearchWord();

    var searchText = document.getElementById('searchWord').value;       

    // prevent empty submits
    if (isEmptyOrWhitespace(searchText)) return; 
    
    document.forms['searchForm'].submit();
 }
  
 function resetSearch() {
 
   fillSearchWord();
   document.forms['searchForm'].submit();
 }

 function submitAdvancedSearch() {
	if (fRow < 0) {
		new Effect.BlindUp('advancedSearchForm');
		return true;
	} else {
		fillAdvancedSearchField();
		return false;
	}
 }
 
 /* 
  * Answers the question: Is any search item in the drop-down list highlighted? 
  */
 function isAnySearchItemHighlighted() {
    
    return fRow != -1;
 } 

 function updateSearchButtons() {

    var searchText = document.getElementById('searchWord').value;   
    var disabled = isEmptyOrWhitespace(searchText) ? 'disabled' : null;   
         
    document.getElementById('doSearch').disabled = disabled;
 }
 
 function isEmptyOrWhitespace(string) {
    return searchText.match(/^\s*$/)
 }