function Suggest(input,matchDiv,liste,group,vorbelegung,platzhalter)
{
	/** eventhandle für tastatureingabe */
	function keyup(evt) {
		if(!evt) evt = window.event;
		var key = evt.keyCode;

		suggest = getSource(evt).suggest;
        if(suggest.input.lastValue==suggest.input.value)
            return;

        matches = suggest.match(suggest.input.value)

        while(matches.length==0){
            suggest.input.value = suggest.input.value.substring(0,suggest.input.value.length-1);
            matches = suggest.match(suggest.input.value);
        }
		suggest.fillSelectList(matches);
        suggest.displayMatchDiv();

		if(key>=32 && matches.length==1){
            suggest.input.value = matches[0];
            suggest.matchDiv.style.display = 'none';
        }
        suggest.input.lastValue=suggest.input.value;
        clearFields(suggest.input);
	}

    function position(node){
        this.x = 0;
        this.y = 0;
        while(node)
        {
            this.x += node.offsetLeft;
            this.y += node.offsetTop;
            node = node.offsetParent;
        }
    }

	function focusGained(evt){
		if(!evt) evt = window.event;
		suggest = getSource(evt).suggest;
        if(suggest.input.value==suggest.platzhalter){
            if(suggest.input.firstFocus == true){   // beim ersten mal nicht loeschen
                suggest.input.firstFocus = false;
            } else {
                suggest.input.value='';
            }
            suggest.input.select();
        }
        closeAllMatchDiv(suggest.input);
	}

	function geklickt(evt){
		if(!evt) evt = window.event;
		suggest = getSource(evt).suggest;
        if(suggest.input.value==suggest.platzhalter){
            suggest.input.value='';
            suggest.input.select();
        }
        closeAllMatchDiv(suggest.input);
	}

    this.closeMatchDiv = function()
    {
        this.matchDiv.style.display = 'none';
    }

    this.displayMatchDiv = function()
    {
        var parent = this.matchDiv.parentNode;
        if(parent.nodeName!="BODY"){
            parent.removeChild(this.matchDiv);
            document.getElementsByTagName('BODY')[0].appendChild(this.matchDiv);
            var pos = new position(this.input);
            this.matchDiv.style.top  = pos.y + this.input.offsetHeight + "px";
            this.matchDiv.style.left = pos.x + "px";
        }
        this.matchDiv.style.display = 'block';
    }

	/** aufbau der selektionslisten
	 * @param matches sind die werte (array), die angezeigt werden sollen
	 */
	this.fillSelectList = function(matches)
	{
		childNodes = this.matchDiv.childNodes;
		for(i=0;!this.childDiv && i<childNodes.length;i++){
			if(childNodes[i].nodeName=='DIV'){
				this.childDiv = childNodes[i];
				this.childDiv.setAttributeNode( createAttribute("class"  , "childDiv"  ) );
			}
		}

        // alles alte generierte entfernene
        for(i=0;this.matchDiv.elements && i<this.matchDiv.elements.length;i++){
            this.childDiv.removeChild(this.matchDiv.elements[i]);
        }

        var firstChar = '';
        var row = 0;
		this.matchDiv.elements = Array();
		for(i=0;i<matches.length;i++){
            if(matches[i]=='groupOff'){
                this.matchDiv.group = false;
                continue;
            }
            if(matches[i]=='groupOn'){
                this.matchDiv.group = true;
                continue;
            }
            if(this.matchDiv.group && matches[i].charAt(0)!=firstChar && matches[i].indexOf(this.semiDelim)==-1){
                firstChar = matches[i].charAt(0);
    			var element = document.createElement("span");
                element.setAttributeNode( createAttribute("class"  , "highlightSpan") );
                element.appendChild(document.createTextNode(firstChar));
    			this.childDiv.appendChild(element);
                element.style.position = 'absolute';
                element.style.top      = (row++) * 15 + "px";
                element.style.left     = 5 + "px";
    			this.matchDiv.elements[matchDiv.elements.length] = element;
            }
			var element = document.createElement("span");
            if(matches[i]!='-'){
                var textNode = document.createTextNode(matches[i]);
                element.appendChild(textNode);
                element.match = matches[i];				// soll im event handler ausgelesen werden
                element.input = this.input;				// in dieses feld soll match eingragen werden
                element.matchDiv = this.matchDiv;		// in dieser div stehen die matches
                element.setAttributeNode( createAttribute("title"  , matches[i]) );
                if(matches[i].indexOf(this.semiDelim)!=-1){
                    element.setAttributeNode( createAttribute("class"  , "matchSpanSemi"  ) );
                } else {
                    element.setAttributeNode( createAttribute("class"  , "matchSpan"  ) );
                }
                element.onclick = selectMatch;
                element.onmouseover = highlightMatch;
                element.onmouseout = normalMatch;
            }
        	element.style.position = 'absolute';
			element.style.top      = (row++) * 15 + "px";
			element.style.left     = (this.matchDiv.group ? 25 : 5) + "px";

			this.childDiv.appendChild(element);
			this.matchDiv.elements[matchDiv.elements.length] = element;
		}
	}


	/** liefert ein Array von Treffern zurück */
	this.match = function(wortanfang)
	{
		if(wortanfang.length == 0)
			return this.liste;
		wortanfang = wortanfang.toLowerCase();

		var treffer = new Array();
		for(i=0; i<this.liste.length; i++){
			s = this.liste[i].toLowerCase();
			if(s.indexOf(wortanfang) == 0)
				treffer[treffer.length] = this.liste[i];
		}
		return treffer;
	}

    /** schnurrt das Eingabefeld auf den ersten Treffer in der match liste zusammen */
    this.firstMatch = function()
    {
        var matches = this.match(this.input.value);
        while(matches.length==0){
            this.input.value = this.input.value.substring(0,this.input.value.length-1);
            matches = this.match(this.input.value);
        }
        if(matches.length==1){
            this.input.value = matches[0];
        }
    }

	this.fullMatch = function(value){
        if(value==this.vorbelegung)
            return true;

		for(i=0; i<this.liste.length; i++){
			if(this.liste[i] == value){
				return true;
            }
		}
		return false;
	}

	/** erzeugt ein HTML Attribut */
	function createAttribute(name, value){
		var attr = document.createAttribute(name);
		attr.nodeValue = value;
		return attr;
	}

	/** errechnet für einen event das herkunftsobjekt */
	function getSource(evt){
		     if(evt.srcElement) return evt.srcElement;
		else if(evt.target)     return evt.target;
	}

	function highlightMatch(evt){
		if(!evt) evt = window.event;
		source = getSource(evt);
		source.style.oldcolor = source.style.color;
		source.style.oldbg    = source.style.backgroundColor;
		source.style.color = 'white';
		source.style.backgroundColor = 'black';
	}

	function normalMatch(evt){
		if(!evt) evt = window.event;
		source = getSource(evt);
		source.style.color = source.style.oldcolor;
		source.style.backgroundColor = source.style.oldbg;
	}

	/** trägt in input den match wert ein */
	function selectMatch(evt){
		if(!evt) evt = window.event;
		source = getSource(evt);
		source.matchDiv.style.display = 'none';
		source.input.value = source.match;
	}

    if(input){
        this.input          = input;		// hier kann der Benutzer tippen
        this.input.suggest  = this;		    // private variable im input merken und im eventhandler auslesen
        this.vorbelegung    = vorbelegung;
        this.platzhalter    = platzhalter;
        this.input.lastValue= input.value;

        this.matchDiv       = matchDiv;		// hier kommen die auszuwählenden Werte hinein
        this.matchDiv.group = group;        // nach erstem Buchstaben im Aplhabet gruppieren (oder halt nicht)
        this.semiDelim      = "(";
        
        this.liste          = liste;		// dies ist die Liste der auszuwählenden Werte
        this.input.onkeyup  = keyup;		// dies ist der eventhandler
        this.input.onfocus  = focusGained;	// dies ist der eventhandler
        this.input.onclick  = geklickt;     // dies ist der eventhandler
        this.fillSelectList(this.liste);	// alle Werte
    }
};

function check(){
    for(i=0;i<document.formular.elements.length;i++){
        if(document.formular.elements[i].suggest && document.formular.elements[i].value==document.formular.elements[i].suggest.platzhalter)
            document.formular.elements[i].value = '';
    }
	var plz          = document.formular.plz.value;
	var ort          = document.formular.ort.value;
	var rechtsgebiet = document.formular.rechtsgebiet ? document.formular.rechtsgebiet.value : '';
	var fachgebiet   = document.formular.fachgebiet   ? document.formular.fachgebiet.value   : '';
	var notargebiet  = document.formular.notargebiet  ? document.formular.notargebiet.value  : '';

	if(plz.length==0 && ort.length==0){
		alert("Bitte geben Sie ein Postleitzahl oder einen Ort an.");
        return false;
    }
	if(ort.length==0 && plz.length!=5){
		alert("Bitte geben Sie eine 5-stellige Postleitzahl an.");
		return false;
    }
	if(init.ort && ort.length>0 && init.ort.fullMatch(ort)==false){
		alert("Bitte geben Sie einen Ort an.");
		return false;
	}
	if(rechtsgebiet.length==0 && fachgebiet.length==0 && notargebiet.length==0){
		alert("Bitte geben Sie ein Rechtsgebiet an.");
        return false;
    }
	if(init.rg && rechtsgebiet.length>0 && init.rg.fullMatch(rechtsgebiet)==false){
		alert("Bitte ein Rechtsgebiet aus der Liste angeben");
		return false;
	}
	if(init.fg && fachgebiet.length>0 && init.fg.fullMatch(fachgebiet)==false){
		alert("Bitte geben Sie ein Fachgebiet an.");
		return false;
	}
	if(init.ng && notargebiet.length>0 && init.ng.fullMatch(notargebiet)==false){
		alert("Bitte geben Sie ein Notargebiet an.");
		return false;
	}
    if(init.fg && fachgebiet=="Mietrecht/Wohnungseigentumsrecht"){
        document.formular.fachgebiet.value = fachgebiet = "Mietrecht";
    }

    if(init.rg && rechtsgebiet.indexOf(init.rg.semiDelim)!=-1){
        document.formular.rechtsgebiet.value = rechtsgebiet.substring(rechtsgebiet.indexOf(init.rg.semiDelim)+1,rechtsgebiet.length-1);
    }

    if(init.fg && fachgebiet.indexOf(init.fg.semiDelim)!=-1){
        document.formular.fachgebiet.value = fachgebiet.substring(fachgebiet.indexOf(init.fg.semiDelim)+1,fachgebiet.length-1);
    }

    var divover = document.createElement('div')
    divover.className = 'divover';
    var body = document.body;
    body.insertBefore(divover, body.firstChild);

    return true;
}

function clearFields(focusField){
   if(focusField == document.formular.ort && focusField.value.length>0){
        document.formular.plz.value = '';
    }
    else if(focusField == document.formular.plz && focusField.value.length>0){
        document.formular.ort.value = '';
    }
    else if(focusField == document.formular.rechtsgebiet){
        if(document.formular.fachgebiet ){ document.formular.fachgebiet.value  = ''; }
        if(document.formular.notargebiet){ document.formular.notargebiet.value = ''; }
    }
    else if(focusField == document.formular.fachgebiet){
        if(document.formular.rechtsgebiet ){ document.formular.rechtsgebiet.value  = ''; }
        if(document.formular.notargebiet  ){ document.formular.notargebiet.value = ''; }
    }
    else if(focusField == document.formular.notargebiet){
        if(document.formular.rechtsgebiet ){ document.formular.rechtsgebiet.value  = ''; }
        if(document.formular.fachgebiet ){ document.formular.fachgebiet.value  = ''; }
    }
}
function closeAllMatchDiv(){
	if(init.umkreis)init.umkreis.matchDiv.style.display = 'none';
	if(init.ort)init.ort.matchDiv.style.display = 'none';
    if(init.rg) init.rg.matchDiv.style.display  = 'none';
	if(init.fg) init.fg.matchDiv.style.display  = 'none';
	if(init.ng) init.ng.matchDiv.style.display  = 'none';
}

function closeAllAndClear(focusField){
    closeAllMatchDiv();
    clearFields(focusField);
}

function openSelectList(suggest){
    closeAllAndClear(suggest.input);
    suggest.fillSelectList(suggest.liste);
    suggest.displayMatchDiv();
}

function closeSelectList(suggest){
    suggest.closeMatchDiv();
}
