if (!Array.prototype.indexOf)
{
/*source: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Array:indexOf*/
  Array.prototype.indexOf = function(elt /*, from*/)
  {
	var len = this.length;

	var from = Number(arguments[1]) || 0;
	from = (from < 0)
		 ? Math.ceil(from)
		 : Math.floor(from);
	if (from < 0)
	  from += len;

	for (; from < len; from++)
	{
	  if (from in this &&
		  this[from] === elt)
		return from;
	}
	return -1;
  };
}

if (!SuggestionObj) {
	var SuggestionObj = new Object();
	Object.extend = function(destination, source) {
		for (var property in source) {
			destination[property] = source[property];
		}
		return destination;
	}
}

SuggestionObj.Methods = {
	input: null,
	inputOldOnclick: null,
	inputOldOnfocus: null,
	inputOldOnblur: null,
	inputFocused: false,
	resultDiv: null,
	previousQuery: "",
	queryMinLength: 3,
	maxDisplayed: 10,
	requestDelay_ms: 333,
	lastRequestId: null,
	resultCounts: new Array(),
	waitingRequests: new Array(),
	lastLap: -1,
	divHidingTimeout: null,
	linkBase: prof_adv.suggest_url,
	cssClassName: "jmSuggestionResults",
	uid: 165,
	cid: 833,
	form: null,
	formQueryPart: null,
	formValue: null,
	openInNewWindow: false,
	newQueryTermArray : new Array(),
	searchWithExternalLink: false,
	
	inputOnfocus: function(e) {
		SuggestionObj.inputFocused=true;
		SuggestionObj.dontHideResults();
		SuggestionObj.showResults();
		if (SuggestionObj.inputOldOnfocus) {
			return SuggestionObj.inputOldOnfocus(e);
		}
	},
	inputOnclick: function(e) {
		SuggestionObj.dontHideResults();
		if (SuggestionObj.inputOldOnclick) {
			return SuggestionObj.inputOldOnclick(e);
		}
	},
	inputOnblur: function(e) {
		SuggestionObj.inputFocused=false;
		SuggestionObj.hideResults();
		if (SuggestionObj.inputOldOnblur) {
			return SuggestionObj.inputOldOnblur(e);
		}
	},

	suggest: function(input) {
		if (this.input == null) {
			this.input = input;
			
			this.inputOldOnfocus = input.onfocus;
			this.inputOldOnclick = input.onclick;
			this.inputOldOnblur = input.onblur;
			input.onfocus = SuggestionObj.inputOnfocus;
			input.onclick = SuggestionObj.inputOnclick;
			input.onblur = SuggestionObj.inputOnblur;
			input.setAttribute("autocomplete", "off");

			this.resultDiv = document.createElement("div");
			this.resultDiv.onmouseover=new Function("SuggestionObj.dontHideResults();");
			this.resultDiv.onmouseout=new Function("SuggestionObj.hideResults();");
			this.resultDiv.onclick=new Function("SuggestionObj.dontHideResults();");
			this.resultDiv.onblur=new Function("SuggestionObj.hideResults();");
			this.resultDiv.onscroll=new Function("SuggestionObj.dontHideResults();");
			this.resultDiv.onfocus=new Function("SuggestionObj.dontHideResults();");
			this.resultDiv.style.display="none";
			this.resultDiv.setAttribute("class", this.cssClassName);
			this.resultDiv.setAttribute("className", this.cssClassName);

			var style = "width";
			var value = input.style[style];
			if(!value)
				if(document.defaultView) value = document.defaultView.getComputedStyle(input, "").getPropertyValue(style);
				else if(input.currentStyle) value = input.currentStyle[style];
			this.resultDiv.style.width = value;

			var p = input.parentNode;
			if(input.lastchild == input){
				p.appendChild(this.resultDiv);
			}else{
				p.insertBefore(this.resultDiv, input.nextSibling);
			}

			this.form = document.createElement("form");
			this.form.setAttribute("action", this.linkBase + "search");
			this.form.setAttribute("method", "POST");
			this.form.setAttribute("id", "suggestionForm");
			if (this.openInNewWindow) {
				this.form.setAttribute("target", "_blank");
			}

			this.formQueryPart = document.createElement("input");
			this.formQueryPart.setAttribute("type", "hidden");
			this.formQueryPart.setAttribute("name", "s");
			this.form.appendChild(this.formQueryPart);

			this.formValue = document.createElement("input");
			this.formValue.setAttribute("type", "hidden");
			this.formValue.setAttribute("name", "v");
			this.form.appendChild(this.formValue);

			if (document.body) {
				document.body.appendChild(this.form);
			} else {
				p.appendChild(this.form);
			}
			
			
		}
		query = input.value;
		if(this.previousQuery!=query && query.length>=this.queryMinLength  ) {
			if (!this.isQueryPointless(query)) {
				var requestSrc = this.linkBase + "search?s=" + encodeURIComponent(query) + "&args=client:profadv,mode:json,callback:SuggestionObj.suggestionCallback";
				var request = new JSONscriptRequest(requestSrc);
				callbackParams=encodeURIComponent("'" + request.scriptId + "'");
				request.fullUrl = request.fullUrl + ",callbackParams:" + callbackParams;
				this.waitingRequests[request.scriptId] = request;
				this.lastRequestId = request.scriptId;
				window.setTimeout("SuggestionObj.sendRequest('" + request.scriptId + "');", this.requestDelay_ms);

			} else {
				this.resultDiv.style.display = "none";
			}
		} else if(this.previousQuery!=query && query.length<this.queryMinLength) {
			this.resultDiv.style.display = "none";
		}
		this.previousQuery = query;
	},

	isQueryPointless: function(query) {
		var sendQuery = true;
		for (i = query.length + 1; i > this.queryMinLength; i--) {
			var frag = query.substring(0,i);
			if (this.resultCounts[frag] != null) {
				sendQuery = this.resultCounts[frag] > 0;
				break;
			}
		}
		return !sendQuery;
	},

	sendRequest: function(requestID) {
		var request = this.waitingRequests[requestID];
		if (request) {
			if (this.lastRequestId == requestID){
				request.buildScriptTag();
				request.addScriptTag();
			} else {
				this.waitingRequests.splice(this.waitingRequests.indexOf(requestID), 1);
			}
		}
	},

	removeRequestElement: function(requestID) {
		request = this.waitingRequests[requestID];
		if (request) {
			request.removeScriptTag();
			this.waitingRequests.splice(this.waitingRequests.indexOf(requestID), 1);
		}
	},
	
	suggestionCallback: function(json_text, rID) {
		if (this.lastRequestId == rID) {
			var result = eval(json_text);
			var suggestions = result && result["sugg"] ? result["sugg"] : new Array();
			if (!this.resultCounts[rID]) {
				this.resultCounts[rID] = suggestions ? suggestions.length : 0;
			}
			if(!suggestions || suggestions.length==0 ) {
				this.resultDiv.style.display = "none";
				this.resultDiv.innerHTML="";
			} else {
				if(SuggestionObj.input) {
					var toInnerHtml = "<ul>";
					suggestions.sort(function(a,b){
						if(a.length - b.length > 0 ) return 1;/*order by length*/
						else if(a.length - b.length < 0) return -1;
						else{/*order by name*/
							if(a.toLowerCase() < b.toLowerCase()) return -1;
							else if(a.toLowerCase() > b.toLowerCase()) return 1;
							else return 0;
						}
					});
					for(i=0;i<suggestions.length;i++) {
						toInnerHtml += "<li>" + this.transformLink(this.highlightQueryInText(SuggestionObj.input.value, "<a href='javascript:void(0)' id='sugg_" + i + "' suggestion='" + suggestions[i].replace(/'/g, "\'") + "'>" + suggestions[i] + "</a>"),suggestions[i],i) + "</li>";
					}
					toInnerHtml += "</ul>";
					this.resultDiv.innerHTML = toInnerHtml;
					var qObjWidth = SuggestionObj.input.clientWidth;
					if (qObjWidth > 0){
						this.resultDiv.style.width = "" + (SuggestionObj.input.clientWidth + 2) + "px";
					}else{
						this.resultDiv.style.width = "350px";
					}
					this.lastLap = -1;
					this.resultDiv.style.visibility = "hidden";
					this.resultDiv.style.display = "";
					if(suggestions.length > this.maxDisplayed){
						var maxHeight = 0;
						for(i = 0;i < this.maxDisplayed; i++){
							maxHeight += this.resultDiv.childNodes[0].childNodes[i].offsetHeight;
						}
						this.resultDiv.childNodes[0].style.height = "" + maxHeight + "px";
					}else{
						this.resultDiv.childNodes[0].style.height = "auto";
					}
					this.resultDiv.style.visibility = "";
				}
			}
		}
		this.removeRequestElement(rID);
	},

	hideResults: function(){
		if (SuggestionObj.resultDiv) {
			this.divHidingTimeout = window.setTimeout("SuggestionObj.hideResultsDo();", 500);
		}
	},

	hideResultsDo: function(){
		if (SuggestionObj.resultDiv.style.display == ""){
			SuggestionObj.resultDiv.style.display = 'none';
			if(document.activeElement.id.indexOf("sugg_") == 0){
				SuggestionObj.focusToInput();
			}
		}
	},
		
	dontHideResults: function(){
		if(SuggestionObj.resultDiv.style.display == ""){/*hided already so do not show again*/
			if (this.divHidingTimeout != null){
				window.clearTimeout(this.divHidingTimeout);
				this.divHidingTimeout = null;
			}
			this.showResults();
		}
	},

	showResults: function(){
		if (SuggestionObj.input && SuggestionObj.input.value.length > 2 && this.resultDiv.innerHTML != ""){
			this.resultDiv.style.display = "";
		}
	},

	keyDown: function(e){
		e = e ? e : event;
		if (e && SuggestionObj.resultDiv){
			if (SuggestionObj.resultDiv.style.display == "" && !SuggestionObj.isInputActive()){
				switch (e.keyCode){
					case 40: /*** down key ***/
						SuggestionObj.move(SuggestionObj.resultDiv.firstChild, true);
						break;
					case 38: /*** up key ***/
						SuggestionObj.move(SuggestionObj.resultDiv.firstChild, false);
						break;
					case 8: /*** backspace ***/
						e.cancelBubble = true;
						e.returnValue = false;
						return false;
						break;
					case 13: /*** enter ***/
						break;
					case 9: /*** tab ***/
						SuggestionObj.tab();
						break;
					default:
						SuggestionObj.focusToInput();
						break;
				}
			} else if (e.keyCode == 9 && SuggestionObj.resultDiv.style.display == "" && SuggestionObj.isInputActive()){
				SuggestionObj.resultDiv.focus();
			}
		}
	},
	c : 0,
	keyUp: function(e){
		e = e ? e : event;
		if (e && SuggestionObj.resultDiv){
			if (e.keyCode == 40){ /*** down key ***/
				if (SuggestionObj.isInputActive()){
					SuggestionObj.showResults();
					if (SuggestionObj.resultDiv.style.display == ""){
						SuggestionObj.move(SuggestionObj.resultDiv.firstChild, true);
					}
				}	
			}else if (e.keyCode == 38) { /*** up key ***/
			}else if (e.keyCode == 9){ /*** tab ***/
			}else if (e.keyCode == 27 && SuggestionObj.resultDiv.style.display == ""){ /*** esc key ***/
				SuggestionObj.focusToInput();
				SuggestionObj.hideResults();
			}else if (SuggestionObj.resultDiv.style.display == "" && !SuggestionObj.isInputActive()){ /*** other key ***/
				SuggestionObj.otherKeyPressed(e.which || e.keyCode);
			}
			if(SuggestionObj.resultDiv.style.display == "" && SuggestionObj.lastLap > 0 && SuggestionObj.lastLap < SuggestionObj.resultDiv.childNodes[0].childNodes.length - 1){
				if (e.keyCode == 40){
					SuggestionObj.move(SuggestionObj.resultDiv.childNodes[0], true);
					SuggestionObj.move(SuggestionObj.resultDiv.childNodes[0], false);
				}else if (e.keyCode == 38){
					SuggestionObj.move(SuggestionObj.resultDiv.childNodes[0], false);
					SuggestionObj.move(SuggestionObj.resultDiv.childNodes[0], true);
				}
			}
		}
	},

	transformLink: function(item, term, index){
		var link = item;
		var search = item.indexOf("href=")<0;
		if(search) {
			this.newQueryTermArray[index] = term;
			link = "<a href=\"javascript: void(0);\" onclick=\"SuggestionObj.suggestionClickedAndSearch(" + index+ ");\" >" + item + "</a>";
		} else {
			if(!this.searchWithExternalLink) {
				link = link.replace(/href=/g, "onclick=\"SuggestionObj.suggestionClicked(this);return false;\" href=");
			} else {
				idx = term.lastIndexOf("<");
				term = term.substring(0,idx);
				idx = term.lastIndexOf(">");
				term = term.substring(idx+1);
				this.newQueryTermArray[index] = term ;
				link = link.replace(/href=/g, "onclick=\"SuggestionObj.suggestionClickedAndSearch(" + index+ ");return false;\" href=");
				link = link.substring(0, link.indexOf("href=")+6) + "javascript: void(0);\"" + link.substring(link.indexOf("\"",link.indexOf("href=")+6)+1);
			}
		}
		link = link.replace("<a ", "<a onfocus='SuggestionObj.dontHideResults();' onblur='SuggestionObj.hideResults();' onmouseover='SuggestionObj.mouseover(this);' ");
		link = link.replace("<A ", "<A onfocus='SuggestionObj.dontHideResults();' onblur='SuggestionObj.hideResults();' onmouseover='SuggestionObj.mouseover(this);' ");
		return link;
	},

	focusToInput: function(){
		if (SuggestionObj.input){
			SuggestionObj.input.focus();
		}
	},

	isInputActive: function(){
		return SuggestionObj.input && document.activeElement.id == SuggestionObj.input.id;
		/*return SuggestionObj.input && SuggestionObj.inputFocused;*/
	},

	move: function(uls, isDown){
		if (uls && uls.hasChildNodes()){
			for (i=0;i < uls.childNodes.length; i++){
			  uls.childNodes[i].className = "";
			}
			if (isDown){ /*** down key ***/
				this.lastLap++;
				if (this.lastLap >= uls.childNodes.length){
					this.lastLap = uls.childNodes.length - 1;
				}
			}else{ /*** up key ***/
				this.lastLap--;
				if (this.lastLap < 0){
					this.lastLap = -1;
				}
			}
			if(this.lastLap > -1){
				uls.childNodes[this.lastLap].childNodes[0].focus();
				uls.childNodes[this.lastLap].className = "focused";
				
			}else{
				this.focusToInput();
			}
			this.dontHideResults();
		}
	},

	otherKeyPressed: function(charcode){
		this.focusToInput();
		if (SuggestionObj.input){
			if (charcode == 8){ /*** backspace ***/
				SuggestionObj.input.value = SuggestionObj.input.value.substring(0, SuggestionObj.input.value.length - 1);
			}else{
				SuggestionObj.focusToInput();
			}
			SuggestionObj.input.onkeyup();
		}
	},

	highlightQueryInText: function(query, text){
		if (text == ""){
			return "";
		}else{
			var counter = 0;
			var newText = "";
			while (counter < text.length){
				var startHtmlTag = text.indexOf("<", counter);
				var endHtmlTag = text.indexOf(">", startHtmlTag);
				if (startHtmlTag > -1 && endHtmlTag > -1){
					if (startHtmlTag > counter){
						var startQuery = text.substring(counter,startHtmlTag).toLowerCase().indexOf(query.toString().toLowerCase());
						if (startQuery > -1){
							/*found query*/
							newText += text.substring(counter, counter + startQuery) + "<strong>" + text.substring(counter + startQuery, counter + startQuery + query.length) + "</strong>" + text.substring(counter + startQuery + query.length);
							return newText;
						}else{
							newText += text.substring(counter, endHtmlTag);
							counter = endHtmlTag;
						}
					}else{
						newText += text.substring(counter, endHtmlTag);
						counter = endHtmlTag;
					}
				}else{
					var startQuery2 = text.substring(counter).toLowerCase().indexOf(query.toString().toLowerCase());
					if (startQuery2 > -1){
						/*found query*/
						newText += text.substring(counter, counter + startQuery2) + "<strong>" + text.substring(counter + startQuery2, counter + startQuery2 + query.length) + "</strong>" + text.substring(counter + startQuery2 + query.length);
						return newText;
					}else{
						newText += text.substring(counter);
						return newText;
					}
				}
			}
			return newText;
		}
	},

	suggestionClicked: function(suggLink) {
		/*this.formQueryPart.value = this.input.value;*/
		this.input.value = suggLink.getAttribute("suggestion");
		SuggestionObj.hideResultsDo();
		/*this.form.submit();*/
		return false;
	},

	suggestionClickedAndSearch: function(index) {
		this.input.parentNode.removeChild(this.resultDiv);
		changeQ(this.newQueryTermArray[index]);
		return true;
	},

	tab: function(){
		this.lastLap++;
		if(this.lastLap >= SuggestionObj.resultDiv.firstChild.childNodes.length){
		  SuggestionObj.focusToInput();
		  SuggestionObj.resultDiv.style.display = "none";
		  this.lastLap = -1;
		}
	},
	
	mouseover: function(link){
		SuggestionObj.dontHideResults();
		var tags = SuggestionObj.resultDiv.getElementsByTagName("*");
		var classNameRegexp = new RegExp('\\bfocused\\b');
		for (i = 0; i < tags.length; i++){
		  var className = tags[i].className;
		  tags[i].className = className.replace(classNameRegexp, "");
		}
		link.className = "focused";
	}
}

Object.extend(SuggestionObj, SuggestionObj.Methods);
document.onkeyup = SuggestionObj.keyUp;
document.onkeydown = SuggestionObj.keyDown;

/* jsr_class.js

 JSONscriptRequest -- a simple class for making HTTP requests
 using dynamically generated script tags and JSON

 Author: Jason Levitt
 Date: December 7th, 2005
 Constructor -- pass a REST request URL to the constructor
*/
function JSONscriptRequest(fullUrl) {
    /* REST request path*/
    this.fullUrl = fullUrl; 
    /* Keep IE from caching requests*/
    this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
    /* Get the DOM location to put the script tag*/
    this.headLoc = document.getElementsByTagName("body").item(0);
    /* Generate a unique script tag id*/
    this.scriptId = 'JscriptId' + JSONscriptRequest.scriptCounter++;
}

/* Static script ID counter*/
JSONscriptRequest.scriptCounter = 1;

/* buildScriptTag method*/
JSONscriptRequest.prototype.buildScriptTag = function () {

    /* Create the script tag*/
    this.scriptObj = document.createElement("script");
    
    /* Add script object attributes*/
    this.scriptObj.setAttribute("type", "text/javascript");
    this.scriptObj.setAttribute("charset", "utf-8");
    this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
    this.scriptObj.setAttribute("id", this.scriptId);
}
 
/* removeScriptTag method*/
JSONscriptRequest.prototype.removeScriptTag = function () {
    /* Destroy the script tag*/
    this.headLoc.removeChild(this.scriptObj);  
}

/* addScriptTag method*/
JSONscriptRequest.prototype.addScriptTag = function () {
    /* Create the script tag*/
    this.headLoc.appendChild(this.scriptObj);
}

