function actb(obj,ca){

	/* ---- Public Variables ---- */

	this.actb_timeOut = -1; // Autocomplete Timeout in ms (-1: autocomplete never time out)

	this.actb_lim = -1;    // Number of elements autocomplete can show (-1: no limit)

	this.actb_firstText = false; // should the auto complete be limited to the beginning of keyword?

	this.actb_mouse = true; // Enable Mouse Support

	this.actb_delimiter = new Array(';',',');  // Delimiter for multiple autocomplete. Set it to empty array for single autocomplete

	this.actb_startcheck = 1; // Show widget only after this number of characters is typed in.

	/* ---- Public Variables ---- */



	/* --- Styles --- */

	this.actb_bgColor = '#ffffff';

	this.actb_textColor = '#000000';

	this.actb_hColor = '#fae6b3';

	this.actb_fFamily = 'Verdana';

	this.actb_fSize = '12px';

	this.actb_hStyle = 'text-decoration:underline;font-weight="bold"';

	/* --- Styles --- */



	/* ---- Private Variables ---- */

	var actb_delimwords = new Array();

	var actb_cdelimword = 0;

	var actb_delimchar = new Array();

	var actb_display = false;

	var actb_pos = 0;

	var actb_total = 0;

	var actb_curr = null;

	var actb_rangeu = 0;

	var actb_ranged = 0;

	var actb_bool = new Array();

	var actb_pre = 0;

	var actb_toid;

	var actb_tomake = false;

	var actb_getpre = "";

	var actb_mouse_on_list = 1;

	var actb_kwcount = 0;

	var actb_caretmove = false;

	this.actb_keywords = new Array();

	/* ---- Private Variables---- */

	

	this.actb_keywords = ca;

	var actb_self = this;



	actb_curr = obj;

	

	addEvent(actb_curr,"focus",actb_setup);

	function actb_setup(){

		addEvent(document,"keydown",actb_checkkey);

		addEvent(actb_curr,"blur",actb_clear);

		addEvent(document,"keypress",actb_keypress);

	}



	function actb_clear(evt){

		if (!evt) evt = event;

		removeEvent(document,"keydown",actb_checkkey);

		removeEvent(actb_curr,"blur",actb_clear);

		removeEvent(document,"keypress",actb_keypress);

		actb_removedisp();

	}

	function actb_parse(n){

		if (actb_self.actb_delimiter.length > 0){

			var t = actb_delimwords[actb_cdelimword].trim().addslashes();

			var plen = actb_delimwords[actb_cdelimword].trim().length;

		}else{

			var t = actb_curr.value.addslashes();

			var plen = actb_curr.value.length;

		}

		var tobuild = '';

		var i;



		if (actb_self.actb_firstText){

			var re = new RegExp("^" + t, "i");

		}else{

			var re = new RegExp(t, "i");

		}

		var p = n.search(re);

				

		for (i=0;i<p;i++){

			tobuild += n.substr(i,1);

		}

		tobuild += "<font style='"+(actb_self.actb_hStyle)+"'>"

		for (i=p;i<plen+p;i++){

			tobuild += n.substr(i,1);

		}

		tobuild += "</font>";

			for (i=plen+p;i<n.length;i++){

			tobuild += n.substr(i,1);

		}

		return tobuild;

	}

	function actb_generate(){

		if (document.getElementById('tat_table')){ actb_display = false;document.body.removeChild(document.getElementById('tat_table')); } 

		if (actb_kwcount == 0){

			actb_display = false;

			return;

		}

		a = document.createElement('table');

		a.cellSpacing='1px';

		a.cellPadding='2px';

		a.style.position='absolute';

		a.style.top = eval(curTop(actb_curr) + actb_curr.offsetHeight) + "px";

		a.style.left = curLeft(actb_curr) + "px";

		a.style.backgroundColor=actb_self.actb_bgColor;

		a.id = 'tat_table';

		document.body.appendChild(a);

		var i;

		var first = true;

		var j = 1;

		if (actb_self.actb_mouse){

			a.onmouseout = actb_table_unfocus;

			a.onmouseover = actb_table_focus;

		}

		var counter = 0;

		for (i=0;i<actb_self.actb_keywords.length;i++){

			if (actb_bool[i]){

				counter++;

				r = a.insertRow(-1);

				if (first && !actb_tomake){

					r.style.backgroundColor = actb_self.actb_hColor;

					first = false;

					actb_pos = counter;

				}else if(actb_pre == i){

					r.style.backgroundColor = actb_self.actb_hColor;

					first = false;

					actb_pos = counter;

				}else{

					r.style.backgroundColor = actb_self.actb_bgColor;

				}

				r.id = 'tat_tr'+(j);

				c = r.insertCell(-1);

				c.style.color = actb_self.actb_textColor;

				c.style.fontFamily = actb_self.actb_fFamily;

				c.style.fontSize = actb_self.actb_fSize;

				c.innerHTML = actb_parse(actb_self.actb_keywords[i]);

				c.id = 'tat_td'+(j);

				c.setAttribute('pos',j);

				if (actb_self.actb_mouse){

					c.style.cursor = 'pointer';

					c.onclick=actb_mouseclick;

					c.onmouseover = actb_table_highlight;

				}

				j++;

			}

			if (j - 1 == actb_self.actb_lim && j < actb_total){

				r = a.insertRow(-1);

				r.style.backgroundColor = actb_self.actb_bgColor;

				c = r.insertCell(-1);

				c.style.color = actb_self.actb_textColor;

				c.style.fontFamily = 'arial narrow';

				c.style.fontSize = actb_self.actb_fSize;

				c.align='center';

				replaceHTML(c,'\\/');

				if (actb_self.actb_mouse){

					c.style.cursor = 'pointer';

					c.onclick = actb_mouse_down;

				}

				break;

			}

		}

		actb_rangeu = 1;

		actb_ranged = j-1;

		actb_display = true;

		if (actb_pos <= 0) actb_pos = 1;

	}

	function actb_remake(){

		document.body.removeChild(document.getElementById('tat_table'));

		a = document.createElement('table');

		a.cellSpacing='1px';

		a.cellPadding='2px';

		a.style.position='absolute';

		a.style.top = eval(curTop(actb_curr) + actb_curr.offsetHeight) + "px";

		a.style.left = curLeft(actb_curr) + "px";

		a.style.backgroundColor=actb_self.actb_bgColor;

		a.id = 'tat_table';

		if (actb_self.actb_mouse){

			a.onmouseout= actb_table_unfocus;

			a.onmouseover=actb_table_focus;

		}

		document.body.appendChild(a);

		var i;

		var first = true;

		var j = 1;

		if (actb_rangeu > 1){

			r = a.insertRow(-1);

			r.style.backgroundColor = actb_self.actb_bgColor;

			c = r.insertCell(-1);

			c.style.color = actb_self.actb_textColor;

			c.style.fontFamily = 'arial narrow';

			c.style.fontSize = actb_self.actb_fSize;

			c.align='center';

			replaceHTML(c,'/\\');

			if (actb_self.actb_mouse){

				c.style.cursor = 'pointer';

				c.onclick = actb_mouse_up;

			}

		}

		for (i=0;i<actb_self.actb_keywords.length;i++){

			if (actb_bool[i]){

				if (j >= actb_rangeu && j <= actb_ranged){

					r = a.insertRow(-1);

					r.style.backgroundColor = actb_self.actb_bgColor;

					r.id = 'tat_tr'+(j);

					c = r.insertCell(-1);

					c.style.color = actb_self.actb_textColor;

					c.style.fontFamily = actb_self.actb_fFamily;

					c.style.fontSize = actb_self.actb_fSize;

					c.innerHTML = actb_parse(actb_self.actb_keywords[i]);

					c.id = 'tat_td'+(j);

					c.setAttribute('pos',j);

					if (actb_self.actb_mouse){

						c.style.cursor = 'pointer';

						c.onclick=actb_mouseclick;

						c.onmouseover = actb_table_highlight;

					}

					j++;

				}else{

					j++;

				}

			}

			if (j > actb_ranged) break;

		}

		if (j-1 < actb_total){

			r = a.insertRow(-1);

			r.style.backgroundColor = actb_self.actb_bgColor;

			c = r.insertCell(-1);

			c.style.color = actb_self.actb_textColor;

			c.style.fontFamily = 'arial narrow';

			c.style.fontSize = actb_self.actb_fSize;

			c.align='center';

			replaceHTML(c,'\\/');

			if (actb_self.actb_mouse){

				c.style.cursor = 'pointer';

				c.onclick = actb_mouse_down;

			}

		}

	}

	function actb_goup(){

		if (!actb_display) return;

		if (actb_pos == 1) return;

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_bgColor;

		actb_pos--;

		if (actb_pos < actb_rangeu) actb_moveup();

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_hColor;

		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list=0;actb_removedisp();},actb_self.actb_timeOut);

	}

	function actb_godown(){

		if (!actb_display) return;

		if (actb_pos == actb_total) return;

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_bgColor;

		actb_pos++;

		if (actb_pos > actb_ranged) actb_movedown();

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_hColor;

		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list=0;actb_removedisp();},actb_self.actb_timeOut);

	}

	function actb_movedown(){

		actb_rangeu++;

		actb_ranged++;

		actb_remake();

	}

	function actb_moveup(){

		actb_rangeu--;

		actb_ranged--;

		actb_remake();

	}



	/* Mouse */

	function actb_mouse_down(){

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_bgColor;

		actb_pos++;

		actb_movedown();

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_hColor;

		actb_curr.focus();

		actb_mouse_on_list = 0;

		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list=0;actb_removedisp();},actb_self.actb_timeOut);

	}

	function actb_mouse_up(evt){

		if (!evt) evt = event;

		if (evt.stopPropagation){

			evt.stopPropagation();

		}else{

			evt.cancelBubble = true;

		}

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_bgColor;

		actb_pos--;

		actb_moveup();

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_hColor;

		actb_curr.focus();

		actb_mouse_on_list = 0;

		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list=0;actb_removedisp();},actb_self.actb_timeOut);

	}

	function actb_mouseclick(evt){

		if (!evt) evt = event;

		if (!actb_display) return;

		actb_mouse_on_list = 0;

		actb_pos = this.getAttribute('pos');

		actb_penter();

	}

	function actb_table_focus(){

		actb_mouse_on_list = 1;

	}

	function actb_table_unfocus(){

		actb_mouse_on_list = 0;

		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list = 0;actb_removedisp();},actb_self.actb_timeOut);

	}

	function actb_table_highlight(){

		actb_mouse_on_list = 1;

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_bgColor;

		actb_pos = this.getAttribute('pos');

		while (actb_pos < actb_rangeu) actb_moveup();

		while (actb_pos > actb_ranged) actb_movedown();

		document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_self.actb_hColor;

		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list = 0;actb_removedisp();},actb_self.actb_timeOut);

	}

	/* ---- */



	function actb_insertword(a){

		if (actb_self.actb_delimiter.length > 0){

			str = '';

			l=0;

			for (i=0;i<actb_delimwords.length;i++){

				if (actb_cdelimword == i){

					prespace = postspace = '';

					gotbreak = false;

					for (j=0;j<actb_delimwords[i].length;++j){

						if (actb_delimwords[i].charAt(j) != ' '){

							gotbreak = true;

							break;

						}

						prespace += ' ';

					}

					for (j=actb_delimwords[i].length-1;j>=0;--j){

						if (actb_delimwords[i].charAt(j) != ' ') break;

						postspace += ' ';

					}

					str += prespace;

					str += a;

					l = str.length;

					if (gotbreak) str += postspace;

				}else{

					str += actb_delimwords[i];

				}

				if (i != actb_delimwords.length - 1){

					str += actb_delimchar[i];

				}

			}

			actb_curr.value = str;

			setCaret(actb_curr,l);

		}else{

			actb_curr.value = a;

		}

		actb_mouse_on_list = 0;

		actb_removedisp();

	}

	function actb_penter(){

		if (!actb_display) return;

		actb_display = false;

		var word = '';

		var c = 0;

		for (var i=0;i<=actb_self.actb_keywords.length;i++){

			if (actb_bool[i]) c++;

			if (c == actb_pos){

				word = actb_self.actb_keywords[i];

				break;

			}

		}

		actb_insertword(word);

		l = getCaretStart(actb_curr);

	}

	function actb_removedisp(){

		if (actb_mouse_on_list==0){

			actb_display = 0;

			if (document.getElementById('tat_table')){ document.body.removeChild(document.getElementById('tat_table')); }

			if (actb_toid) clearTimeout(actb_toid);

		}

	}

	function actb_keypress(e){

		if (actb_caretmove) stopEvent(e);

		return !actb_caretmove;

	}

	function actb_checkkey(evt){

		if (!evt) evt = event;

		a = evt.keyCode;

		caret_pos_start = getCaretStart(actb_curr);

		actb_caretmove = 0;

		switch (a){

			case 38:

				actb_goup();

				actb_caretmove = 1;

				return false;

				break;

			case 40:

				actb_godown();

				actb_caretmove = 1;

				return false;

				break;

			case 13: case 9:

				if (actb_display){

					actb_caretmove = 1;

					actb_penter();

					return false;

				}else{

					return true;

				}

				break;

			default:

				setTimeout(function(){actb_tocomplete(a)},50);

				break;

		}

	}



	function actb_tocomplete(kc){

		if (kc == 38 || kc == 40 || kc == 13) return;

		var i;

		if (actb_display){ 

			var word = 0;

			var c = 0;

			for (var i=0;i<=actb_self.actb_keywords.length;i++){

				if (actb_bool[i]) c++;

				if (c == actb_pos){

					word = i;

					break;

				}

			}

			actb_pre = word;

		}else{ actb_pre = -1};

		

		if (actb_curr.value == ''){

			actb_mouse_on_list = 0;

			actb_removedisp();

			return;

		}

		if (actb_self.actb_delimiter.length > 0){

			caret_pos_start = getCaretStart(actb_curr);

			caret_pos_end = getCaretEnd(actb_curr);

			

			delim_split = '';

			for (i=0;i<actb_self.actb_delimiter.length;i++){

				delim_split += actb_self.actb_delimiter[i];

			}

			delim_split = delim_split.addslashes();

			delim_split_rx = new RegExp("(["+delim_split+"])");

			c = 0;

			actb_delimwords = new Array();

			actb_delimwords[0] = '';

			for (i=0,j=actb_curr.value.length;i<actb_curr.value.length;i++,j--){

				if (actb_curr.value.substr(i,j).search(delim_split_rx) == 0){

					ma = actb_curr.value.substr(i,j).match(delim_split_rx);

					actb_delimchar[c] = ma[1];

					c++;

					actb_delimwords[c] = '';

				}else{

					actb_delimwords[c] += actb_curr.value.charAt(i);

				}

			}



			var l = 0;

			actb_cdelimword = -1;

			for (i=0;i<actb_delimwords.length;i++){

				if (caret_pos_end >= l && caret_pos_end <= l + actb_delimwords[i].length){

					actb_cdelimword = i;

				}

				l+=actb_delimwords[i].length + 1;

			}

			var ot = actb_delimwords[actb_cdelimword].trim(); 

			var t = actb_delimwords[actb_cdelimword].addslashes().trim();

		}else{

			var ot = actb_curr.value;

			var t = actb_curr.value.addslashes();

		}

		if (ot.length == 0){

			actb_mouse_on_list = 0;

			actb_removedisp();

		}

		if (ot.length < actb_self.actb_startcheck) return this;

		if (actb_self.actb_firstText){

			var re = new RegExp("^" + t, "i");

		}else{

			var re = new RegExp(t, "i");

		}



		actb_total = 0;

		actb_tomake = false;

		actb_kwcount = 0;

		for (i=0;i<actb_self.actb_keywords.length;i++){

			actb_bool[i] = false;

			if (re.test(actb_self.actb_keywords[i])){

				actb_total++;

				actb_bool[i] = true;

				actb_kwcount++;

				if (actb_pre == i) actb_tomake = true;

			}

		}



		if (actb_toid) clearTimeout(actb_toid);

		if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list = 0;actb_removedisp();},actb_self.actb_timeOut);

		actb_generate();

	}

	return this;

}