//Stops the enter key from submitting the form
function noEnter(evt) {
	//Multibrowser compatibility
	var evt  = (evt) ? evt : ((event) ? event : null);
	var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
	//If keypressed was enter:
	if ((evt.keyCode == 13) && (node.type=="text")) { 	
	return false; } else {
	return true;
	}
}

document.onkeypress = noEnter;





//Global Variables
	var resultDelim = "^"
	var fieldDelim = "|"
	var isIE=false;
	
	
//End Globals

////////////////////
/* Cache
*/
///////////////////
function SuggestCache() {
	var cacheItems = new Array();
	var length = 0;
	
	this.AddItem = AddItem;
	this.RemoveItem = RemoveItem;
	this.GetItem = GetItem;
	this.ExistsItem = ExistsItem;
	this.GetLength = GetLength;
	
	function AddItem(key,val) {
		if(typeof(cacheItems[key]) == 'undefined') {
			//Item is new
			length++;
		}
		cacheItems[key] = val;
	}
	function RemoveItem(key) {
		if(typeof(cacheItems[key]) != 'undefined') {
			length--;
			delete cacheItems[key];
			return true;
		} else {
			return false;
		}
	}
	function ExistsItem(key) {
		if(typeof(cacheItems[key]) == 'undefined') {
			return false;
		}
		else {
			return true;
		}
	}
	function GetItem(key) {
		return cacheItems[key];
	}
	function GetLength() {
		return length;
	}
}
//End Cache//
////////////////////
/*Input Object
*/
////////////////////
function SuggestInputObject(inputElementID) {
	var inputElement = document.getElementById(inputElementID);
	this.SetInputValue = SetInputValue;
	this.GetInputValue = GetInputValue;
	this.GetInputElement = GetInputElement;
	this.AddEventListener = AddEventListener;
	this.AttachEvent = AttachEvent;
	this.SetAttribute = SetAttribute;
	this.Focus = Focus;
	
	function SetInputValue(theValue) {
		if(inputElement) {
			inputElement.value = theValue;
		}
	}
	function GetInputValue() {
		if(inputElement) {
			return inputElement.value;		
		}
	}
	function GetInputElement() {
		return inputElement;
	}
	function AddEventListener(eventName,functionName,flag) {
		if(inputElement) {
			inputElement.addEventListener(eventName,functionName,flag);
		}
	}
	function AttachEvent(eventName,functionName) {
		if(inputElement) {
			inputElement.attachEvent(eventName,functionName);
		}
	}
	function SetAttribute(attribName,attribValue) {
		if(inputElement) {
			inputElement.setAttribute(attribName,attribValue);
		}
	}
	function Focus() {
		if(inputElement) {
			inputElement.focus();
		}
	}
}
//End Input Object//




////////////////////
/*Output Object - modeled as an input whose value
  will be set upon selection from the autosuggest
  	Objects creation is keyed on the one input parameter, outputElementID.
*/
////////////////////
function SuggestOutputObject(outputElementID) {
	var suggestOutput	= document.getElementById(outputElementID);
	
	this.SetOutputValue = SetOutputValue;
	this.ResetOutputValue = ResetOutputValue;
	
	function SetOutputValue(theValue) {
		
		if(theValue == '')
			return;
		
		if (suggestOutput) {
			suggestOutput.value		= theValue;
			suggestOutput.disabled	= true;
		}
	}
	
	function ResetOutputValue() {
		if (suggestOutput) {
			suggestOutput.value		= "";
			suggestOutput.disabled	= false;
		}
	}
}
//End Output Object//




////////////////////
/* Menu Handler
*/
///////////////////
function SuggestMenuHandlerObject(pullDownElementID, hmcIE, hmoIE) {
	var pullDownMenuElement = document.getElementById(pullDownElementID);
	var highlightedElement = null;
	var HandleMouseClickIE = hmcIE;
	var HandleMouseOverIE = hmoIE;
	
	
	this.HideMenu = HideMenu;
	this.ShowMenu = ShowMenu;
	this.UpArrow = UpArrow;
	this.DownArrow = DownArrow;
	this.GetHighlightedElement = GetHighlightedElement;
	this.GetHighlightedValue = GetHighlightedValue;
	this.GetHighlightedLabel = GetHighlightedLabel;
	this.SetHighlightedElement = SetHighlightedElement;
	this.RemoveHighlightedElement = RemoveHighlightedElement;

	this.AddHighlightedStyle = AddHighlightedStyle;
	this.RemoveHighlightedStyle = RemoveHighlightedStyle;
	
	this.UpdateMenuContent = UpdateMenuContent;
	
	function HideMenu() {
		pullDownMenuElement.style.display = "none";
	}
	function ShowMenu() {
		pullDownMenuElement.style.display = "block";
	}

	function UpdateMenuContent(dataFeedText, myName) {
		
		if(pullDownMenuElement.firstChild) {
			pullDownMenuElement.removeChild(pullDownMenuElement.firstChild);
		}
		
		if(dataFeedText.length == 0)  // no suggestions!
			return;
		
		var dataFeedItemSet = dataFeedText.split(resultDelim);
		
		var borderElement = document.createElement("DIV");
		borderElement.className = "menuBorder";
		pullDownMenuElement.appendChild(borderElement);
		
		for(var i=0; i < dataFeedItemSet.length; i++) {
			
			var dataItem = dataFeedItemSet[i].split(fieldDelim);
			
			var theLabel = dataItem[1];
			var theValue = dataFeedItemSet[i];
			
			var myNewElement = document.createElement("DIV");
			//myNewElement.setAttribute("class", "menuRowClass");
			myNewElement.className = "menuRowClass";
			if(isIE) {
				myNewElement.onclick = HandleMouseClickIE;
				myNewElement.onmouseover = HandleMouseOverIE;
			} else {
				myNewElement.setAttribute("onclick", myName + ".HandleMouseClick(this);");
				myNewElement.setAttribute("onmouseover", myName + ".HandleMouseOver(this);");
			}
			myNewElement.setAttribute("value", theValue);
			myNewElement.innerHTML = theLabel;
			borderElement.appendChild(myNewElement);
		}
	}
	
	function GetHighlightedElement() {
		return highlightedElement;
	}
	function GetHighlightedValue() {
		if(highlightedElement)
			return highlightedElement.getAttribute("value");
		else
			return '';
	}
	
	function GetHighlightedLabel() {
		if(highlightedElement)
			return highlightedElement.innerHTML;
		else
			return '';
	}
	
	function SetHighlightedElement(el) {
		highlightedElement = el;
	}
	function RemoveHighlightedElement() {
		highlightedElement = null;
	}
	
	function UpArrow() {
		if (!highlightedElement) {
			if(pullDownMenuElement.firstChild) {
				highlightedElement = pullDownMenuElement.firstChild.lastchild;
			}
		} else {
			highlightedElement = highlightedElement.previousSibling;
		} 
	}
	
	function DownArrow() {
		if (!highlightedElement) { //There is no highlighted element, make it the first one
			if(pullDownMenuElement.firstChild) { //If the search menu is open
				highlightedElement = pullDownMenuElement.firstChild.firstChild;	
			}
		} else { //There is a highlighted element, so make it the next one
			highlightedElement = highlightedElement.nextSibling;
		}		
	}
	
	function AddHighlightedStyle() {
		if(highlightedElement) {
			highlightedElement.setAttribute("id","highlightID");
		}
	}
	function RemoveHighlightedStyle() {
		if(highlightedElement) {
			highlightedElement.removeAttribute("id");
		}
	}
}
//End Menu Handler


////////////////////
/* Main Auto Completer Object
*/
///////////////////
function SuggestPullDownMenuObject(theSuggestID, theJSObjectName, suggestURL) {
	var SuggestID = theSuggestID
	var menuHandlerObj = null;
	var outputObj = null;
	var inputObj = null;
	var myCache = null;
	var searchURL = suggestURL
	var debugOutput = null;
	var debugMode = false;
	var t = null;
	var h = null;
	var searchReq = false;
	var searchLast = "";
	var searchRoot = "";
	var myName = theJSObjectName;
	var searchType=0;

	var hideDelay = 4000;
	var outputType = "single";

	if (window.XMLHttpRequest) {
		searchReq = new XMLHttpRequest();
	}

	this.Init = Init;
	this.SetOutputObject = SetOutputObject;
	this.InitAttatchEvents = InitAttatchEvents;
    this.HideDelayed = HideDelayed;
	this.DisplayDebug = DisplayDebug;
	this.DebugOn = DebugOn;
	this.DebugOff = DebugOff;
	this.KeyPress = KeyPress;
	this.SearchStart = SearchStart;
	this.DoSearch = DoSearch;
	this.HandleMouseOver = HandleMouseOver;
	this.HandleMouseClick = HandleMouseClick;
	this.HandleMouseOverIE = HandleMouseOverIE;
	this.HandleMouseClickIE = HandleMouseClickIE;
	this.UpdateInputBox = UpdateInputBox;
	this.ResetInputBox = ResetInputBox;
	this.ResetInputBox = ResetInputBox;
	this.EnterHandler = EnterHandler;
	this.HideShortDelay = HideShortDelay;
	this.SetOutputType = SetOutputType;
	this.SetSearchURL = SetSearchURL;

    function DebugOn(){
		debugMode = true;
	}
	
	function DebugOff() {
		debugMode = false;
	}

	function DisplayDebug(debugText) {
		if(debugMode){
			if(debugOutput) {
				debugOutput.innerHTML = debugText;
			} else {
				document.write(debugText);
			}
		}
	}
			
	
	function Init() {
		inputObj = new SuggestInputObject('suggestInput_' + SuggestID);
		outputObj = new SuggestOutputObject('suggestOutput_' + SuggestID);
		menuHandlerObj = new SuggestMenuHandlerObject('suggestMenu_' + SuggestID, HandleMouseClickIE, HandleMouseOverIE);
		myCache = new SuggestCache();
		InitAttatchEvents();
	}
	
	// In case a custom output object is called for:
	function SetOutputObject(theOutputObject) {
		outputObj = theOutputObject;
	}
	
	// In case the search URL needs to be updated on the fly:
	function SetSearchURL(newSearchURL) {
		searchURL = newSearchURL;
	}
	
	function InitAttatchEvents() {
		if (navigator.userAgent.indexOf("Safari") > 0) {
			inputObj.AddEventListener("keydown",KeyPress,false);
		} else if (navigator.product == "Gecko") {
			inputObj.AddEventListener("keypress",KeyPress,false);
			inputObj.AddEventListener("blur",HideShortDelay,false);
		} else {
			inputObj.AttachEvent('onkeydown',KeyPress);
			isIE = true;
		}
		
		inputObj.SetAttribute("autocomplete","off");
		
	}

	function HideShortDelay() {
		window.setTimeout(menuHandlerObj.HideMenu, 800);
	}
	
	function HideDelayed() {
		if (h) {
			window.clearTimeout(h);
		}
		h = window.setTimeout(menuHandlerObj.HideMenu,hideDelay);
	}

	
	function SearchHide() {
		pullDownMenuElement.style.display = 'none';
	}
	
	function EnterHandler(event, el) {
		if(event.keyCode == 13) { // enter, the user has made a choice...
			searchLast = inputObj.GetInputValue();
			menuHandlerObj.HideMenu();
			
			// ... so acknowledge it and move them to the next input in the form!
			f = el.form;
			for(i = 0; i < f.elements.length; i++) {
				if(f.elements[i] == el) {
					for(j = i+1; j < f.elements.length; j++) {
						if(f.elements[j].type != 'hidden'  &&  !f.elements[j].disabled) {
							f.elements[j].focus();
							j=f.elements.length;
						}
					}
				}
			}
			
			return false;
		} else {
			return true;
		}
	}
	function KeyPress(event) {
		
		if(event.keyCode != 13) {
			HideDelayed();
		}
		//ENTER
		if (event.keyCode == 13)
		{
			searchLast = inputObj.GetInputValue();
			outputObj.SetOutputValue(menuHandlerObj.GetHighlightedValue());
			menuHandlerObj.HideMenu();
			menuHandlerObj.RemoveHighlightedStyle();

		} 
		else if (event.keyCode == 40)
		//KEY DOWN
		{
			outputObj.ResetOutputValue();
			menuHandlerObj.ShowMenu();
			menuHandlerObj.RemoveHighlightedStyle();
			menuHandlerObj.DownArrow();
			menuHandlerObj.AddHighlightedStyle();
			inputObj.SetInputValue(menuHandlerObj.GetHighlightedLabel());
			HideDelayed();

			if (!isIE) { event.preventDefault(); }	
				
			if(menuHandlerObj.GetHighlightedElement) {
				searchLast = inputObj.GetInputValue();
				outputObj.SetOutputValue(menuHandlerObj.GetHighlightedValue());
			}
		} 
		//KEY UP
		else if (event.keyCode == 38 ) {
			outputObj.ResetOutputValue();
			menuHandlerObj.ShowMenu();
			menuHandlerObj.RemoveHighlightedStyle();
			menuHandlerObj.UpArrow();
			menuHandlerObj.AddHighlightedStyle();
			inputObj.SetInputValue(menuHandlerObj.GetHighlightedLabel());
			
			HideDelayed();

			if (!isIE) { event.preventDefault(); }		
			if(menuHandlerObj.GetHighlightedElement) {
				searchLast = inputObj.GetInputValue();
				outputObj.SetOutputValue(menuHandlerObj.GetHighlightedValue());
			}
		} 
		//ESC
		else if (event.keyCode == 27) {
			menuHandlerObj.RemoveHighlightedStyle();
			menuHandlerObj.RemoveHighlightedElement();
			menuHandlerObj.HideMenu();
			outputObj.ResetOutputValue();
			inputObj.SetInputValue("");

		}  
		//TAB
		else if (event.keyCode == 9) {
			//TAB should not reset the search
		} 
		//LEFT/RIGHT
		else if (event.keyCode == 37 || event.keyCode == 39) {
			//Left/right arrows should not reset the search
		}
		//HOME/END/PAGEUP/PAGEDOWN
		else if (event.keyCode <= 36 && event.keyCode >= 33) {
			//Do Nothing
		} 
		else if (event.keyCode == 16) {
			// Shift doesn't do anything
		}
		else {
			//A letter or number has been pressed, so reset the search
			outputObj.ResetOutputValue();
			SearchStart();
		}
	}
	
	function SearchStart() {
		if (t) {
			window.clearTimeout(t);
		}
		t = window.setTimeout(DoSearch,50);
	}
	
	function DoSearch() {
		
		var currentInputText = inputObj.GetInputValue();
		
		if (searchLast != currentInputText) {
			menuHandlerObj.RemoveHighlightedStyle();
			menuHandlerObj.RemoveHighlightedElement();
			if(myCache.ExistsItem(currentInputText)) {
				//Cache Hit HOORAY
				UpdatePullDown(myCache.GetItem(currentInputText));
				searchLast = currentInputText;
			}
			else {
			//Cache Miss : Do Search
				if (searchReq && searchReq.readyState < 4) {
					searchReq.abort();
				}
				if ( inputObj.GetInputValue() == "") {
					menuHandlerObj.HideMenu();
					return false;
				}
				if (window.XMLHttpRequest) {
					// branch for IE/Windows ActiveX version
					searchReq = new XMLHttpRequest();
				} else if (window.ActiveXObject) {
					searchReq = new ActiveXObject("Microsoft.XMLHTTP");
				}
				
				searchReq.onreadystatechange = ProcessReqChange;
				URLString = searchURL.replace('[inputText]', currentInputText)
			//	URLString = searchURL + "?namePrefix=" + currentInputText;
				searchReq.open("GET", URLString);
				searchLast = inputObj.GetInputValue();
				searchReq.send(null);

			}
		}
	}

	function ProcessReqChange() {
		if (searchReq.readyState == 4) {
			UpdatePullDown(searchReq.responseText);
			myCache.AddItem(inputObj.GetInputValue(), searchReq.responseText);
		}
	}
	function UpdatePullDown(txt) {
		
		menuHandlerObj.UpdateMenuContent(txt, myName);
		menuHandlerObj.ShowMenu();
		HideDelayed(); //make it disappear afer a few seconds
	}
	function HandleMouseOverIE() {
		HandleMouseOver(window.event.srcElement);
	}
	function HandleMouseClickIE() {
		HandleMouseClick(window.event.srcElement);
	}
	function HandleMouseOver(el) {
		menuHandlerObj.RemoveHighlightedStyle();
		menuHandlerObj.SetHighlightedElement(el);
		menuHandlerObj.AddHighlightedStyle();
		HideDelayed();
	}

	function HandleMouseClick(el) {
		menuHandlerObj.RemoveHighlightedStyle();
		menuHandlerObj.SetHighlightedElement(el);
		inputObj.SetInputValue(menuHandlerObj.GetHighlightedLabel());
		outputObj.SetOutputValue(menuHandlerObj.GetHighlightedValue());
		menuHandlerObj.HideMenu();
		inputObj.Focus();
	}
	function UpdateInputBox() {
		hl = menuHandlerObj.GetHighlightedElement();
		if(hl) {
			newVal = menuHandlerObj.GetHighlightedValue(0);
			newVal = newVal.replace("&amp;","&")
			newVal = newVal.replace(/^\s+/g, '').replace(/\s+$/g, '');	
		} else {
			newVal = "0";
		}
		inputObj.SetInputValue(newVal);
	}

	function ResetInputBox() {
		inputObj.SetInputValue("");
	}

	function SetOutputType(typeStr) {
		outputType = typeStr;
	}
//End Class	
}



