function initSqSuggest() {
  timer = null;

  for(var i=0;i<SqInputFields.length;i++){
    if(document.getElementById(SqInputFields[i]["id"])){
      currentField = document.getElementById(SqInputFields[i]["id"]);
      currentField.focus();
      currentField.onkeyup = function(ereignis){
        test = this;
        if(timer) window.clearTimeout(timer);
        curKC=(ereignis)?ereignis.keyCode:window.event.keyCode;
        if(curKC!=40&&curKC!=38&&curKC!=9&&curKC!=16&&curKC!=13){
          timer = window.setTimeout('suggestion(test, curKC)', SqGetStopDelay);
        }else{
          suggestion(test, curKC);
        }
      }
      // timeout wird benoetigt, da onblur sonst die korrekte durchfuehrung eines evtl. onclick auf einen der Eintraege behindert
      currentField.onblur = new Function ("ereignis","window.clearTimeout(timer);leaveInputField();");
      currentField.onclick = new Function("ereignis", "if(Sqs.container)Sqs.delete_Sqs();");
    }
  }

  // wenn nach waehlen eines Eintrags der Liste (Pfeiltasten) Enter gedrueckt wird,
  // wird nur der Container geloescht, nicht das Formular abgeschickt
  document.getElementsByName(SqCurrentFormName)[0].onsubmit = function (){
    if(Sqs.container) return false;
    else return true;
  }

  // Initialisieren der flags und des Inputs
  clickSel = 0;
  scrollSel = 0;
  userInput = "";
}

function leaveInputField(){
  if (Sqs.container){
    // wenn per mouse selektiert wurde bleibt der Focus im Eingabefeld
    if(scrollSel && scrollSel == 1 && !clickSel){
      Sqs.inputField.focus();
      scrollSel = 0;
    }else{
      if(clickSel == 1){
        Sqs.inputField.focus();
        clickSel = 0;
      }else if(Sqs.countList > -1) Sqs.inputField.value = Sqs.container.getElementsByTagName("div")[Sqs.countList].firstChild.nodeValue;
      Sqs.delete_Sqs();
    }
  }
}

function suggestion(curField, kc) {
  // find index
  var count = 0;
  do{
    fieldIndex = count;
    count++;
  }while(curField.id != SqInputFields[count-1]["id"])

  Sqs.inputField = curField;

  if((kc == 40) && (Sqs.container)){
    // Bei Druecken der Pfeiltaste 'runter' wird in den Eintraegen navigiert
    if(Sqs.container.getElementsByTagName("div")[Sqs.countList+1]){
      if(Sqs.countList != -1) Sqs.container.getElementsByTagName("div")[Sqs.countList].className = "";
      else Sqs.container.scrollTop = 0;
      Sqs.countList++;
      // setzen der bisherigen Scrollheight, falls diese ueber die Scrollbar veraendert wurde
      Sqs.container.scrollTop = Sqs.currentTop * 15;
      if(Sqs.countList > Sqs.currentBottom){
        Sqs.container.scrollTop = Sqs.container.scrollTop + 15;
        Sqs.currentBottom++;
        Sqs.currentTop++;
      }
      Sqs.container.getElementsByTagName("div")[Sqs.countList].className = "selected";
//      Sqs.container.getElementsByTagName("div")[Sqs.countList].style.width = Sqs.container.clientWidth;
    }
  }else if((kc == 38) && (Sqs.container)){
    // Bei Druecken der Pfeiltaste 'rauf' wird in den Eintraegen navigiert
    if(Sqs.countList >= 0){
      Sqs.container.getElementsByTagName("div")[Sqs.countList].className = "";
      Sqs.countList--;
      if(Sqs.countList == -1){
        Sqs.inputField.value = userInput;
      }else{
        // setzen der bisherigen Scrollheight, falls diese ueber die Scrollbar veraendert wurde
        Sqs.container.scrollTop = Sqs.currentTop * 15;
        if(Sqs.countList < Sqs.currentTop){
          Sqs.container.scrollTop = Sqs.container.scrollTop - 15;
          Sqs.currentTop--;
          Sqs.currentBottom--;
        }
        Sqs.container.getElementsByTagName("div")[Sqs.countList].className = "selected";
//        Sqs.container.getElementsByTagName("div")[Sqs.countList].style.width = Sqs.container.clientWidth;
      }
    }
  }else if(kc != 9 && kc != 16 && kc != 13){
    // bei Druecken der Tab-, Shift- oder der Entertaste passiert nichts...
    // erzeugt den suggestion-Container und holt die Inhalte
    // user-Eingabe merken, wird bei verlassen der Auswahlliste ueber die Pfeiltasten wieder im Feld eingetragen
    userInput = curField.value;
    if (Sqs.container){
      Sqs.delete_Sqs();
      // Markierung des ausgewaehlten Eintrags zuruecksetzen.
      Sqs.countList = -1;
    }
    if(curField.value != ""){
      document.getElementsByTagName("body")[0].appendChild(Sqs.erzeugen(fieldIndex));
      Sqs.holen(curField.value+"?", fieldIndex);
    }
  } else if(kc == 13){
    if(Sqs.container){
      if(Sqs.countList > -1)Sqs.inputField.value = Sqs.container.getElementsByTagName('div')[Sqs.countList].firstChild.nodeValue;
      Sqs.inputField.focus();
      Sqs.delete_Sqs();
    }
  }
  // naechsten Tastendruck werten
}

// suggestion-Layer-Objekt 'SuggestionLocations'
var Sqs = {
  container: null,		// DIV-Container
  ajax: false,			// XMLHttpRequest-Objekt
  div_width: "auto",		// width und ...
  div_height: 150,			// height des suggestion-Containers
  countList: -1,
  currentTop: 0,
  currentBottom: 9,
  inputField: null,

  erzeugen: function(fieldIndex) {
    // erzeugt Div-Container
    Sqs.container = document.createElement("div");
    Sqs.container.id = "suggestion";
    // Opera braucht zwingend eine feste width, um 'overflow' korrekt zu interpretieren
    if(navigator.userAgent.toLowerCase().indexOf("opera")>-1) Sqs.container.style.minWidth = "152px";
    Sqs.container.style.width = "auto";
    Sqs.container.style.height = "auto";
    // Positionieren direkt unterhalb des Eingabefelds (L&F einer LB)
    var pos_x = Sqs.getPosX(Sqs.inputField);
    var pos_y = Sqs.getPosY(Sqs.inputField)+20;
    Sqs.container.style.left = pos_x + "px";
    Sqs.container.style.top = pos_y + "px";

    // MSIE/Opera setzt bei scrollen in der Auswahllist den Focus auf den Container um,
    // das Eingabefeld wird also verlassen und der Container loescht sich quasi selbst...
    // Das hier gesetzte Flag faengt diesen Fall in leaveInputField() ab.
    Sqs.container.onmousedown = new Function ("ereignis", "if(navigator.userAgent.toLowerCase().indexOf('msie')>-1)scrollSel=1;")

    // zurueckgeben
    return Sqs.container;
  },

  holen: function(input, fieldIndex) {
    // Ajax-Verbindung herstellen
    try {			// W3C-Standard
      Sqs.ajax = new XMLHttpRequest();
    } catch(w3c) {
      try {			// Internet Explorer
        Sqs.ajax = new ActiveXObject("Msxml2.XMLHTTP");
      } catch(msie) {
        try {		// Internet Explorer alt
          Sqs.ajax = new ActiveXObject("Microsoft.XMLHTTP");
        } catch(msie_alt) {
          Sqs.delete_Sqs();
          for(var i=0;i<SqInputFields.length;i++){
            if(document.getElementById(SqInputFields[i]["id"])){
              document.getElementById(SqInputFields[i]["id"]).onfocus = null;
              document.getElementById(SqInputFields[i]["id"]).onkeyup = null;
              document.getElementById(SqInputFields[i]["id"]).onblur = null;
              document.getElementById(SqInputFields[i]["id"]).onclick = null;
            }else if(document.getElementById(SqInputFields[i]["id"])){
              document.getElementById(SqInputFields[i]["id"]).onfocus = null;
              document.getElementById(SqInputFields[i]["id"]).onkeyup = null;
              document.getElementById(SqInputFields[i]["id"]).onblur = null;
              document.getElementById(SqInputFields[i]["id"]).onclick = null;
            }
          }
          return false;	
        }
      }
    }
    // Datei anfordern (asynchron)
    var tempURL = SqInputFields[fieldIndex]['requrl']+input;
    Sqs.ajax.open('GET', tempURL, true);
    Sqs.ajax.setRequestHeader('Content-Type', 'text/xml');
    // umgeht Internet Explorers Caching von GET-Anfragen
    Sqs.ajax.setRequestHeader('If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT');
    Sqs.ajax.send(null);
    Sqs.ajax.onreadystatechange = function() {
      // wenn Ergebnis komplett empfangen ist ...
      if (Sqs.ajax.readyState == 4) {
        // Fehler bei der uebertragung (Server nicht gefunden...)
        if (Sqs.ajax.status != 200) {
          Sqs.delete_Sqs();
          return false;
        }
        // schreibe alle Vorschlaege in sls
        if(Sqs.ajax.responseXML != null){
          var sls = Sqs.ajax.responseXML.getElementsByTagName("suggestions");
          // Eine Schleife, die alle Vorschlaege durchlaeuft und jeden mit allen subnodes in den Container einfuegt
          for(var i = 0; i < sls.length; i++) {
            sugCount = 0;
            // Werden Eingaben schnell hintereinander geloescht und das Eigabefeld ist leer,
            // wird der Container geloescht waehrend die Funktion noch laeuft, daher Abbruch.
            if(Sqs.container)klonen(sls[i].cloneNode(true), Sqs.container);
            else return false;
            // Border wird erst hier gesetzt damit leeres div nicht zu sehen ist...
            Sqs.container.style.borderWidth = 1;
            if(navigator.userAgent.toLowerCase().indexOf('msie')>-1 && navigator.userAgent.indexOf('7.0')<0){
              if(sugCount > 1 && document.getElementById("time"))
                document.getElementById("time").style.display = "none";
              else if(sugCount > 4 && document.getElementById("toselect") && Sqs.container.clientWidth > 170)
                document.getElementById("toselect").style.display = "none";
            }
            if(sugCount < 10)Sqs.container.style.height = "auto";
            else Sqs.container.style.height = Sqs.div_height + "px";
            if(navigator.userAgent.toLowerCase().indexOf("msie")>-1) Sqs.container.style.width = Sqs.container.clientWidth+20;
            if(sugCount < 1) Sqs.delete_Sqs();
            return true;
          }
        }
        //var nicht_gefunden = document.createTextNode("No suggestions for your input '" + input + "'.");
        //Sqs.container.appendChild(nicht_gefunden);
        return false;
      }
    }
  },

  delete_Sqs: function() {
    // loescht den suggestion-Container
    if(Sqs.container){
      document.getElementsByTagName("body")[0].removeChild(Sqs.container);
      if(navigator.userAgent.toLowerCase().indexOf('msie')>-1 && navigator.userAgent.indexOf('7.0')<0){
        if(document.getElementById("time"))
          document.getElementById("time").style.display = "inline";
        else if(document.getElementById("toselect"))
          document.getElementById("toselect").style.display = "inline";
      }
      Sqs.countList = -1;
     // Sqs.inputField = null;
      Sqs.container = null;
      Sqs.currentTop = 0;
      Sqs.currentBottom = 9;
    }
  },

  // Get x-positon of element
  getPosX: function(element){
    var curleft = 0;
    if (element.offsetParent){
       while (element.offsetParent){
          curleft += element.offsetLeft;
          element = element.offsetParent;
       }
    }
    else if (element.x)	curleft += element.x;
    return curleft;
  },

  // Get y-position of element
  getPosY: function(element){
    var curtop = 0;
    if (element.offsetParent)	{
       while (element.offsetParent){
          curtop += element.offsetTop;
          element = element.offsetParent;
       }
    }
    else if (element.y)	curtop += element.y;
    return curtop;
  }
};

function klonen(original, copy) {
  // Hilfsfunktion fuer suggestion-Darstellung im DOM
  // rekursiver Aufruf baut die gesamte Struktur des zu klonenden Elements nach.
  for(var i = 0; i < original.childNodes.length; i++) {
    var knoten = original.childNodes[i];
    switch (knoten.nodeType) {
      case 1:	// Elementknoten
        var neu = copy.appendChild(document.createElement(knoten.nodeName));
        for (var j = 0; j < knoten.attributes.length; j++) {
          neu.setAttribute(knoten.attributes[j].nodeName, knoten.attributes[j].nodeValue);
        }
        if(knoten.nodeName == "div"){
          //neu.onmousedown = new Function("ereignis", "selectEntry(this.firstChild.nodeValue);");
          neu.onmousedown = new Function("ereignis", "Sqs.inputField.value = this.firstChild.nodeValue;clickSel = 1;");
        }
        sugCount++
        klonen(knoten, neu);
        break;
      case 3:	// Textknoten
        subknoten = document.createTextNode(knoten.nodeValue);
        copy.appendChild(subknoten);
      // andere Knotentypen sind nicht relevant
    }
  }
}
