/* smart select object
L&S, DC 10/2006
*/

function SmartSelect(_container,_dataurl,_itemfield,_displayfield,_valuefield) {
	/******************************
	PRIVATE	Class Attributes
	******************************/
	var container = _container;
		if(typeof(container) == "string") {container = document.getElementById(container);}
	var dataurl = _dataurl;
	var itemfield = _itemfield.toLowerCase();
	var displayfield = _displayfield.toLowerCase();
	var valuefield = _valuefield.toLowerCase();
	
	var trigger = document.createElement("img");
	var kwdform = document.createElement("form");
	var kwdinput = document.createElement("input");
	var options = document.createElement("ul");
	
	var ajaxobj = new AjaxObject("get",dataurl,"","");
	
	var urlpattern = "";
	var defaulttext = "Select an Option";
	var emptymessage = "No options matched your search";
	var triggernum = 100;
	var triggeralways = 3;
	var triggerincrement = 2;
	
	var focusoption = null;
	var focusbyarrow = false;
	var focusurl = "";
	
	var reserveheight = true;
	
	/******************************
	PRIVATE	Class Methods
	******************************/
	var displayOptions = function(data) {
		var results = data.responseXML.getElementsByTagName(itemfield);
		//alert(results.length);
		clearData(options);
		toggleDisplay(options,true);
		var listitem;
		var itemlink;
		if (results.length > 0) {
			for(var i=0; i<results.length; i++) {
				listitem = document.createElement("li");
				itemlink = document.createElement("a");
				//create href
					itemlink.setAttribute("href",getDataURL(results[i].getElementsByTagName(valuefield)[0].firstChild.nodeValue));
				//create name
					var this_name = results[i].getElementsByTagName(displayfield)[0].firstChild.nodeValue;
					//itemlink.appendChild(document.createTextNode(this_name));
					formatOptionName(itemlink,this_name);
				//create DOM structure and events
					listitem.appendChild(itemlink);
					listitem.onmouseover = function() {
							//updateClassName(this,"on","");
							setFocusOption(this);
						};
					listitem.onmouseout = function() {
							updateClassName(this,"","on");
						};
					options.appendChild(listitem);
			}
			setFocusOption(options.childNodes[0]);
		} else {
			listitem = document.createElement("li");
			listitem.appendChild(document.createTextNode(emptymessage));
			options.appendChild(listitem);
		}
	};
	var formatOptionName = function(link_obj,link_text) {
		var highlighted = document.createElement("span");
		var search_text = (kwdinput.value);
		var pos_begin = link_text.toLowerCase().indexOf(search_text.toLowerCase());
		//alert(pos_begin);
		if ((pos_begin < 0) || (search_text.length === 0)) {
			link_obj.appendChild(document.createTextNode(link_text));
		} else if (pos_begin === 0) {
			highlighted.appendChild(document.createTextNode(link_text.substr(0,search_text.length)));
			link_obj.appendChild(highlighted);
			link_obj.appendChild(document.createTextNode(link_text.substr(search_text.length,(link_text.length-search_text.length))));
			//link_obj.appendChild(document.createTextNode("pending begin placement"));
		} else {
			link_obj.appendChild(document.createTextNode(link_text.substr(0,pos_begin)));
			highlighted.appendChild(document.createTextNode(link_text.substr(pos_begin,search_text.length)));
			link_obj.appendChild(highlighted);
			link_obj.appendChild(document.createTextNode(link_text.substr((pos_begin+search_text.length),(link_text.length-search_text.length))));
			//link_obj.appendChild(document.createTextNode("pending middle placement"));
		}
	};
	
	var getDataURL = function(urldata) {
		if(urlpattern.length) {
			return urlpattern.replace("#",urldata);
		} else {
			return urldata;
		}
	};
	
	var getOptions = function() {
		/*if (kwdinput.value == defaulttext) {
			kwdinput.value = "";
		}*/
		ajaxobj.setQueryString(getQueryString());
		ajaxobj.setHandler(displayOptions);
		ajaxobj.execute();
	};
	
	var getOptions_triggered = function(e) {
		//alert(e.keyCode);
		if(e.keyCode == 37 || e.keyCode == 38) {
			setFocusOption_prev();
		} else if(e.keyCode == 39 || e.keyCode == 40) {
			//alert("move down");
			setFocusOption_next();
		} else {
			if ((kwdinput.value.length < triggernum) ||
				(kwdinput.value.length <= triggeralways)) {
				triggernum = kwdinput.value.length;
				getOptions();
			} else if ((kwdinput.value.length - triggernum) >= triggerincrement) {
				triggernum = kwdinput.value.length;
				getOptions();
			}
		}
	};
	
	var getQueryString = function() { // builds querystring from form fields
		var qs = "?";
		if(kwdinput.value != defaulttext) {
			qs += "kwd=" + escape(kwdinput.value);
		}
		//alert(qs);
		return qs;
	};
	
	var setFocusOption = function(option) {
		if(focusoption !== null) {
			updateClassName(focusoption,"","on");
		}
		focusoption = option;
		focusurl = option.getElementsByTagName("a")[0].getAttribute("href");
		focusbyarrow = false;
		updateClassName(focusoption,"on","");
	};
	
	var setFocusOption_next = function() {
		//alert(focusoption.nextSibling);
		setFocusOption(focusoption.nextSibling);
		focusbyarrow = true;
	};
	
	var setFocusOption_prev = function() {
		//alert(focusoption.nextSibling);
		setFocusOption(focusoption.previousSibling);
		focusbyarrow = true;
	};
	
	/******************************
	PUBLIC	Class Methods
	******************************/
	this.activateInitialClick = function() {
		var this2 = this;
		this.setTextValue("");
		kwdinput.onclick = function() {
				this2.activateSubsequentClick();
			};
	};
	
	this.activateSubsequentClick = function() {
		toggleDisplay(options,true); // make sure options are visible
		kwdinput.select();
		getOptions();
		kwdinput.onclick = function() {};
	};
	
	this.display = function() {
		var this2 = this;
		// set up the container element
			updateClassName(container,"smartselect","");
		// set up the trigger element
			updateClassName(trigger,"smartselect_trigger","");
			trigger.setAttribute("src","/_scripts/ajax_select/selectarrow_off.gif");
			trigger.onmouseover = function() {this.src = "/_scripts/ajax_select/selectarrow_on.gif";};
			trigger.onmouseout = function() {this.src = "/_scripts/ajax_select/selectarrow_off.gif";};
			trigger.onclick = function() {
					if(toggleDisplay(options)) {
						this2.activateSubsequentClick();
					} else {
						this2.activateInitialClick();
					}
				};
		// set up the keyword form element
			updateClassName(kwdform,"smartselect_form","");
			kwdform.onsubmit = function() {
					if(focusbyarrow === true) {
						if(focusurl.length > 0) {
							//alert(focusurl);
							location.href = focusurl;
						}
					} else {
						getOptions();
					}
					return false;
				};
		// set up the keywork input field
			updateClassName(kwdinput,"smartselect_input","");
			this.setTextValue("");
			kwdinput.onclick = function() {
					this2.activateSubsequentClick();
				};
			if((navigator.appVersion.toLowerCase().indexOf("mac") > -1) && (navigator.appVersion.toLowerCase().indexOf("msie") > -1)) {
				//alert("IE Mac");
			} else {
				kwdinput.onkeyup = function(event) {
						//alert(event);
						if(event === undefined) {
							getOptions_triggered(window.event);
						} else {
							getOptions_triggered(event);
						}
					};
			}
		// set up the options
			updateClassName(options,"smartselect_options","");
		
		// create DOM structure
			container.appendChild(trigger);
			container.appendChild(kwdform);
			container.appendChild(options);
			kwdform.appendChild(kwdinput);
	};
	
	this.setDefaultText = function(txt) {
		defaulttext = txt;
	};
	
	this.setNoResultMessage = function(txt) {
		emptymessage = txt;
	};
	
	this.setOptionsHeight = function(h) {
		options.style.height = ""+h+"px";
		if(reserveheight) {
			container.style.marginBottom = ""+h+"px";
		}
	};
	
	this.setOptionsWidth = function(w) {
		options.style.width = ""+w+"px";
		kwdinput.style.width = ""+w-28+"px";
		kwdform.style.width = ""+w-19+"px";
		container.style.width = ""+w+"px";
	};
	
	this.setRefreshIncrements = function(always,increment) {
		if(always > 0) {triggeralways = always;}
		if((increment > 0) && (increment < 10)) {triggerincrement = increment;}
	};
	
	this.setURLPattern = function(pattern) {
		urlpattern = pattern;
	};
	
	this.setTextValue = function(txt) {
		if(txt.length > 0) {
			kwdinput.value = txt;
		} else {
			kwdinput.value = defaulttext;
		}
	};
	
	this.setReserveHeight = function(tf) {
		reserveheight = tf;
	};
}