var LiveSearch = Class.create({
	inputs: null,
	resultWrap: null,
	resultChoose: 0,
	tagName: "input",
	keys: {
		capslock:20,
		shift:16,
		right:Event.KEY_RIGHT,
		left:Event.KEY_LEFT,
		up:Event.KEY_UP,
		down:Event.KEY_DOWN,
		strg:17,
		alt:18,
		windows:91,
		esc:Event.KEY_ESC,
		enter:Event.KEY_RETURN
	},
	settings: {
		afterChoose: Prototype.emptyFunction
	},
	initialize: function(element,settings){
		this.input = $(element);
		
		if(!Object.isElement(this.input)) return false;
		
		if(!Object.isUndefined(settings)){
			Object.extend(this.settings,settings); 	
		}
		
		this.handleEmptyInput("init");
		
		this.input.writeAttribute("autocomplete","off");
		this.setEvents();
		this.createSearchWrap();
	},
	handleEmptyInput: function(type){
		if(!Object.isUndefined(type) && type == "init"){
			this.input.observe("focus",function(e){
				this.handleEmptyInput();
			}.bind(this));
			this.input.observe("blur",function(){
				this.handleEmptyInput();
			}.bind(this));
		}
		
		if(this.input.value == ""){
			this.input.setStyle({color:"#cccccc",fontStyle:"italic"});
			this.input.value = this.input.readAttribute("default_value");
		} else if(this.input.value == this.input.readAttribute("default_value")){
			this.input.setStyle({color:"",fontStyle:""});
			this.input.value = "";
		}
	},
	setEvents: function(){
		this.input.observe("keyup",this.handleKeys.bind(this)).
		observe("keydown",function(event){
			if(event.keyCode == this.keys.enter){
				if(this.resultChoose>0){
					Event.stop(event);
					this.transferResult(this.resultChoose-1);
				}
			}
		}.bindAsEventListener(this)).observe("click",function(){
			if(!Object.isUndefined(this.resultWrap) && this.resultWrap.childElements().size()>0){
				this.resultWrap.show();
			}
		}.bindAsEventListener(this));
	},
	handleKeys: function(event){
		var handle_keys = [this.keys.up,this.keys.down];
		var abort_keys = [
			this.keys.enter,this.keys.capslock,this.keys.shift,this.keys.left,
			this.keys.right,this.keys.strg,this.keys.alt,this.keys.windows
		];
		// up & down
		if(Object.inArray(event.keyCode,handle_keys)){
			Event.stop(event);
			if(this.results.size()>0){
				this.chooseResult(event.keyCode);
			}
		// escape	
		} else if(event.keyCode == this.keys.esc){
			Event.stop(event);
			this.reset(true);
		// eingabe
		} else if(!Object.inArray(event.keyCode,abort_keys)){
//			this.search();
			this.handleSearch();
		} else { 
			Event.stop(event);
		}
	},
	createSearchWrap: function(){
		var element = this.input;
			element.wrap().addClassName("editsearcher").insert({after:
			this.resultWrap = new Element("div").setStyle({
				top:(element.getHeight()-2)+"px",
				width:(element.getWidth()-2)+"px"
			}).hide().addClassName("resultwrap")
		});
		document.observe("click",function(event){
			var e = Event.element(event);
			var div = this.resultWrap;
			if(this.input != e && !Element.descendantOf(e,div) && div.visible())
				div.hide();
		}.bind(this));
	},
	chooseResult: function(key){
		var nums = this.resultWrap.childElements().size();
		var set = false;
		var select = this.resultChoose;
		
		// key handling
		if(key == this.keys.down && select==0){
			this.resultChoose = select+1;
			this.resultWrap.childElements().invoke("removeClassName","selected")[0].addClassName("selected");
		} else if(key == this.keys.up && select > 1){
			this.resultChoose = select-1;
			set = true;
			this.handleView("up");
		} else if(key == this.keys.down && select < nums){
			this.resultChoose = select+1;
			set = true;
			this.handleView("down");
		}
		// selected setten
		if(set){
			this.resultWrap.childElements().each(function(e,i){
				if(i==(this.resultChoose-1)){
					e.addClassName("selected");
				} else e.removeClassName("selected");
			}.bind(this));
		}
	},
	handleView: function(key){
		var selected = this.resultWrap.childElements()[this.resultChoose-1];
		var selectedBottom = selected.offsetTop+selected.getHeight();
		var height = this.resultWrap.getHeight();
		var scrollTop = this.resultWrap.scrollTop;
		
		if(height<selectedBottom && key == "down"){
			this.resultWrap.scrollTop = scrollTop+selected.getHeight();
		} else if(key == "up" && selectedBottom<=scrollTop){
			this.resultWrap.scrollTop = scrollTop-selected.getHeight();
		}
	},
	timeout: null,
	handleSearch: function(){
		if(this.timeout==null){
			this.timeout = this.search.bind(this).delay(0.3);
		} else if(this.timeout != null){
			window.clearTimeout(this.timeout);
			this.timeout = null;
			this.handleSearch();
		}
	},
	search: function(){
		if(!this.input.value.empty()){
			var obj_params = {
				action:"live_search",
				string: this.input.value
			};
			main.ajax({
				path:main.path.href+"/search.ajax",
				abortError:true,
				parameters:obj_params,
				onSuccess: function(json){
					this.resultWrap.update("").hide();
					if(!Object.isUndefined(json.results) && json.results != null){
						this.results = json.results;
						this.results.each(function(e,i){
							var label = e;
							this.resultWrap.insert(
								new Element("div").update(label).observe("click",function(event){
									this.transferResult(i)
								}.bindAsEventListener(this))
							);
						}.bind(this));
						this.resultWrap.show();
					}
				}.bind(this),
				onError: function(json){
//					this.resultWrap.update("").insert(
//						new Element("div",{className:"error"}).update(json.error)
//					).show();
					this.resultWrap.update("").hide();
				}.bind(this)
			});
		}
	},
	results:[],
	transferResult: function(iterator){
		this.input.value = this.results[iterator];
		this.reset();
		this.input.setStyle({cursor:"wait"});
		this.submit.bind(this).delay(0.5);
	},
	reset: function(boolean){
		if(!Object.isUndefined(boolean) && boolean)
			this.input.value = this.input.defaultValue;
		
		this.resultWrap.hide().update("");
		this.resultChoose = 0;
	},
	submit: function(){
		this.input.up("form").submit();
	}
});
