function ac(object,output,table,field,enable_add,mustexist) {
//set the autocomplete to the object

	// kill the autocomplete 
	try {gid(object).setAttribute("autocomplete","off"); } catch (err) {}
	
	// preserve event functions
	var keyup=gid(object).onkeyup;
	var blur=gid(object).onblur;
	var focus=gid(object).focus;
	
	gid(object).onkeyup=function() {
		autocomplete(gid(object),output,table,field,enable_add,mustexist);
		try {keyup();} catch (err) {}  	
	}
	gid(object).onfocus=function () {
		gid(object).select();
		try {focus();} catch (err) {}
	}
	gid(object).onblur=function() {
		reset_autocomplete(gid(object),output);
		try{blur();} catch (err) {} 
	}
}

function ac_reset(object) {
	gid(object).onkeyup='';
	gid(object).onblur='';
	gid(object).onfocus='';
}

// autocomplete functions
	
var css_selected_color='#88cb1c';
var css_text_color='#355600';
var css_background_color='#FFFFFF';
var autocomplete_sever_side='autocomplete/autocomplete.php';

var keycode;
var topobject='';
var topoutput='';
var toptable='';
var topfield='';
var topmustexist=false;
var chosen=false;
var current_value='';

var ac_current=0;
var current_sel=0;
var ac_exist=false;



function saveKeycode(e) {
	if (window.event) keycode = window.event.keyCode; 
	else if (e) keycode = e.which;	
}
function gid(element) {
	return document.getElementById(element);
}
function newHTTP() {
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;
	  }
	}
  }
  
  return xmlHttp;
}
function ajax(page,returnobject) {
var xmlHttp=newHTTP();
  xmlHttp.onreadystatechange=function() {
	if (xmlHttp.readyState==4) {
		try {
			if (returnobject=='eval') {
				try {eval (xmlHttp.responseText); } catch (err) {window.alert(err+"\n"+xmlHttp.responseText);}
				
			} else {
				if (xmlHttp.responseText.length>0) {
					document.getElementById(returnobject).innerHTML =xmlHttp.responseText;
				}
				xmlHttp='';
				if (gid('eval')) {
					if (gid('eval').value!='') {
						eval(gid('eval').value);
						gid('eval').value='';
					}
				}
				return true;
			}
		} catch(err) {
			//window.alert(err);
		}
	}
  }
  xmlHttp.open("GET",page+"&random="+Math.random(),true);
  xmlHttp.send(null);
return true;  
}
function trim (str, charlist) {
	var whitespace, l = 0, i = 0;
	str += '';
	
	if (!charlist) {
		// default list
		whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
	} else {
		// preg_quote custom list
		charlist += '';
		whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1');
	}
	
	l = str.length;
	for (i = 0; i < l; i++) {
		if (whitespace.indexOf(str.charAt(i)) === -1) {
			str = str.substring(i);
			break;
		}
	}
	
	l = str.length;
	for (i = l - 1; i >= 0; i--) {
		if (whitespace.indexOf(str.charAt(i)) === -1) {
			str = str.substring(0, i + 1);
			break;
		}
	}
	
	return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}
function walkDOMtree(element,attribute,arr) {
	var i=0;
	for (i=0; i<element.childNodes.length; i++) {
		eval('if (element.childNodes[i].'+attribute+') arr.push(element.childNodes[i]);');
		if (element.childNodes[i].childNodes.length>0) walkDOMtree(element.childNodes[i],attribute,arr);
	}	
}
function urlencode( str ) {         
	var histogram = {}, tmp_arr = [];
	var ret = (str+'').toString();
	
	var replacer = function(search, replace, str) {
		var tmp_arr = [];
		tmp_arr = str.split(search);
		return tmp_arr.join(replace);
	};
	
	// The histogram is identical to the one in urldecode.
	histogram["'"]   = '%27';
	histogram['(']   = '%28';
	histogram[')']   = '%29';
	histogram['*']   = '%2A';
	histogram['~']   = '%7E';
	histogram['!']   = '%21';
	histogram['%20'] = '+';
	histogram['\u20AC'] = '%80';
	histogram['\u0081'] = '%81';
	histogram['\u201A'] = '%82';
	histogram['\u0192'] = '%83';
	histogram['\u201E'] = '%84';
	histogram['\u2026'] = '%85';
	histogram['\u2020'] = '%86';
	histogram['\u2021'] = '%87';
	histogram['\u02C6'] = '%88';
	histogram['\u2030'] = '%89';
	histogram['\u0160'] = '%8A';
	histogram['\u2039'] = '%8B';
	histogram['\u0152'] = '%8C';
	histogram['\u008D'] = '%8D';
	histogram['\u017D'] = '%8E';
	histogram['\u008F'] = '%8F';
	histogram['\u0090'] = '%90';
	histogram['\u2018'] = '%91';
	histogram['\u2019'] = '%92';
	histogram['\u201C'] = '%93';
	histogram['\u201D'] = '%94';
	histogram['\u2022'] = '%95';
	histogram['\u2013'] = '%96';
	histogram['\u2014'] = '%97';
	histogram['\u02DC'] = '%98';
	histogram['\u2122'] = '%99';
	histogram['\u0161'] = '%9A';
	histogram['\u203A'] = '%9B';
	histogram['\u0153'] = '%9C';
	histogram['\u009D'] = '%9D';
	histogram['\u017E'] = '%9E';
	histogram['\u0178'] = '%9F';
	
	// Begin with encodeURIComponent, which most resembles PHP's encoding functions
	ret = encodeURIComponent(ret);
	
	for (search in histogram) {
		replace = histogram[search];
		ret = replacer(search, replace, ret) // Custom replace. No regexing
	}
	
	// Uppercase for full PHP compatibility
	return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
		return "%"+m2.toUpperCase();
	});
	
	return ret;
}
function ac_prepare(value) {
		current_value=value;
		chosen=true;		
}
function ac_select() {
	if (chosen) {
		topobject.value=current_value;
		try {eval(gid(topoutput).title)} catch (err) {/*window.alert(err);*/}
		chosen=false;
		reset_autocomplete(topobject,topoutput);
	}
}
function ac_addvalue() {
	var value=gid('ac_newentry').value;
	ajax(autocomplete_sever_side+"?table="+toptable+"&field="+topfield+"&value="+urlencode(value)+"&exist=1&insert=1",'eval');
}
function ac_newentry_test() {
	if (keycode==13) ac_addvalue();
}
function ac_cancel(value) {
	if (value==false) {
		topobject.value='';
	}
}
function reset_autocomplete(object,output) {
	ac_current=0;
	if (chosen || (gid("ac_newentry") && !gid("ac_items"))) return false; 
	if (topmustexist) {
		ajax(autocomplete_sever_side+"?table="+toptable+"&field="+topfield+"&value="+urlencode(object.value)+"&exist=1",'eval');
	}
	if (gid(output)) {
		gid(output).innerHTML='';
	}
}
function autocomplete(object,output,table,field,enable_add,mustexist) {
	try {
		gid(output).style.fontSize='0px';
		gid(output).style.height='0px';
		gid(output).style.lineHeight='0px';
	} catch (err) {/*window.alert(err);*/}
	
	if (keycode==27) {
		chosen=false;
		reset_autocomplete(object,output)
		return false;
	}
	
		if (gid('ac_items')) {
			try {eval(gid('ac_items').innerHTML);} catch (err) {}
			
			if (ac_items.length==0 && enable_add!='')  {
				try {gid("ac_newentry").value=object.value;} catch (err) {window.alert(err);} 
				if (keycode==13) {
					ac_addvalue();
					return true;
				}
			}
			
			if (keycode==13) {
				if (ac_items[ac_current]) {
					object.value=ac_items[ac_current];
					try {eval(gid(output).title)} catch (err) {/*window.alert(err);*/}
				}
				reset_autocomplete(object,output)
				return true;
			}
			
			
			var direction=0;
			if (keycode==40) direction=1;
			if (keycode==38) direction=-1;
			
			if (direction!=0) {
				var item=gid('ac_'+ac_current);
				item.style.background=css_background_color;
				item.style.color=css_text_color;
				ac_current+=direction;
				if (ac_current<0) ac_current=ac_items.length-1;
				
				ac_current=(ac_current)%ac_items.length;
				item=gid('ac_'+ac_current);
				item.style.background=css_selected_color;
				item.style.color=css_background_color;
				chosen=false;
				return true;
			}
			
	}
	
	if (topobject && topobject!=object) reset_autocomplete(topobject,topoutput);
	try {
		ajax(autocomplete_sever_side+"?table="+table+"&field="+field+"&value="+urlencode(object.value)+"&add="+enable_add,output);
	} catch (err) {/*window.alert(err);*/}

	topobject=object;
	topoutput=output;
	toptable=table;
	topfield=field;
	topmustexist=mustexist;
	ac_items=new Array();
	ac_current=0;

}

document.onkeydown = saveKeycode
