

function actb(obj,ca, instance, client_parameters){
	/* ---- Public Variables ---- */
	this.actb_timeOut = -1; // Autocomplete Timeout in ms (-1: autocomplete never time out)
	this.actb_lim = 4;    // 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_list_extra_width = 0; 
	this.actb_more_results_available_msg = '';
	this.actb_bgColor = '#FAFBFC';
	this.actb_textColor = '#000000';
	this.actb_hColor = '#CDEDFC';
	this.actb_fFamily = 'Verdana';
	this.actb_fSize = '11px';
	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();
	this.actb_hasfocus = false;
	this.instance = instance;
	this.client_parameters = client_parameters;
	
	this.recheck = function(){
		var e;
		try 
			{
				// IE style
				e = document.createEventObject('onkeydown');
			} catch(err){
				// Mozilla style
				e = document.createEvent('HTMLEvents');
			}

		actb_checkkey(e);
	};
	
	/* ---- 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;
		}
		return n;
	}
	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;
		}

		var parentTable = document.createElement('table');
		parentTable.cellSpacing='0px';
		parentTable.cellPadding='0px';
		
		parentTable.style.position='absolute';
		parentTable.style.top = eval(curTop(actb_curr) + actb_curr.offsetHeight) + "px";
		parentTable.style.left = curLeft(actb_curr) + "px";

		parentTable.style.width = actb_curr.offsetWidth + actb_self.actb_list_extra_width;
		
		parentTable.id = 'tat_table';
		document.body.appendChild(parentTable);

		a = document.createElement('table');
		a.cellSpacing='1px';
		a.cellPadding='2px';
		
		a.style.backgroundColor=actb_self.actb_bgColor;
		a.style.borderBottom = '1px solid #DDDDDD';
		a.style.width = '100%';
		a.style.borderTop = a.style.borderLeft = a.style.borderRight = a.style.borderBottom;
		
		a.id = 'tat_table_child';

		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;
				var html = actb_parse(actb_self.actb_keywords[i]);
				
				c.innerHTML = html;

				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;
			}
		}
		//inserting "more results" line
		if (actb_self.more_results) {
				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 = actb_self.actb_fFamily;
				c.style.fontSize = actb_self.actb_fSize;
				c.innerHTML = "<font color=#000088><i>" + actb_more_results_available_msg +  "<i></font>";
		}
		//end of inserting "more results" line							

		var contentTR = parentTable.insertRow(-1);
		var contentTD = contentTR.insertCell(-1);
		contentTD.appendChild(a);

		var bottomTR = parentTable.insertRow(-1);
		var bottomTD = bottomTR.insertCell(-1);

		bottomTD.innerHTML = _get_table_bottom_html(this.instance, actb_curr.offsetWidth + actb_self.actb_list_extra_width);
		actb_rangeu = 1;
		actb_ranged = j-1;
		actb_display = true;
		if (actb_pos <= 0) actb_pos = 1;
	}
	function _get_table_bottom_html(instance, width){
		var imageRoot = "/" + instance + "/img/azlist_ver3/";
		
		return 	'<table border=0 cellspacing=0 cellpadding=0 style="width:' + width + '; height:8px">' +
				'<tr>' +
				'	<td><img style="width: 4px;  height: 8px" 		src="' + imageRoot + 'ajax_box_bar_left.jpg"/></td>' +
				'	<td><img style="width: ' + (parseInt(width) - 8) + 'px; height: 8px"  	src="' + imageRoot + 'ajax_box_bar_middle.jpg"/></td>' +
				'	<td><img style="width: 4px;  height: 8px" 		src="' + imageRoot + 'ajax_box_bar_right.jpg"/></td>' +
				'</tr>' +
				'</table>';
	
	}
	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);
		triggerListCheck(false, actb_curr.id);
	}
	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();
		
		var AutocompleteObj;
		eval("AutocompleteObj = AutocompleteObj_" + actb_curr.id);

		ajaxStart(actb_curr.id, AutocompleteObj.client_parameters);
	}
	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_self.actb_hasfocus==false) actb_toid = setTimeout(function(){actb_mouse_on_list = 0;actb_removedisp();},actb_self.actb_timeOut);
	}
	function actb_table_highlight(){
		actb_mouse_on_list = 1;
		var objTR = document.getElementById('tat_tr' + actb_pos);
		if (objTR==null) return;
		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];
				//remove bold and underscore
				word = word.replace(/<.+?>/g,'');
				break;
			}
		}
		actb_insertword(word);
		l = getCaretStart(actb_curr);

		actb_curr.focus();		
		setCaret(actb_curr, actb_curr.value.length);
	}
	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){
		try {
			if (!evt) evt = event;
			a = evt.keyCode;
			caret_pos_start = getCaretStart(actb_curr);
			actb_caretmove = 0;
	
			switch (a){
				case 27:
					actb_mouse_on_list = 0;
					actb_curr.blur();
					return false;
					break;
	
				case 38:
					actb_goup();
					actb_caretmove = 1;
					return false;
					break;
				case 40:
					actb_godown();
					actb_caretmove = 1;
					return false;
					break;
				case 13: 
					return true;
				break;
				case 9:
					if (actb_display){
						actb_caretmove = 1;
						actb_penter();
						return false;
					}else{
						return true;
					}
					break;
				default:
					setTimeout(function(){actb_tocomplete(a)},50);
					break;
			}
		} catch(e){
		}
	}
	function sortTitle(a, b)
	{
		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 placeA = a.search(re);
		if (placeA == -1) placeA = 1000;

		var placeB = b.search(re);
		if (placeB == -1) placeB = 1000;
		return placeA - placeB;
	}
	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");
		}
		
		var exactRe = new RegExp("^" + t + "$", "i");
			
		actb_total = 0;
		actb_tomake = false;
		actb_kwcount = 0;
		
		var lastMatch = 0;
// moved sorting to server size	
//		actb_self.actb_keywords.sort(sortTitle);
		
		for (i=0;i<actb_self.actb_keywords.length;i++){
			actb_bool[i] = false;
// Commented out for showing even not matching titles 
//	since the filtering is made on the server side			
//			if (re.test(actb_self.actb_keywords[i])){
				lastMatch = i;
				actb_total++;
				actb_bool[i] = true;
				actb_kwcount++;
				if (actb_pre == i) actb_tomake = true;
//			}
		}				

		if (actb_total==1 && exactRe.test(actb_self.actb_keywords[lastMatch].replace(/<.+?>/g,''))){
			actb_tomake = false;
			actb_kwcount = 0;
			actb_total = 0;
			actb_bool[lastMatch] = 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;
}

//---------------------------------------------------
//---------------------------------------------------
//starts fetching the autocomlete list from the KB
function ajaxStart(id, client_parameters){
	if (client_parameters!='')
		client_parameters+=',';
	eval("find_" + id + "( [id," + client_parameters + "'NO_CACHE'], [ajaxFinish]); ");
}

// returns
// 0) __list__
// 1) pattern searches
// 2) id of the control
// 3) are more results available
// 4) and more) the list itself
//fired after the autocomlete list is fetched
function ajaxFinish(){

	if (ajaxFinish.arguments.length ==0 || ajaxFinish.arguments[0]!='__list__') return;
	var input = document.getElementById(ajaxFinish.arguments[2]);
	//validate this is our response

	if (input.value!=Base64.decode(ajaxFinish.arguments[1])) {
//		console.log("Input is " + input.value + " encoded " + Base64.encode(input.value));
//		console.log("Received " + Base64.decode(ajaxFinish.arguments[1]) + " encoded " + ajaxFinish.arguments[1]);
		
		triggerListCheck(true, arguments[2]);
		return;
	}
	replaceWordList(ajaxFinish.arguments);

}

//-------------------------------------------------------
// Autocomplete 

//updates the autocomlete list with a new one
function replaceWordList(){
	var AutocompleteObj;

	eval("AutocompleteObj = AutocompleteObj_" + arguments[0][2]);	
	
	if (!AutocompleteObj) return;

	var list = new Array();
	for (var i = 4; i<arguments[0].length; i++){
		var incoming = arguments[0][i];
		incoming = Base64.decode(incoming);
		list[ i - 4 ] = incoming;
	}
	AutocompleteObj.actb_keywords = list;
	AutocompleteObj.more_results = arguments[0][3];
	triggerListCheck(true, arguments[0][2]);
}



function triggerListCheck(immidiate, obj_id){
	var AutocompleteObj;
	eval("AutocompleteObj = AutocompleteObj_" + obj_id);

    if (immidiate) 
    	fireKeyEvent(AutocompleteObj);
   	else
   		setTimeout(function(){fireKeyEvent(AutocompleteObj)},50);
}

function fireKeyEvent(AutocompleteObj){
	AutocompleteObj.recheck();
}
