	var send=false;
	var dyn_list=new Array;
	var fun_after_set='';
	var selectedDyn=0;

	function getCaretPos(obj){
		obj.focus();
	 	if(obj.selectionStart) {
	  		return obj.selectionStart;
	  	} else if (document.selection) {
			var sel = document.selection.createRange();
			var clone = sel.duplicate();
			sel.collapse(true);
			clone.moveToElementText(obj);
			clone.setEndPoint('EndToEnd', sel);
			return clone.text.length;
		}
		return 0;
	}

	function get_cursor_place(obj){
		var arr=obj.value.split(',');
		var cursor_pos=getCaretPos(obj);
		var cnt=0;
		for(i in arr){
			cnt+=arr[i].length+1;
			if(cnt>=cursor_pos){
				var info={'pos':i,'txt':trim(arr[i])};
				return info;
			}
		}
	}

	function dynamic_list(evt, inp, list, fun_get, fun_set){
		obj=document.getElementById('dynamic_list');
		var e=window.event || evt;
		switch(e.keyCode){
		case 13:
			setDyn(inp);
			obj.style.display='none';
			inp.onkeypress='return true;';
			return false;
			break;
		case 40:
			if(selectedDyn<dynTotal){
				selectedDyn++;
				setDyn(inp);
			}
			break;
		case 38:
			if(selectedDyn>1){
				selectedDyn--;
				setDyn(inp);
			}
			break;
		default:
			dynTotal=0;
			selectedDyn=0;
			var src_txt;
			if(typeof fun_get != 'undefined' && fun_get!=''){
				eval('src_txt='+fun_get+'(inp)');
			}else{
				src_txt=inp.value;
			}
			if(typeof fun_set != 'undefined' && fun_set!=''){
				fun_after_set=fun_set;
			}else{
				fun_after_set='inp.value=htmlentities(dyn_list[selectedDyn-1]);';
			}
			if(inp.value.length>0){
				pos=absPosition(inp);
				obj.style.left=pos.x+'px';
				obj.style.top=pos.y+25+'px';
				if(is_array(list)){
					$('#dynamic_list').html(load_list(list, src_txt));
					$('#var_list tr td a').click(function(){setDyn(inp);return false;});
					if(dynTotal>0){
						$('#dynamic_list').show();
					}else{
						$('#dynamic_list').hide();
					}
				}else{
					$('#dynamic_list').load('/ajax.php?show='+list+'&str='+escape_utf8(src_txt)+'&r='+Math.random(), function(html){eval(html);$('#dynamic_list').html(load_list(dyn_list, src_txt)); $('#var_list tr td a').click(function(){selectedDyn=this.id.substr(3);setDyn(inp);$('#dynamic_list').hide();return false;});
					$('#dynamic_list').show();});
				}
			}else{
				obj.style.display='none';
			}
		}
		return false;
	}

	function load_list(arr, str){
		if(str.length>0){
			var ret='';
			var cnt=0;
			for(i in arr){
				cnt++;
				ret+='<tr><td id="cell'+cnt+'"><a href="#"  id="dyn'+cnt+'">'+arr[i].replace(str, '<b>'+str+'</b>')+'</a></td></tr>';
			}
			dynTotal=cnt;
			if(cnt>0){
				ret='<table id="var_list">'+ret+'</table>';
			}
			return ret;
		}else{
			return '';
		}
	}

	function setDyn(inp){
		for(i=1;i<=dynTotal;i++){
			if(i==selectedDyn){
				$('#dyn'+i).css('background-color', '#000').css('color', '#fff')
			}else{
				$('#dyn'+i).css('background-color', '#fff').css('color', '#000').val();
			}
		}
		if(typeof fun_after_set != 'undefined'){
			eval(fun_after_set+'(inp);');
		}
	}

	/* services functions */

	function absPosition(obj) {
	      var x = y = 0;
	      while(obj) {
	            x += obj.offsetLeft;
	            y += obj.offsetTop;
	            obj = obj.offsetParent;
	      }
	      return {x:x, y:y};
	}

	function escape_utf8(data) {
        if (data == '' || data == null){
               return '';
        }
       data = data.toString( );
       var buffer = '';
       for(var i=0; i<data.length; i++){
               var c = data.charCodeAt(i);
               var bs = new Array( );
              if (c > 0x10000){
                       // 4 bytes
                       bs[0] = 0xF0 | ((c & 0x1C0000) >>> 18);
                       bs[1] = 0x80 | ((c & 0x3F000) >>> 12);
                       bs[2] = 0x80 | ((c & 0xFC0) >>> 6);
                   bs[3] = 0x80 | (c & 0x3F);
               }else if (c > 0x800){
                        // 3 bytes
                        bs[0] = 0xE0 | ((c & 0xF000) >>> 12);
                        bs[1] = 0x80 | ((c & 0xFC0) >>> 6);
                       bs[2] = 0x80 | (c & 0x3F);
             }else if (c > 0x80){
                      // 2 bytes
                       bs[0] = 0xC0 | ((c & 0x7C0) >>> 6);
                      bs[1] = 0x80 | (c & 0x3F);
               }else{
                       // 1 byte
                    bs[0] = c;
              }
             for(var j=0; j<bs.length; j++){
                      var b = bs[j];
                       var hex = nibble_to_hex((b & 0xF0) >>> 4)
                      + nibble_to_hex(b &0x0F);buffer += '%'+hex;
              }
    	}
    	return buffer;
	}

	function nibble_to_hex(nibble){
        var chars = '0123456789ABCDEF';
        return chars.charAt(nibble);
	}


