function ACObject(obj_name)
{
	var acdiv = (document.getElementById("acDiv")==null ? document.createElement("DIV") : document.getElementById("acDiv"));
	acdiv.id = "acDiv";
	acdiv.className = "menu";
	acdiv.style.zIndex = 5;
	acdiv.style.visibility = "hidden";
	document.body.appendChild(acdiv);
	var acmenu = new xMenu1(null, 'acDiv');
	var cache = new Hashtable();
	
	var objName = obj_name;
	var txtObj = null;
	var servlet = null;
	var prevTxt;
	var selectedIdx;
	var itemCount;
//	var parentObj = null;
	
	this.SetAC = setAC;
	this.DoSelect = doSelect;
	this.DoClick = doClick;
	this.GetParam = function () { return param; }
	
	var timer = null;
	var results;
	var fromkey;
	var param;
	var callback;
	var originate_obj; //trigger object
	var parent_obj; // container object
	
	var onfocus_call=null;
	var onblur_call=null;
	function setAC(tobj, servl, par, cback, ori_obj, on_focus, on_blur, parent)
	{
		if (timer) clearTimeout(timer); timer = null;
		isenabled = true;
		servlet = servl;
		prevTxt = '';
		selectedIdx = -1;
		itemCount = 0;
		if (param!=par)
		{
			cache.clear();
			param = par;
		}
		callback = cback;
		originate_obj = ori_obj;
		parent_obj = parent;
		if (txtObj!=null)
		{
			txtObj.onkeyup = null;
			txtObj.onkeydown = null;
			txtObj.onfocus = null;
			txtObj.onblur = null;
		}
		if (tobj==null)
		{
			if (txtObj!=null)
			{
//				txtObj.onfocus = on_focus;
//				txtObj.onblur = on_blur;
			}
			return;
		}
		txtObj = tobj;
		txtObj.onkeyup = okuh;
		txtObj.onkeydown = function(e)
		{
			if (!acmenu.isOpen()) return;
			var kc;
			var nextIdx;
			if (e)
				kc=e.which;
			else
				kc=window.event.keyCode;
			if (kc==38) //up
			{
				if (selectedIdx>=0)
				{
					nextIdx = selectedIdx - 1;
				}
				else
				{
					 nextIdx = itemCount - 1;
				}
				doSelect(nextIdx, true);
			}
			else if (kc==40) //down
			{
				if (selectedIdx+1==itemCount)
				{
					nextIdx = -1;
				}
				else
				{
					nextIdx = selectedIdx + 1;
				}
				doSelect(nextIdx, true);
			}
			else if (kc==27) //esc
			{
				fromkey=true;
				txtObj.value = prevTxt;
				acmenu.onClose();
				fromkey=false;
				return;
			}
//			else if (kc==13) //enter
//			{
//				if (selectedIdx==-1) return;
//				fromkey=true;
//				prevTxt = txtObj.value = results[selectedIdx];
//				if (callback!=null) callback(originate_obj, prevTxt, xGetElementById('intelli_id' + selectedIdx).innerHTML, param);
//				acmenu.onClose();
//				fromkey=false;
//				return;
//			}
			else if (kc!=39 && kc!=37)
			{
				fromkey=false;
			}
		}
		onfocus_call = on_focus;
		txtObj.onfocus = function()
		{
			prevTxt = txtObj.value;
			if (onfocus_call!=null) eval(onfocus_call); 
		}
		onblur_call = on_blur;
		txtObj.onblur = function()
		{
			setTimeout(delayedClose, 30);
			if (onblur_call!=null) eval(onblur_call); 
		}
	}
	
	function okuh(e)
	{
		if (!fromkey)
		{
			var key;
			if (e)
				key=e.keyCode;
			else
				key=window.event.keyCode;
			if (key==13) //enter
			{
				if (selectedIdx==-1) return;
				fromkey=true;
				prevTxt = txtObj.value = results[selectedIdx];
				if (callback!=null) callback(originate_obj, prevTxt, xGetElementById('intelli_id' + selectedIdx).innerHTML, param);
				acmenu.onClose();
				fromkey=false;
				return;
			}
			if (txtObj.value=='')
			{
				prevTxt = txtObj.value;
				acmenu.onClose();
			}
			else if (prevTxt!=txtObj.value)
			{
				delayedCall();
			}
		}
	}
	
	function doClick(idx)
	{
		doSelect(idx);
		if (callback!=null) callback(originate_obj, results[idx], xGetElementById('intelli_id' + idx).innerHTML, param);
	}
	
	function doSelect(idx, iskb, ismouse)
	{
		if (idx>=0)
		{
			xGetElementById('intelli' + idx).style.backgroundColor = "#FFFF99";
			fromkey = iskb;
			if (!ismouse) txtObj.value = results[idx];
		}
		else
		{
			txtObj.value = prevTxt;
		}
		if (selectedIdx!=idx)
		{
			if (selectedIdx>=0)
			{
				xGetElementById('intelli' + selectedIdx).style.backgroundColor = "white";
			}
			selectedIdx = idx;
		}
	}
	
	function delayedClose()
	{
		acmenu.onClose();
	}
		
	function delayedCall()
	{
		if (timer) clearTimeout(timer); timer = null;
		timer = setTimeout(callGoogle, 100);
	}
	
	function callGoogle()
	{
		prevTxt = txtObj.value;
		selectedIdx = -1;
		if (prevTxt!='')
		{
			if (cache.get(prevTxt)==null)
			{
				makeRequest('/complete/' + servlet, timeoutHandler, "qu=" + encodeURI(prevTxt) + (param==null ? "" : "&" + param));
			}
			else
			{
				eval(cache.get(prevTxt));
			}
		}
	}

	function sendRPCDone(fr,is,cs,ds,pr)
	{
		prevTxt = is;
		if (prevTxt!=txtObj.value) delayedCall();
		itemCount = cs.length;
		results = cs;
		if(cs.length>0) 
		{
			var txts = new Array();
			for (var a = 0; a<cs.length; a++)
			{
				txts.push("<div id='intelli" + a + "' style='padding:3px;' onmousedown='" + objName + ".DoClick(" + a + ");' onmouseover='" + objName + ".DoSelect(" + a + ",false,true);'><table boder='0' style='width:248px;' cellspacing='0' cellpadding='0' class='terms'><tr><td>");
				if (cs[a].toLowerCase().indexOf(is.toLowerCase())==0)
				{
					var subs = cs[a].substr(0, is.length);
					txts.push("<span><font color='red'><b>" + subs + "</b></font></span>");
					txts.push(cs[a].substr(is.length));
				}
				else
				{
					txts.push(cs[a]);
				}
				if (pr[0]!="")
				{
					txts.push("<span id='intelli_id" + a + "' style='display:none'>" + pr[a] + "</span>");
				}
				if (ds[0]!="")
				{
					txts.push("</td><td align='right'>");
					if (ds[a].toLowerCase().indexOf(is.toLowerCase())==0)
					{
						var subs = ds[a].substr(0, is.length);
						txts.push("<span><font color='red'><b>" + subs + "</b></font></span>");
						txts.push(ds[a].substr(is.length));
					}
					else
					{
						txts.push(ds[a]);
					}
				}
				txts.push("</td></table>")
				txts.push("</div>");
			}
			xGetElementById("acDiv").innerHTML = "<table id='ac_tb001' border='0' cellpadding='0' cellspacing='0'><tr><td><div style='border:1px solid #57B6DD; padding:0px; width:280px;'>" + txts.join("") + "</div></td></tr></table>";
			acmenu.onOpen(xWidth(xGetElementById("ac_tb001")), xHeight(xGetElementById("ac_tb001")), txtObj, 3, parent_obj);
		}
		else 
		{
//			xGetElementById("acDiv").innerHTML = "<table id='ac_tb001' border='0' cellpadding='0' cellspacing='0'><tr><td><div style='border:1px solid #57B6DD; padding:0px; width:280px;'>No result.</div></td></tr></table>";
//			acmenu.onOpen(xWidth(xGetElementById("ac_tb001")), xHeight(xGetElementById("ac_tb001")), txtObj, 3);
//			return;
			acmenu.onClose();
		}
	}
	
	function timeoutHandler(txt)
	{
		try
		{
			if (ajax_abort || http_request.readyState == 4)
			{
				if(!ajax_abort && http_request.status == 200)
				{
				 	if (http_request.responseText != null)
					{
						eval(http_request.responseText);
						cache.put(prevTxt, http_request.responseText);
						return;
				 	}
				}
//				alert("##CANNOT_EXECUTE##");
			}
		}
		finally
		{
			http_request=null;
		}
	}
}