/**
 * @name:		im_autocomplete.js
 * @Author:		Albert Harounian
 * @desc: 		Autocomplition for textarea and text inputs
 * @version: 	1.1.5
 * @uses: 		im_gui 2.5.5
 * @uses: 		im_ajax
 * @since: 		July 21 2008
 * @revision: 	October 15, 2008
 * @revision: 	October 28, 2008
 * @revision: 	October 29, 2008
 * @revision: 	November 03, 2008
 * @revision: 	November 05, 2008
 * @revision: 	December 05, 2008
 * @revision: 	January 08, 2009
 *
 */

var im_autocomplete={
	curValue: '',
	isInProccess: false,
	curResultArr: '',
	curIndex: 0,
	curPosition: {start:0,end:0},
	curElementID: 0,
	timerID_1: 0,
	timerID_2: 0,
	timerID_3: 0,
	onblurFlag: false,
	
	_delay: 350,
	_strLoading: 'Loading . . .',
	_strNotFound: 'Sorry, No results where found',
	
	_keyCodes:{
		TAB:9,
		ENTER:13,
		ESC:27,
		PAGE_UP:33,
		PAGE_DOWN:34,
		ARROW_UP:38,
		ARROW_DOWN:40
	},
	
	_defaultValues:{
		rows_per_screen:9,
		line_height: 12,
		offset_x: 0,
		offset_y: 0,
		paging: false,
		max_height: 300,
		rows_limit: 40,
		close_onblur: true,
		esc_choose: false,
		show_not_found: true,
		show_loading: true,
		mark_search_word: true,
		comma_seperated: false,
		max_commas: 5,
		submit_onchoose: false,
		extra_params: '',
		file: 'ac.index.ajax.php',
		param: 'ac_request'
	},
	
	_settings:{
		containerClassName: 'ac-results',
		rowClassName: 'ac-row',
		markerClassName: 'bold'
	},
	
	set: function(){
		if(arguments.length>0){
			var el=resultDiv=hiddenInp='';
			for(var j=i=0; i<arguments.length; i++){
				if(typeof(arguments[i].id)=='string'){el=im_gui.obj(arguments[i].id);};
				if(typeof(el)=='object'){
					for(j in this._defaultValues){el.setAttribute('ac_'+j,(arguments[i][j]!=null?arguments[i][j]:this._defaultValues[j]));};
					el.setAttribute('autocomplete', 'off');el.setAttribute('ac_comma_counter',0);
					el.onkeyup=function(e){im_autocomplete.keyup_hanlder(e, this);};
					el.onkeydown=function(e){im_autocomplete.keydown_hanlder(e, this);};
					el.setAttribute('org_onblur', (el.onblur||'').toString());
					el.onblur=function(e){var el=this;window.setTimeout(function(){if(el.getAttribute('org_onblur')!=''){eval('('+el.getAttribute('org_onblur')+')(el, this)');}im_autocomplete.onblur(el)}, 150);};
					el.setAttribute('org_onfocus', (el.onfocus||'').toString());
					el.onfocus=function(e){if(this.getAttribute('org_onfocus')!=''){eval('('+this.getAttribute('org_onfocus')+')(e, this)');}im_autocomplete.onfocus(this);};
					resultDiv=document.createElement('div');hiddenInp=document.createElement('input');
					resultDiv.onclick=function(){im_autocomplete.onblurFlag=true;};
					resultDiv.onscroll=function(){im_autocomplete.onblurFlag=true;};
					if(el.getAttribute('required')!=null&&el.getAttribute('required')!=''){hiddenInp.setAttribute('required', el.getAttribute('required').toString());el.setAttribute('required', '');}
					with(hiddenInp){type='hidden';name=el.name;id=el.id+'_id';value=el.getAttribute('ac_value');}
					with(resultDiv){id='ac_'+el.id;className=this._settings.containerClassName;
					with(style){
						left=parseInt(im_gui.misc.findPosX(el)+(arguments[i].offset_x||this._defaultValues.offset_x))+'px';maxHeight=parseInt(arguments[i].max_height||this._defaultValues.max_height)+'px';
						top=parseInt(im_gui.misc.findPosY(el)+(arguments[i].offset_y||this._defaultValues.offset_y)+el.offsetHeight+1)+'px';overflow='auto';
						width=(arguments[i].width>0?arguments[i].width:el.offsetWidth)+'px';display='none';zIndex='100001';position='absolute';
					};};document.body.appendChild(resultDiv);el.parentNode.appendChild(hiddenInp);el.name+='_text';el.style.visibility='visible';
				};
			};
		};
	},
	
	onkeyup: function(e, el){
		if(el==''){el = im_gui.obj(this.curElementID);};
		var key=(document.all?(this._tmpKey==''?event.keyCode:this._tmpKey):e.which);
		if(el.value==''){
			im_gui.obj(this.curElementID+'_id').value='';this.curValue='';im_gui.misc.innerData('ac_'+this.curElementID, '');el.setAttribute('ac_comma_counter',0);this.hide();
		}else if(el.value!=this.curValue){
			this.curIndex=0;this.curValue=el.value;this.curElementID=el.id;
			this.timerID_1=window.setTimeout(function(){im_autocomplete.request();},this._delay);
		}else if(el.value!=''&&key==40&&im_gui.obj('ac_'+this.curElementID).style.display=='none'){
			this.build_list();this.curIndex=0;this.scroll();
		}else{switch(key){
			case this._keyCodes.TAB:case this._keyCodes.ENTER:this.choose();break;
			case this._keyCodes.ESC:if(el.getAttribute('ac_esc_choose').toString()!='false'){this.hide();};break;
			case this._keyCodes.PAGE_UP:this.previous(true);break;case this._keyCodes.PAGE_DOWN:this.next(true);break;
			case this._keyCodes.ARROW_UP:this.previous(false);break;case this._keyCodes.ARROW_DOWN:this.next(false);break;
		};};
	},
	
	keyup_hanlder: function(e, el){
		window.clearInterval(this.timerID_2);this.timerID_2=0;window.clearInterval(this.timerID_3);this.onkeyup(e, el);
	},
	
	keydown_hanlder: function(e, el){
		window.clearTimeout(this.timerID_1);this.curElementID=el.id;if(im_gui.browser.ie){this._tmpKey=event.keyCode;};if(!this.isInProccess){var key=(document.all?event.keyCode:e.which);switch(key){
		case this._keyCodes.ARROW_UP:case this._keyCodes.ARROW_DOWN:
		if(!this.timerID_2){this.timerID_2=window.setTimeout(function(){im_autocomplete.timerID_3=window.setInterval(function(){
		im_autocomplete.onkeyup(e, el);}, 80);},150);};break;};}else{window.clearInterval(this.timerID_3);};
	},
	
	hide: function(){
		im_gui.display.hide('ac_'+this.curElementID);
	},
	
	onblur: function(el){
		if(el.value==''){im_gui.obj(this.curElementID+'_id').value='';this.curValue='';im_gui.misc.innerData('ac_'+this.curElementID, '');el.setAttribute('ac_comma_counter',0);this.hide();return false;}
		if(!this.onblurFlag&&el.getAttribute('ac_close_onblur').toString()=='true'){this.choose();this.hide();};
	},
	
	onfocus: function(el){
		if(el.id!=this.curElementID){this.hide();this.curElementID=el.id;this.curValue=el.value;this.curResultArr='';curIndex=0;}
	},
	
	next: function(isJump){
		im_gui.css.removeClass('ac_row_'+this.curIndex, 'current');
		if(isJump){this.curIndex+=im_gui.obj(this.curElementID).getAttribute('ac_rows_per_screen')-1;
		if(this.curIndex>=this.curResultArr.length){this.curIndex=this.curResultArr.length-1;}}else{this.curIndex++;};
		if(this.curIndex>this.curResultArr.length&&!isJump){this.curIndex=1;};
		this.highligh_current_index();this.scroll(this._keyCodes.ARROW_DOWN);
	},
	
	previous: function(isJump){
		im_gui.css.removeClass('ac_row_'+this.curIndex, 'current');
		if(isJump){this.curIndex-=im_gui.obj(this.curElementID).getAttribute('ac_rows_per_screen');if(this.curIndex<=0){this.curIndex=1;}}else{this.curIndex--;};
		if(this.curIndex<0&&!isJump){this.curIndex=this.curResultArr.length;};
		this.highligh_current_index();this.scroll(this._keyCodes.ARROW_UP);
	},
	
	highligh_current_index: function(){
		im_gui.css.addClass('ac_row_'+this.curIndex, 'current');
	},
	
	scroll: function(key){
		if(this.curIndex>im_gui.obj(this.curElementID).getAttribute('ac_rows_per_screen')-2){var divObj=im_gui.obj('ac_'+this.curElementID);
		divObj.scrollTop=((this.curIndex*im_gui.obj(this.curElementID).getAttribute('ac_line_height'))-((im_gui.obj(this.curElementID).getAttribute('ac_rows_per_screen')-2)*im_gui.obj(this.curElementID).getAttribute('ac_line_height')));
		}else{im_gui.obj('ac_'+this.curElementID).scrollTop=0;};this.highligh_current_index();
		if((im_gui.obj(this.curElementID).getAttribute('ac_paging').toString()=='true')&&key==this._keyCodes.ARROW_DOWN){
		if(this.curIndex==this.curResultArr.length&&this.curResultArr.length>2){this.request();}};
		if((im_gui.obj(this.curElementID).getAttribute('ac_paging').toString()=='true')&&key==this._keyCodes.ARROW_UP){
		if(this.curIndex==1&&this.curResultArr.length>2){this.curIndex=-2;this.request();}};
	},
	
	choose: function(index){
		if(im_gui.obj('ac_'+this.curElementID).style.display=='none'){return false;}
		var str='',id=0,el=im_gui.obj(this.curElementID);
		if(typeof(index)!='undefined'){str=this.curResultArr[index].text;id=this.curResultArr[index].id;
		}else if(this.curIndex>0&&this.curIndex<=this.curResultArr.length){
		str=this.curResultArr[this.curIndex-1].text;id=this.curResultArr[this.curIndex-1].id;
		}else{return false;};
		el.value=(el.getAttribute('ac_comma_seperated').toString()=='true'?el.value.substr(0, this.curPosition.start-1)+(el.value.lastIndexOf(',')>-1?',':'')+im_gui.string.stripTags(str)+el.value.substr(this.curPosition.end)+',':im_gui.string.stripTags(str));
		im_gui.obj(this.curElementID+'_id').value=(el.getAttribute('ac_comma_seperated').toString()=='true'?im_gui.obj(this.curElementID+'_id').value+(el.value.indexOf(',')<el.value.length-1?',':'')+id:id);this.hide();if(el.getAttribute('ac_submit_onchoose').toString()=='true'&&el.form){el.form.submit();}else{return false;};
	},
	
	request: function(id){
		if(typeof(id)=='string'){this.curElementID=id;}this.isInProccess=true;
		var el=im_gui.obj(this.curElementID),strValue=extraParams='';
		if(el.getAttribute('ac_comma_seperated').toString()=='true'){
			if(parseInt(el.getAttribute('ac_max_commas'))==parseInt(el.getAttribute('ac_comma_counter'))){return false;}
			el.setAttribute('ac_comma_counter',parseInt(el.getAttribute('ac_comma_counter'))+1);
			this.curPosition.start=this.curPosition.end=0;
			this.curPosition.end=im_gui.input.getCursorPosition(el);
			strValue=el.value.substr(0,this.curPosition.end);
			strValue=strValue.substr(strValue.lastIndexOf(',')+1);
			this.curPosition.start=this.curPosition.end-strValue.length;
		}else{strValue=el.value;this.curPosition.start=0;this.curPosition.end=strValue.length;}if(strValue!=''){
		im_gui.misc.innerData('ac_'+this.curElementID,(el.getAttribute('ac_show_loading').toString()=='true'?this._strLoading:''));
		if(el.getAttribute('ac_extra_params')!=''){eval("extraParams='&'+"+el.getAttribute('ac_extra_params').toString()+'()');}
		im_ajax.send(el.getAttribute('ac_file'), im_autocomplete.response_handler, 
			el.getAttribute('ac_param')+'='+escape(strValue)+extraParams
			+'&pagenum='+Math.floor((this.curIndex+1)/im_gui.obj(this.curElementID).getAttribute('ac_rows_per_screen'))
			+'&rows_limit='+parseInt(el.getAttribute('ac_rows_limit'))
			+'&'+el.getAttribute('ac_param')+'_id='+escape(im_gui.obj(el.id+'_id').value)
		);}
	},
	
	response_handler: function(data){
		var divObj=im_gui.obj('ac_'+im_autocomplete.curElementID);im_autocomplete.isInProccess=false;
		if(data=='  '||data==''){if(im_gui.obj(im_autocomplete.curElementID).getAttribute('ac_show_not_found').toString()=='true'){
		im_gui.misc.innerData(divObj,im_autocomplete._strNotFound);}else{im_gui.misc.innerData(divObj,'');im_autocomplete.hide();}return false;};
		eval('im_autocomplete.curResultArr='+data+';');im_autocomplete.build_list();
	},
	
	build_list: function(){
		var divObj=im_gui.obj('ac_'+this.curElementID);var curDiv='';im_gui.misc.innerData(divObj, '');var el=im_gui.obj(this.curElementID);
		if(this.curResultArr.length>0){
			im_gui.display.show(divObj);if(im_gui.browser.ie){divObj.style.height='auto';};
			for(var i=0; i<this.curResultArr.length; i++){
				curDiv=document.createElement('div');curDiv.onmouseover=function(){im_gui.css.removeClass('ac_row_'+(im_autocomplete.curIndex),'current');
				im_gui.css.addClass(this,'current');};curDiv.onmouseout=function(){im_gui.css.removeClass(this,'current');};
				curDiv.onclick=function(){im_autocomplete.choose(this.getAttribute('ac_index'));}
				with(curDiv){innerHTML=(el.getAttribute('ac_mark_search_word').toString()=='true'?this.curResultArr[i].text.replace(new RegExp('('+this.curValue.substring(this.curPosition.start,this.curPosition.end)+')', 'i'), '<span class="'+this._settings.markerClassName+'">$1</span>'):this.curResultArr[i].text);className=this._settings.rowClassName;id='ac_row_'+(i+1);setAttribute('ac_index', i);}
				divObj.appendChild(curDiv);
			}
			if(im_gui.browser.ie){if(divObj.offsetHeight>=parseInt(im_gui.obj(this.curElementID).getAttribute('ac_max_height'))){
			divObj.style.height=im_gui.obj(this.curElementID).getAttribute('ac_max_height')+'px';}else{divObj.style.height='auto';}};
			window.setTimeout(function(){window.clearInterval(im_autocomplete.timerID_2);im_autocomplete.timerID_2=0;},10);this.scroll();
		}else{if(im_gui.obj(im_autocomplete.curElementID).getAttribute('ac_show_not_found').toString()!='true'){this.hide();};};
	}
};