function search_suggest(settings){
	this.settings=settings;
	this.cache=[];
	this.lock=[];
	this.current=[];
	var self=this;
	this.selected=0;
	DOMReady(function(){self.init();});
}

search_suggest.prototype.init= function(){
	this.input=DOM(this.settings.input);
	this.ul=DOM(this.settings.ul);
	var self=this;
	this.input.listen('keyup', function(e){
		if (self.input.value.length<self.settings.minlength){
			self.ul.hide();
			return;
		}
		if (e.keyCode==keyCode.up){
			self.select((self.selected==-1)?-1:self.selected-1);
		}
		else if(e.keyCode==keyCode.down){
			self.select(self.selected+1);
		}
		else if(e.keyCode==keyCode.esc){
			self.selected=-1;
			self.ul.hide();
		}
		else {
			self.doSuggest(self.input.value);
		}
	});
	
	DOM(this.input.form).listen('submit', function(e){
		if (self.current.length&&self.selected!=-1){		
			DOM(self.settings.tag).value=self.current[self.selected].tagID;				
			//submit:
			self.input.form.submit();				
		}
		return true;
	});
}

search_suggest.prototype.doSuggest= function(search){
	search=search.toLowerCase();	
	if (this.cache[search.substr(0, this.settings.minlength)]){
		this.loadFromCache(search);
	}
	else {
		this.load(search);
	}
}

search_suggest.prototype.loadFromCache= function(search){
	var items=[];
	var length=search.length;
	if (this.current[this.selected]){
		this.current[this.selected].detachClass('selected');
	}
	for (var i=0; i<this.current.length; i++){
		this.current[i].hide();
	}
	this.current=[];
	var cache=this.cache[search.substr(0, this.settings.minlength)];
	var total=0;	
	for (key in cache){
		if (key.substr(0,length)==search){
			cache[key].show();
			total++;
			this.current[this.current.length]=cache[key];
		}
	}
	if (total>0){
		this.settings.show(this.input, this.ul);
		//this.select(0);
		this.selected=-1;
	}
	else {
		this.ul.hide();
	}
}

search_suggest.prototype.select= function(index){
	if (this.current[this.selected]) this.current[this.selected].detachClass('selected');
	this.selected=index%this.current.length;
	if (this.selected<0) this.selected=this.current.length+this.selected;	
	this.current[this.selected].attachClass('selected');
}

search_suggest.prototype.load= function(search){
	search= search.substr(0, this.settings.minlength);
	if (this.lock[search]) return;
	this.lock[search]=search;
	var self=this;
	var POST=[];
	POST[this.input.name]=search;
	op.query(this.settings.href, function(xml){self.loaded(xml);},POST);
}

search_suggest.prototype.loaded= function(xml){
	
	var search=xml.selectString('search');
	var results=xml.selectList('results');
	this.cache[search]=[];
	
	for (var i=0; i<results.length; i++){
		var systemName=results[i].title.toLowerCase();		
		this.cache[search][systemName]=this.ul.create({tagName:'li'});
		this.cache[search][systemName].tagID=results[i].id;
		//create link:
		this.cache[search][systemName].create({
			tagName:'a',
			href:this.settings.linkTpl.replace('[id]',results[i].id),
			innerHTML:results[i].title + '<span>'+results[i].total+'</span>'
		});
		//sup count:
		this.cache[search][systemName].create({
			tagName:'span', 			
			innerHTML:'',
			className:'d_none'
		});		
	}
	//reindex:
	this.loadFromCache(this.input.value);
}

search_suggest.bubble= function(input, ul){
	ul.style.left=input.offsetLeft;
	ul.style.top=input.offsetTop+input.offsetHeight;
	ul.style.display='block';
}
