function makedSuggest(base_elem, choicescript, showempty, dsmode, multiple, allowdouble, multscript, absolute) {

	// Turn a common input element into a hitech piece of art.
	// See dsuggest.info.txt
	var base = document.getElementById(base_elem);
	base.choiceval = "";
	base.descript = "";
	base.preselect = 0;
	base.choicescript = choicescript;
	base.showempty = showempty;
	base.dsmode = dsmode;
	base.multiple = multiple;
	base.multscript = multscript;
	base.allowdouble = allowdouble;
	if(absolute) {
		base.absolute = document.getElementById(absolute); // id of absolute positioned parent if applicable
	} else {
		base.absolute = false;
	}
	base.choicediv = makeChoiceDiv(base);
	base.returnelement = makeReturnElement(base);
	if(base.multiple) {
		makeMultiple(base);
	}
	
	base.onkeyup = function(event) {
		try { //IE
			var whatkey = event.keyCode;
		} catch (e) {
			try { //FF	
				var whatkey = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
			} catch (e) {
				try {
					var whatkey = window.event.keyCode;
				} catch (e) {
					//alert('Cannot read event');
				}
			}
		}
		dSfill(this, whatkey);
	}
	base.onkeydown = function(event) {
		try { //IE
			var whatkey = event.keyCode;
		} catch (e) {
			try { //FF	
				var whatkey = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
			} catch (e) {
				try { //IE again. get me Bi... ah, never mind :(
					var whatkey = window.event.keyCode;
				} catch (e) {
					//alert('Cannot read event');
				}
			}
		}
		if(whatkey == 9) { //catch tab by its tail
			if(processKey(this, whatkey)) {
				return false;
			}
		} else {
			processKey(this, whatkey);
		}
	}
	base.onmousedown = function () {
		if((base.showempty) && (base.value == "")) {
			dSfill(base, "");
		}
	}
	base.onblur = function () {
		this.choicediv.style.display = "none";
		this.choicediv.innerHTML = "";
		this.choicediv.style.display = "none";
		if(this.returnelement.value == "") {
			this.value = "";
		}
	}
	function makeChoiceDiv(base) {
		// containerdiv for choices
		var cdiv = document.createElement("div");
		base.parentNode.appendChild(cdiv);
		cdiv.style.inherit = "none";
		cdiv.id = base.id + '_choices';
		cdiv.style.position = "absolute";
		cdiv.style.display = "none";
		cdiv.className = "dsuggest";
		cdiv.style.backgroundColor = "#FFFFFF";
		return cdiv;
	}
	function makeReturnElement(base) {
		// input element for return value, if none given
		var relm;
		if(!document.getElementById(base.id + '_return')) {
			var relm = document.createElement("input");
			base.parentNode.appendChild(relm);
			relm.id = base.id + '_return';
			relm.style.display = "none";
			relm.value = "";
			return relm;
		} else {
			return document.getElementById(base.id + '_return');
		}
	}
	function dSfill(base, whatkey) {
		if(whatkey == 9 || whatkey == 40 || whatkey == 38 || whatkey == 13) {
			return false;
		}
		if(base.dsmode != "suggest") {
			base.returnelement.value = "";
		} else {
			base.returnelement.value = base.value;
		}
		if((base.value == "") && (!base.showempty)) {
			base.choicediv.style.display = 'none';
			base.choicediv.innerHTML = "";
			return false;
		}
		base.preselect = 0;
		var xmlHttp;
		try {					// Firefox, Opera 8.0+, Safari
			xmlHttp=new XMLHttpRequest();
		} catch (e) {			// Internet Explorer
			try {
				xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
				try {
					xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
				} catch (e) {
					alert("Your browser does not support AJAX!");
					return false;
				}
			}
		}

		xmlHttp.onreadystatechange = function() {
		
			if (xmlHttp.readyState==4) {
				base.choicediv.innerHTML = "";			
				var dres = xmlHttp.responseText;
				if(dres !== 'false') {
					base.choicediv.style.display = 'block';
					if(!base.absolute) {
						base.choicediv.style.top = base.offsetHeight + findPosY(base) + 'px';
						base.choicediv.style.left = findPosX(base) + 'px';
					} else {
						var corry = findPosY(base) - findPosY(base.absolute);
						var corrx = findPosX(base) - findPosX(base.absolute);
						base.choicediv.style.top = base.offsetHeight + corry + 'px';
						base.choicediv.style.left = corrx + 'px';
					}
					base.choicediv.style.width = base.offsetWidth + 'px';

					var dresar = dres.split('<retv>');
					for(i = 1; i < dresar.length; i++) {
						var respl = dresar[i].split('<desc>');
						var desc = respl[1].split('<cust>');
						var rdiv = document.createElement("div");
						base.choicediv.appendChild(rdiv);
						rdiv.id = base.id+'_'+i;
						rdiv.choiceval = respl[0];
						rdiv.descript = desc[0];
						rdiv.numb = i;
						rdiv.className = 'dsuggestselectout';
						rdiv.onmouseover = function() {
							base.preselect.className = 'dsuggestselectout';
							base.preselect = this;
							this.className = 'dsuggestselect';
						}
						rdiv.onmouseout = function() {
							this.className = 'dsuggestselectout';
						}
						rdiv.onmousedown = function() {
							dsSelect(base);
						}
						if(base.dsmode == "custom") {
							rdiv.innerHTML = desc[1];
						} else {
							rdiv.innerHTML = desc[0];
						}
					}
				} else {
					base.choicediv.style.display = 'none';
				}
			}
		}
		xmlHttp.open("GET", base.choicescript+"val="+base.value, true);
		xmlHttp.send(null);
	}

	function dsSelect(base) {
		base.value = base.preselect.descript;
		base.returnelement.value = base.preselect.choiceval;
		base.choicediv.style.display = 'none';
		base.choicediv.innerHTML = "";
		base.preselect = 0;
	}

	function processKey(base, key) {
		if(key == 9) { //tab: catch first if present, else go ahead
			if(base.preselect != 0) {
				dsSelect(base);
				return true;
			} else if((document.getElementById(base.id+'_1')) && (base.dsmode != "suggest")) {
				base.preselect = document.getElementById(base.id+'_1');
				dsSelect(base);
				return true;
			} else {
				return false;
			}
		}
		if(key == 13) { //enter
			if(base.preselect != 0) {
				dsSelect(base);
			} else {
				if(document.getElementById(base.id+'_1')) {
					base.preselect = document.getElementById(base.id+'_1');
					dsSelect(base);
				} else if((base.multiple) && (base.returnelement.value != "")) {
					if(!base.multscript) {
						procMultiple(base);
					} else {
						base.multscript.apply();
					}
				}
			}
		}
		if(key == 40) { //arrow down
			oneDown(base)
		}
		if(key == 38) { //arrow up
			oneUp(base);
		}
	}
	function oneDown(base) {
		if(base.preselect == 0) {
			if(document.getElementById(base.id + '_1')) {
				base.preselect = document.getElementById(base.id + '_1');
				base.preselect.className = 'dsuggestselect';
			} 
		} else {
			if(document.getElementById(base.id + '_' + (base.preselect.numb + 1))) {
				base.preselect.className = 'dsuggestselectout';
				base.preselect = document.getElementById(base.id + '_' + (base.preselect.numb + 1));
				base.preselect.className = 'dsuggestselect';
			}
		}
	}
	function oneUp(base) {
		if(base.preselect != 0) {
			if(document.getElementById(base.id + '_' + (base.preselect.numb - 1))) {
				base.preselect.className = 'dsuggestselectout';
				base.preselect = document.getElementById(base.id + '_' + (base.preselect.numb - 1));
				base.preselect.className = 'dsuggestselect';
			} else {
				base.preselect.className = 'dsuggestselectout';
				base.preselect = 0;
			}
		}
	}
	function makeMultiple(base) {
		if(document.getElementById(base.id + '_add')) {
			base.addbutton = document.getElementById(base.id + '_add');
			base.addbutton.onclick = function () {
				if(!base.multscript) {
					procMultiple(base);
				} else {
					base.multscript.apply();
				}
			}
		} else {
			alert('Can\'t find button with id ' + base.id + '_add');
			return false;
		}
		if(!base.multscript) {
			// the default handling of multiple choices, not called if a multscript is specified
			if(document.getElementById(base.id + '_window')) {
				base.mwin = document.getElementById(base.id + '_window');
			} else {
				alert('Can\'t find block element with id ' + base.id + '_window');
				return false;
			}
			if(document.getElementById(base.id + '_multiple')) {
				base.multelement = document.getElementById(base.id + '_multiple');
				//ugly browserhack, refresh doesn't update input values in some browsers :(
				if(document.getElementById(base.id + '_ref')) {
					base.multelement.value = document.getElementById(base.id + '_ref').value;
				}	
			} else {
				alert('Can\'t find input element with id ' + base.id + '_multiple');
				return false;
			}
		}
	}
	function procMultiple(base) {
		//only called in "multiple" when param "multscript" is false
		if(base.returnelement.value == "") {
			alert('element is leeg');
			return false;
		}
		if(base.allowdouble) {
			base.multelement.value += ('~' + base.returnelement.value);
			addMultiple(base);
		} else {
			var chck = true;
			var cur = base.multelement.value.split('~');
			for(i = 0; i < cur.length; i++) {
				if(cur[i] == base.returnelement.value) {
					chck = false;
				}
			}
			if(chck) {
				base.multelement.value += ('~' + base.returnelement.value);
				addMultiple(base);
			}
		}
		//reset
		base.returnelement.value = "";	
		base.value = "";

		function addMultiple(base) {
			var mldiv = document.createElement("div");
			base.mwin.appendChild(mldiv);
			mldiv.id = base.id + '_mlt_' + base.returnelement.value;
			mldiv.innerHTML = base.value;
			var mlrem = document.createElement("span");
			mldiv.appendChild(mlrem);
			mlrem.retval = base.returnelement.value;
			mlrem.style.color = "red";
			mlrem.style.fontWeight = "bold";
			mlrem.style.fontSize = "12px";
			mlrem.style.cursor = "pointer";
			mlrem.innerHTML = "&nbsp;x&nbsp;";
			mlrem.onclick = function () {
				dSuggestRemoveOne(mldiv.id, base.id, this.retval);
			}			
		}
	}
}

function dSuggestRemoveOne(elemid, baseid, destroy) {
	//alert(elemid+'-'+baseid+'-'+destroy);
	var elem = document.getElementById(elemid);
	var base = document.getElementById(baseid);
	var cur = base.multelement.value.split('~');
	var nw = "";
	var firsthit = true;
	for(i = 1; i < cur.length; i++) {
		if((cur[i] == destroy) && (firsthit)) {
			firsthit = false;
		} else {
			nw += '~' + cur[i];
		}
	}
	base.multelement.value = nw;
	elem.parentNode.removeChild(elem);
}
