var CustomMenuClass = new Class({
	initialize: function(options) {
		options = $merge({
			'disabled': false,
			'hiddenValue':'0',
			'value':'',
			'title':'',
			'hint':'',			
			'onItemSelected':Class.empty,
			'onItemReseted':Class.empty,
			'onCreate':Class.empty,
			'getList':Class.empty
			}, options);
		
		this.hiddenId = options.hiddenId;
		this.initHiddenValue =this.hiddenValue = options.hiddenValue;
		this.initValue = this.value=unescapeHTML(options.value);
		this.title=options.title;
		this.hint=options.hint;		
		this.getList=options.getList;
		this.disabled=options.disabled;
		this.onItemSelected=options.onItemSelected;
		this.onItemReseted=options.onItemReseted;
		this.onCreate=options.onCreate;
		this.sDivPref="_menu";
		if(!$defined(options.inputPref))
			this.sInputPref=this.hiddenId+'Label';
		else	
			this.sInputPref=options.inputPref;
		this.sDivOptionsPref="_options";
		this.inputStyle = "bigbox tooltip";
		this.inputStyleGrey = "bigBoxGrey";
		this.inputStyleBlack = "bigbox";		
		this.innerStyle = "inner";
		
		this.CLtimerID = 0;
		this.CLdelay = 700;
		this.CLsending = 0;
		
		window.addEvent('load', this.init.bind(this));
	},
	
	init: function(){
		$$("body")[0].addEvent("click",this.hide.bind(this));
		this.createElements();
		this.onCreate(this);
	},
	
	getValue: function(){
		return this.getInput().value;
	},
	
	getListTimer: function(){
		if(!this.CLsending){
			if(this.CLtimerID) {
				clearTimeout(this.CLtimerID);
				this.CLtimerID  = 0;
			}
			this.CLtimerID = setTimeout(this.getListTimerRun.bind(this), this.CLdelay);
		}
	},
	
	getListTimerRun: function(){
		this.CLsending=1;
		this.getList();
	},
	
	createElements: function(){
		if(this.getDiv()===false||this.getDiv()==null){
			alert("Sorry but can't find div with id:" + this.hiddenId+this.sDivOptionsPref);
			return;
		}
		var input=new Element('input', {
		    'type': 'text',
		    'value': this.value,
		    'class': this.inputStyle,
  		    'title': this.title,
		    'id': this.sInputPref,	    
		    'name': this.sInputPref,
		    'autocomplete':'off',
		    'events': {
				'click': this.startWork.bind(this),
				'keyup': this.getListTimer.bind(this)
				,'blur': this.showHint.bind(this)
		    }
	    });
	    input.injectInside(this.getDiv());	

		var hidden=new Element('input', {
		    'type': 'hidden',
		    'value': this.hiddenValue,
		    'id': this.hiddenId,	    
		    'name': this.hiddenId
	    });
	    hidden.injectInside(this.getDiv());	

		var divOptions=new Element('div', {
	    'class': this.innerStyle,
	    'id': this.hiddenId+this.sDivOptionsPref
	    });
	    divOptions.injectInside(this.getDiv());	
	    this.hide();
	    if(this.disabled){
	    	this.getInput().disabled=true;
	    }
	    addToolTip(input, 'custom');
	    this.hideHint();
	    this.showHint();
	    
	},
	startWork: function(){
		this.hideHint();
		this.getList();
		
	},
	showHint: function(){
		if (this.hint=='') return;
		var input =  this.getInput();
		if (input.value == ''){
			input.value = this.hint;
			input.removeClass(this.inputStyleBlack);
			input.addClass(this.inputStyleGrey);
		}
	},
	
	hideHint: function(){
		if (this.hint=='') return;
		var input =  this.getInput();
		if (input.value == this.hint){
			input.value = '';
			input.removeClass(this.inputStyleGrey);
			input.addClass(this.inputStyleBlack);
		}
	},
	
	disabled: function(){
	    	this.getInput().disabled=true;
	},
	
	getDivOptions: function(){
		return $(this.hiddenId+this.sDivOptionsPref);
	},
	
	getDiv: function(){
		return $(this.hiddenId+this.sDivPref);
	},
	
	
	getInput: function(){
		return $(this.sInputPref);
	},

	getHidden: function(){
		return $(this.hiddenId);
	},
	
	updateList: function(list){
		this.CLsending=0;
		var div = this.getDivOptions();
		div.empty();
		if (list.length > 0){
	        for(var i=0; i<list.length; i++){
    	        this.addMenuOption(div, list[i].value, list[i].label, this.hiddenId);
    	    }
      		this.show();
      		this.checkForCompleteValue();
	    } else {
	    	if(this.initValue == this.getInput().value){
	    		this.select(this.initHiddenValue,this.initValue);
	    	}else{
		        this.resetHidden();
	        }
	        this.hide();
	    }
	},
	
	checkForCompleteValue: function(id){
		var res;
		var found = false;
		var value=this.getInput().value.toLowerCase();
		this.getDivOptions().getChildren().each(function(item){
			if (unescapeHTML(item.innerHTML).toLowerCase()  == value  ){
				res = item.itemGetRes();
				found = true;
			}
		});	
		if (!found){
			this.resetHidden();
		}else{
			this.select(res.id,res.value);
		}
		
	},
	
	resetHidden: function(){
		$(this.hiddenId).value=0;
		this.onItemReseted(this);
	},

	reset: function(){
		this.getInput().value='';
		$(this.hiddenId).value=0;
		this.onItemReseted(this);
	    this.showHint();		
	},
	
	addMenuOption: function(div, id, name, fieldName){
		var item = new Element('div', {
			'class' : 'item',
			'id' : fieldName+'_'+id
		});
		item.addEvent('mouseover',this.onRowOver);
		item.addEvent('mouseout',this.onRowOut);
		item.addEvent('click',this.onAutocompleteItemClick);
		
		item.setHTML(name);
		item.customMenuClass=this;
		item.injectInside(div);
		item.itemGetRes=this.itemGetRes;
	},
	
	onRowOver: function() {
	   this.addClass("mouse_over");
	},
	
	onRowOut: function() {
	    this.removeClass("mouse_over");
	},


	onAutocompleteItemClick: function(){
		var res = this.itemGetRes();
	    this.customMenuClass.callBackClick(res.id,res.value);
	},	

	itemGetRes: function(){
		var id=this.id;
		var innerHTML=this.innerHTML;
	    var pattern = /([^_]+)_([^_]+)/i;
	    var result = pattern.exec(id);
	    return {"id":result[2],"value":innerHTML};
	},	


	callBackClick: function(value,innerHTML){
		this.select(value,innerHTML);
	    this.hide();
	},
	
	select: function(value,innerHTML){
		this.getHidden().value=value;
	    this.getInput().value=unescapeHTML(innerHTML);
		this.getInput().removeClass(this.inputStyleGrey);
		this.getInput().addClass(this.inputStyleBlack);
	    this.onItemSelected(this);
	},
	
	
	show: function(){
		this.getDivOptions().setStyle('display', 'block');
	},
	hide: function(){
		this.getDivOptions().setStyle('display', 'none');
	}
	
});

function unescapeHTML(str){
	str = str.replaceAll('&quot;','&#34;');
	str = str.replaceAll('&amp;','&#38;');
	str = str.replaceAll('&lt;','&#60;');
	str = str.replaceAll('&gt;','&#62;');
	str = str.replaceAll('&nbsp;','&#160;');
	str = str.replaceAll('&pound;','&#163;');
	str = str.replaceAll('&OElig;','&#338;');
	str = str.replaceAll('&oelig;','&#339;');
	str = str.replaceAll('&Scaron;','&#352;');
	str = str.replaceAll('&scaron;','&#353;');
	str = str.replaceAll('&Yuml;','&#376;');
	str = str.replaceAll('&circ;','&#710;');
	str = str.replaceAll('&tilde;','&#732;');
	str = str.replaceAll('&ensp;','&#8194;');
	str = str.replaceAll('&emsp;','&#8195;');
	str = str.replaceAll('&thinsp;','&#8201;');
	str = str.replaceAll('&zwnj;','&#8204;');
	str = str.replaceAll('&zwj;','&#8205;');
	str = str.replaceAll('&lrm;','&#8206;');
	str = str.replaceAll('&rlm;','&#8207;');
	str = str.replaceAll('&ndash;','&#8211;');
	str = str.replaceAll('&mdash;','&#8212;');
	str = str.replaceAll('&lsquo;','&#8216;');
	str = str.replaceAll('&rsquo;','&#8217;');
	str = str.replaceAll('&sbquo;','&#8218;');
	str = str.replaceAll('&ldquo;','&#8220;');
	str = str.replaceAll('&rdquo;','&#8221;');
	str = str.replaceAll('&bdquo;','&#8222;');
	str = str.replaceAll('&dagger;','&#8224;');
	str = str.replaceAll('&Dagger;','&#8225;');
	str = str.replaceAll('&permil;','&#8240;');
	str = str.replaceAll('&lsaquo;','&#8249;');
	str = str.replaceAll('&rsaquo;','&#8250;');
	str = str.replaceAll('&euro;','&#8364;');
	var byCode;
	do{
		byCode =  unescapeHTMLByCode(str);
		str=byCode.str;
	}while(byCode.have)
	return str;
}

function unescapeHTMLByCode(str){
	var b=str.indexOf('&#');
	var have=false;
	if(b>-1){
		var e=str.indexOf(';',b);
		if(e>0){
			str=str.replace('&#'+str.substring(b+2,e)+';',String.fromCharCode(str.substring(b+2,e).toInt()));
			have = true;
		}
	}
	return {'have':have,'str':str};
}

String.prototype.replaceAll = function(search, replace){
	  return this.split(search).join(replace);
}