/* uiSuggestor {+jml+} version 1, HK510.com */
function uiSuggestor(config){
	var ui=getObj(config.id),cUi=getObj(config.id.split("_name")[0]),uiObj=null,oId="jmlUISuggestor_"+ui.id,isOn=false,ifrm=null,cbk=config.onSelect,cbg=config.onChange,tmpDta,intl;
	if(typeof(jmlUISuggestor_virtual)=='undefined') jmlUISuggestor_virtual={};
	jmlUISuggestor_virtual[ui.id]={};
	var c1=jml.server,c2=jml.events,c3=jml.xml.node,c4=jml.obj,c5=jml.browser;
	if(!isset(ui)) return;
	if(!isset(cUi)) return;
	if(!isset(config.data)) return;
	function getData(s){
		if(!isset(config.data.action) || !isset(config.data.gateway)) return;
		var cx=new c1.connection(),a=[];
		cx.url=config.data.gateway+config.data.action;
		cx.data={startsWith:s,limit:config.data.limit};
		if(isset(config.data.make_name)) cx.data.make_name=c4.get(config.data.make_name,'value');
		cx.onLoad=function(data){
			if(data.length==2&&data=='[]') return;
			a=decode(data);
			generate(a);
		};
		cx.onError=function(id,msg){alert(id+", msg = "+ msg);};
		if(isset(cbg)) cbg();
		cx.connect();
	}
	function swapClass(e,x1,b){c4.set(x1,'className',b?'over':'normal');}
	function checkValidation(b){
		var g=window.uiFormValidatorDrlk,b=b||false;
		if(isObj(g)&&isObj(g=g['ui_'+ui.name]))g.clear(b);
	}
	function setClick(e,x1,s1,s2){
		ui.value=s1;
		if(isset(cUi)) cUi.value=s2;
		if(isset(cbk)) cbk(ui,s1);
		clear();
		checkValidation(false);
	}
	function clear(){
		c2.remove(document,'mousemove',evaluateSector);
		c2.remove(ui,'keyup',getKey);
		c3.remove(uiObj);
		c3.remove(ifrm);
	}
	function setClearDelay(){if(!isOn) setTimeout(clear,100);}
	function evaluateSector(e){
		var e=c2.initialize(e);
		var o=c2.getXY(e);
		var o1=c2.hitTest(e,[ui,uiObj]);
		isOn=o1.on;
		if(isOn) ui.focus();
	}
	function onItem(o,x){
		var s=o.label,i=c3.create("LI",x);
		var s1=s.match(new RegExp(ui.value,"i"));
		c4.set(i,'innerHTML',s.replace(new RegExp(s1,"i"),'<span>'+s1+'</span>'));
		c2.add(i,'mouseover',delegate(this,swapClass,i,true));
		c2.add(i,'mouseout',delegate(this,swapClass,i,false));
		c2.add(i,'click',delegate(this,setClick,i,s,o.value));				
	}
	function generate(a){
		var x1=c3.byPosition(0,uiObj);
		c4.set(x1,'innerHTML','');
		var x2=c3.byPosition(0,x1);
		if(!isset(x2)) x2=c3.create("UL",x1);
		for(var i=0;i<a.length;i++) onItem(a[i],x2);
		setPosition();
		c4.set(uiObj,'visibility','visible');
	}
	function setPosition(){
		var o1=c5.getScroll(),o2=c5.getWindowSize(),n1=c4.get(ui,'offsetLeft'),n2=c4.get(ui,'offsetTop'),n3=c4.get(ui,'offsetWidth'),n4=c4.get(ui,'offsetHeight'),n5=c4.get(uiObj,'offsetHeight'),n6=isset(config.height)?config.height:200,n7=isset(config.width)?config.width:n3,n8=n5>n6?n6:n5,n9=isset(config.padding)?config.padding:12,n10=n2+n4+n8>o1.y+o2.h?n2-n8-n9:n2+n4;
		c4.set(uiObj,'width',n7+'px');
		var n11=c4.get(uiObj,'offsetWidth')-n7;
		c4.set(uiObj,'width',(n7-n11)+'px');
		c4.set(uiObj,'height',n8+'px');
		c4.set(uiObj,'left',n1+'px');
		c4.set(uiObj,'top',n10+'px');
		if(ifrm!=null){
			c4.set(ifrm,'width',n7+'px');
			c4.set(ifrm,'height',n8+'px');
			c4.set(ifrm,'left',n1+'px');
			c4.set(ifrm,'top',n10+'px');			
		}
	}
	function create(){
		checkValidation(true);
		if(!isset(getObj(oId))){
			uiObj=c3.create('DIV',document.body);
			c4.set(uiObj,'id',oId);
			c4.set(uiObj,'className',isset(config.className)?config.className:'suggestor01');
			var x2=c3.create('DIV',uiObj);
            if(lower(navigator.userAgent).match('msie 6')!=null){
				ifrm=c3.create('DIV',document.body);
				c4.set(ifrm,'innerHTML','<iframe></iframe>');
				c4.set(ifrm,'className','ie6UnderFloatBugForm');
			}
		}
		c2.add(document,'mousemove',evaluateSector);
		c2.add(ui,'keyup',getKey);
		c4.set(uiObj,'visibility','hidden');
		//getData(null);
	}
	function getKey(e){
		var e=c2.initialize(e),n=c2.getKey(e),o=c2.getElement(e),s=null;
		if(isset(o.value)) s=o.value;
		if(n==13){
			if(isFunc(cbk)) cbk(ui,ui.value);	
			clear();
			return false;
		}
		if((n==38||n==40)&&isset(getObj(oId))){
			// scroll by arrow, no yet implemented...
		}else{
			if((n==8||c2.getKey(e,true)!=-1)&&isset(s)){
				tmpDta=s;
				setDelay();
			}
		}
	}
	function setDelay(){
		 clearDelay();
		 intl=setInterval(exeDelay,200);
	}
	function clearDelay(){
		if(isset(intl)) clearInterval(intl);
	}
	function exeDelay(){
		clearDelay();
		getData(tmpDta);
	}
	ui.setAttribute("autocomplete","off");
	c2.add(ui,'focus',create);
	c2.add(ui,'blur',function(){
		if(isFunc(cbk)) cbk(ui,ui.value);	
		setClearDelay();
	});
	c2.add(ui,'keydown',getKey);
	return {
		$:function(){
			jml.events.text.add('resize',delegate(this,'setPosition'));
			jml.events.add('resize',delegate(this,'setPosition'));			
			return this;
		},
		remove:function(){clear();},
		setPosition:setPosition
	}.$();
};
