function setStringToInput(val){
    $('sString').value = val;
    document.myform.submit();
}

Event.observe(window, 'load', function() {

	var suggestions = new SuggestionsDataContainer() ;
	var suggestMeSomething = new InputFieldSuggestions("sString", suggestions, { className: 'suggestions', autoComplete: true, autoSubmit: true });
	suggestMeSomething.addObserver("modus", "change") ;
  
} );

var InputFieldSuggestions = Class.create({
	initialize: function(inputFieldId, dataObjectId, options) {
		this.options = Object.extend(Object.extend({}, this.DefaultOptions), options || {}) ;

		this.inputField = $(inputFieldId) ;
		this.form = $(this.inputField.form) ;
		this.data = dataObjectId ;

		this.userInput = '' ;
		this.contentData = [] ;
		this.contentSize = 0 ;

		this.visible = true ;
		this.blocked = false ;

		this.highlighted ;
		this.highlightedItem ;
		this.hideTimer = "" ;
		
		this.deleteMode = false ;
		
		if (this.options.className == '') {
			this.divStyle = $H({ style: 'background-color: white; border: 1px solid black; padding: 4px; z-index: 100;' }) ;
			this.listStyle = $H({ style: 'cursor: pointer; list-style-type: none; padding-left: 0' }) ;
		}
		else {
			this.divStyle = $H({ className: this.options.className }) ;
			this.listStyle = $H() ;
		}
		this.element = this._create() ;

		this.inputField.observe('focus', this.show.bindAsEventListener(this)) ;	// wenn Eingabefeld im Fokus ist, vorhandene Vorschlaege einblenden
		this.inputField.observe('blur', this.hide.bindAsEventListener(this)) ;	// wenn Eingabefeld Fokus verliert, Vorschlaege ausblenden

		this.inputField.observe('keydown', this.handleKeyEvents.bindAsEventListener(this)) ;
		//this.inputField.observe('keypress', this.handleKeyEvents.bindAsEventListener(this)) ;
		this.inputField.observe('keyup', this.handleKeyEvents.bindAsEventListener(this)) ;
		
		this.inputField.writeAttribute({ autocomplete: 'off' }) ;  // Browser-Vorschlaege in Firefox unterbinden

		this.highlight(false) ;		
		this.hide(false) ;

		return this ;
	},
	
	_create: function() {
		this.divStyle.set('id', 'sbox' + new Date().getTime()) ;
		var newDiv = new Element('div', this.divStyle.toObject()) ;
		$$('body')[0].appendChild(newDiv) ;	// IE6/7 z-index-Bug umgehen
		return newDiv ;
	},
	
	addObserver: function(elementId, eventType) {
		// vorlaeufig, stopObserving sollte evtl. noch implementiert werden
		$(elementId).observe(eventType, this.refresh.bindAsEventListener(this)) ;
	},

	show: function() {
		if (this.hideTimer != "") {
			clearTimeout(this.hideTimer) ;
			this.hideTimer = "" ;
		}
		
		if (!this.isVisible() && this.contentSize > 0) {
			this.inputField.focus() ;	// Fokus auf Eingabefeld setzen
			this.element.setStyle({ display: 'block',
				left: this.inputField.cumulativeOffset().left + 'px', 
				position: 'absolute', 
				top: this.inputField.cumulativeOffset().top + this.inputField.getHeight() + 'px' }) ;
			this.element.observe('click', this.handleMouseClick.bindAsEventListener(this)) ; 
			this.visible = true ;
			
		}

	},
	
	hide: function(withDelayFlag) {
		if (withDelayFlag) {
			if (this.hideTimer == "") this.hideTimer = this._hide.delay(0.2, this) ;	// verzoegert, damit click-event durchgeht
		}
		else {
			this._hide(this) ;
		}

	},
	
	_hide: function(element) {
		if (element.isVisible()) {
			element.element.setStyle({ display: 'none' }) ;
			element.element.stopObserving();
			element.visible = false ;
		}

	},

	isVisible: function() {
		return this.visible ;
	},

	handleMouseClick: function(event) {
		this.highlight(event.findElement().id.sub(this.element.id + "_", "")) ;
		this.hide();
		if (this.options.autoSubmit) {
			this.form.submit() ;
		}
		else {
			this.inputField.focus() ;
		}
		event.stop() ;
	},

	handleKeyEvents: function(event) {
		var keyCode = event.keyCode ; 
		var highlighted = this.getHighlighted() ;

		switch(keyCode) {
			case (Event.KEY_TAB):
				if (this.isHighlighted()) {
					if (this.options.autoSubmit) {
						this.form.submit() ;
					}
					else {
						this.userInput = '' ;
						this.highlight(-1) ;
						this.hide(false) ;
					}
				}
				break ;

			case (Event.KEY_ESC):
				if (this.isVisible()) {
					if (this.isHighlighted()) this.inputField.value = this.userInput ;	// User-Eingabe wiederherstellen
					this.hide() ;
				}
				break ;
				
			case (Event.KEY_BACKSPACE):
			case (Event.KEY_DEL):
				this.deleteMode = true ;
				if (event.type == 'keyup') this.refresh() ;
				break;

			case (Event.KEY_UP):
				if (this.isVisible() && event.type != 'keyup' && this.isHighlighted()) this.highlight(highlighted - 1) ;
				break ;

			case (Event.KEY_DOWN):
				if (this.isVisible() && event.type != 'keyup') {
					if (!this.isHighlighted()) highlighted = -1 ;
					this.highlight(highlighted + 1) ;
				}

				break ;

			default:
				this.deleteMode = false ;
				if (event.type == 'keyup') this.refresh() ;
				return ;
		}

	},

	highlight: function(contentItem) {
		if (this.contentSize == 0 || contentItem == -1) {
			this.highlighted = false ;
			this.highlightedItem = -1 ;
		}
		else {
			if (this.userInput == '') this.userInput = this.inputField.value ;	// User-Eingabe fuer KEY_ESC merken

			contentItem = (contentItem < 0 ? 0 : (contentItem > this.contentSize - 1 ? this.contentSize - 1 : contentItem )) ;
			if (this.isHighlighted()) this.element.down('li', this.getHighlighted()).setStyle({ backgroundColor: '' }) ;	// altes Highlight entfernen
			this.element.down('li', contentItem).setStyle({ backgroundColor: this.options.itemHighlightColor }) ;	// neues Highlight anbringen
			this.inputField.value = this.contentData[contentItem] ;		// Vorschlag ins Eingabefeld uebernehmen
			//this.inputField.select() ;
			this.inputField.focus() ;
			this.highlightedItem = contentItem ;
			this.highlighted = true ;

		}
		return this.highlightedItem ;

	},

	isHighlighted: function() {
		return this.isVisible() ? this.highlighted : false ;
	},

	getHighlighted: function() {
		return this.highlightedItem ;
	},

	refresh: function() {
		if (!this.isBlocked()) {
			this.userInput = '' ;	// bisherige User-Eingabe loeschen

			if (this.inputField.value != '' || this.inputField.value.length >= this.options.minInputLength) {
				this.data.request($H(this.form.serialize(true)), 	// Daten-Objekt abfragen
					function(data) {
						if (!data) {
							this.block() ;	// Fehler beim Datenabruf (data = false) -> keine Vorschlaege mehr generieren
						}
						else {
							this._refresh(data) ;
						}
					}.bind(this)) ;
			}
			else {
				this._refresh([]) ;
			}
		}

	},

	_refresh: function(data) {
		this.contentData = data ;
		this.contentSize = this.contentData.size() ;

		if (this.contentSize == 0 || (this.contentSize == 1 && this.contentData[0].toLowerCase() === this.inputField.value.toLowerCase())) {
			this.element.update('') ;
			this.contentSize = 0 ;
			this.hide(false) ;
		}
		else if (this.contentSize == 1 && this.options.autoComplete && !this.deleteMode) {
			this.inputField.value = this.contentData[0] ;
			//this.inputField.select() ;
			this.inputField.focus() ;
			this.element.update('') ;
			this.contentSize = 0 ;
			this.hide(false) ;
		}
		else {
			var newId = this.element.id + "_" ;
			var newContent = new Element('ul', this.listStyle.toObject()) ;
			this.contentData.each(function(item, index) { 
				newContent.insert ({ bottom: new Element('li', { id: newId + index }).update(item) }) ; 
				}) ;
			this.element.update(newContent) ;
			this.show() ;
		}
		this.highlighted = false ;	// Tastaturauswahl entfernen
		this.highlightedItem = -1 ;

	},
	
	block: function() {
		this.blocked = true ;	// keine Vorschlaege mehr liefern
		this.hide(false) ;
		this.inputField.stopObserving() ;	// alle Observer vom Eingabefeld entfernen

	},

	isBlocked: function() {
		return this.blocked ;
	},

	DefaultOptions: {
		autoComplete:		true,		// true = bei Eindeutigkeit automatisch vervollstaendigen
		autoSubmit:			true,		// true = bei Anklicken/Tab des Vorschlags Formular absenden
		className:			'',	
		itemHighlightColor:	'#cdcdcd',
		minInputLength:		1
		 
	}

}) ;

var SuggestionsDataContainer = Class.create({
	initialize: function(options) {
		this.options = Object.extend(Object.extend({}, this.DefaultOptions), options || {}) ;
		this.hash = new Hash() ;
		this.hashModus = '' ;
		this.hashCount = [] ;
		return this ;
	},
	
	request: function(formValues, responseFunction) {
		// Parameter-Mapping und Caching von Abfragen!!! 
		var isii = this._checkRequestCache(formValues.get('sString'),formValues.get('modus'));
		if(!isii)
		    this._load({ sString: formValues.get('sString'), modus: formValues.get('modus') }, responseFunction) ;
        else{
            responseFunction(isii) ; 
        }
	},
	
	_setRequestChache: function(value,data){
	        this.hashModus = value.modus;
	        
           if(!this.hash.get(value.sString)){
                this.hash.set(value.sString, data);
                this.hashCount.push(value.sString);
           }
           if(this.hashCount.size() > this.options.cacheRequests){
                this.hash.unset(this.hashCount[0]);
                this.hashCount.shift();
           }
	},
	_checkRequestCache: function(value,modus){
        if(modus != this.hashModus){
	        this.hash = new Hash() ;
	        this.hashCount = [] ;
	        return false;
        }
        if(this.hash.get(value))
            return this.hash.get(value);
        else
            return false;
	},

	_load: function(ajaxParameters, responseFunction) {

		new Ajax.Request(this.options.requestUrl, {
			method: this.options.requestMethod,
			parameters: ajaxParameters,
		
			onSuccess: function(transport) {
				var sentdata = [] ;
				$A(transport.responseXML.getElementsByTagName(this.options.responseValueElement)).each(function(item) {
					sentdata.push(item.firstChild.data) ;
				});
				this._setRequestChache(ajaxParameters,sentdata);
				responseFunction(sentdata) ;
			}.bind(this),
		
			onFailure: function(transport) {
				responseFunction(false) ;
			}.bind(this)
		
	    }); 

	},

	DefaultOptions: {
		requestUrl:				'/woerterbuch/ajax_search_preview.php',
		requestMethod:			'post',
		requestParamTemplate:	{ sString: 'sString', modus: 'modus' },		// Template fuer Parameter-Mapping
		cacheRequests:			10,			// Anzahl zwischenzuspeichernder Requests
		responseIsXML:			true,		// true = ist XML, false = ist Text (noch nicht implementiert)
		responseValueElement:	'search'

	}

}) ;
