
var refcnt = 0;
var inputs = new Array();

function doBlur(event) {
    if (!event && window.event) {
        event = window.event;
    }
    // hide suggestion boxes
    for (var i = 0; i < inputs.length; i++) {
        hideSuggBox(inputs[i]);
    }
}

function doFieldKeyDown(event) {
    if (!event && window.event) {
        event = window.event;
    }
    target = (typeof(event.srcElement) == "undefined" ? event.target : event.srcElement);
    if (!target.xmlhttp) return;
    //console.log("Taste:"+event.keyCode); // Firefox debug message
    //opera.postError("Taste:"+event.keyCode); // Opera Debug message
    switch (event.keyCode) {
        case 13: {
            // Enter
            if (target.suggVisible && (target.lastHighlightedId >= 0)) {
                hideSuggBox(target);
                var row = document.getElementById("suggRow" + target.refcnt + "_" + target.lastHighlightedId);
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
                if (row) {
                    var fx = row.onmousedown;
                    fx();
                }
            }
            break;
        }
        case 27: {
            // Escape
            if (target.suggVisible) {
                selectRow(target, -1);
                hideSuggBox(target);
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
            }
            break;
        }
        case 33: {
            // PgUp
            if (target.suggVisible && (target.suggCount > 0)) {
                selectRow(target, 0);
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
                break;
            }
        }
        case 34: {
            // PgDn
            if (target.suggVisible && (target.suggCount > 0)) {
                selectRow(target, target.suggCount - 1);
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
                break;
            }
        }
        case 35: {
            // End
            if (target.suggVisible && (target.suggCount > 0)) {
                selectRow(target, target.suggCount - 1);
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
                break;
            }
        }
        case 36: {
            // Home
            if (target.suggVisible && (target.suggCount > 0)) {
                selectRow(target, 0);
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
                break;
            }
        }
        case 38: {
            // up
            if (target.suggCount > 0) {
                if (target.lastHighlightedId > 0) {
                    selectRow(target, target.lastHighlightedId - 1);
                    showSuggBox(target);
                }
                event.cancelBubble = true;
                event.returnValue = false;
                event.cancel = true;
                break;
            }
        }
        case 40: {
            // down
            if (!target.suggVisible) {
                target.callcounter++;
                setTimeout("doSearch(" + target.refcnt + ")", 10);
            } else
                if (target.suggCount > 0) {
                    if (target.lastHighlightedId < target.suggCount - 1) {
                        selectRow(target, target.lastHighlightedId + 1);
                        showSuggBox(target);
                    }
                    event.cancelBubble = true;
                    event.returnValue = false;
                    event.cancel = true;
                    break;
                }
        }
    }
    if ((event.keyCode == 8) || (event.keyCode == 32) || (event.keyCode >= 46))
        callSearch(target);
}

function getXMLHTTP() {
        var xmlhttp;
        if (window.ActiveXObject) {
            // Instantiate the latest Microsoft ActiveX Objects
            if (_XML_ActiveX) {
                xmlhttp = new ActiveXObject(_XML_ActiveX);
            } else {
                // loops through the various versions of XMLHTTP to ensure we're using the latest
                var versions = ["MSXML2.XMLHTTP", "Microsoft.XMLHTTP",
                                "Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0",
                                "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0"];
                for (var i = 0; i < versions.length ; i++) {
                    try {
                        // Try and create the ActiveXObject for Internet Explorer, if it doesn't work, try again.
                        xmlhttp = new ActiveXObject(versions[i]);
                        if (xmlhttp) {
                            var _XML_ActiveX = versions[i];
                            break;
                        }
                    }
                    catch (e) {
                        // TRAP
                    } ;
                };
            }
        }

        // Well if there is no ActiveXObject available it must be firefox, opera, or something else
        if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
            try {
                xmlhttp = new XMLHttpRequest();
            } catch (e) {
                xmlhttp = false;
            }
        }
        return xmlhttp;
}

function getParentProps(elem, prop) {
    // returns the sum of the property "prop" along the offsetParent row of elem
    var result = 0;
    while (elem != null) {
        result += elem[prop];
        elem = elem.offsetParent;
    }
    return result;
}

function selectRow(target, row) {
    var rowDiv;
    if (target.lastHighlightedId > -1) {
        rowDiv = document.getElementById("suggRow" + target.refcnt + "_" + target.lastHighlightedId);
        if (rowDiv.firstChild.className=="odd highlight"){
        	rowDiv.firstChild.className="odd";
        }
        else {
        	rowDiv.firstChild.className="even";
        }
    }
    target.lastHighlightedId = row;
    rowDiv = document.getElementById("suggRow" + target.refcnt + "_" + target.lastHighlightedId);
    if (rowDiv) {
    	rowDiv.firstChild.className+=" highlight";
    }
}

function mouseEnter(target_id, id) {
    var target = inputs[target_id];
    selectRow(target, id);
}

function submitString(target_id, string) {
    var target = inputs[target_id];
    target.value = string;
    //target.form.submit();
}

function setDivSize(target) {
    if (target.suggBoxWrapper) {
        target.suggBoxWrapper.style.top   = getParentProps(target, "offsetTop") + target.offsetHeight + "px";
        target.suggBoxWrapper.style.left  = getParentProps(target, "offsetLeft") + "px";
        target.suggBoxWrapper.style.width = (target.fixedwidth < 0 ? target.offsetWidth : target.fixedwidth);
    }
}

function fillDiv(target, fieldnames, rows) {
    // remove previous elements
    while (target.suggBox.hasChildNodes()) {
        target.suggBox.removeChild(target.suggBox.firstChild);
    }
    var field_index = new Array();
    for (j = 0; j < fieldnames.length; j++) {
        field_index[fieldnames[j]] = j;
    }
    target.suggBox.innerHTML = target.pretext;
    for (i = 0; i < rows.length; i++) {
        var iDiv = document.createElement("div");
        iDiv.onmouseover = new Function("", "mouseEnter(" + target.refcnt + "," + i + ")");
        var val = rows[i][0].replace(/'/g, "\\\'");
        var fstr = "submitString(" + target.refcnt + ", '" + val + "')";
        iDiv.onmousedown = new Function("", fstr);
        iDiv.id = "suggRow"  + target.refcnt + "_" + i;
        iDiv.className = "suggRow";
        iDiv.style.cursor = "pointer";

        if ((typeof target.rowfunction != "undefined") && (target.rowfunction != null) && (target.rowfunction != "")) {
            iDiv.innerHTML = target.rowfunction(i, field_index, rows[i]);
        } else {
            iDiv.innerHTML = "<div class='" + ((i % 2==0)?"odd":"even") + "'>" + decodeURI(rows[i][0]) + "</div>";
        }
        target.suggBox.appendChild(iDiv);
    }


    target.lastHighlightedId = -1;
}

function zeige(target_id,fieldnames, rows) {
    var target = inputs[target_id];
    target.suggCount = rows.length;
    fillDiv(target, fieldnames, rows);
    // no results?
    if (rows.length == 0) {
        hideSuggBox(target);
        return;
    }
    showSuggBox(target);
}

function callSearch(target) {
    target.callcounter++;
    setTimeout("doSearch(" + target.refcnt + ")", target.searchDelay);
}

function doSearch(target_id) {
    var target = inputs[target_id];
    if (target.callcounter > 0) target.callcounter--;
    if (target.callcounter > 0) return;
    if (target.value.length < target.minCharCount) {
        hideSuggBox(target);
        return;
    }
    if (!target.xmlhttp) return;
    // is asearch running right now?
    if (target.xmlhttp.readyState != 0) {
        // then cancel current search
        target.xmlhttp.abort();
    }

    target.xmlhttp.open("GET", target.requestURL + escape(target.value) + "&target_id=" + target_id, true);
    target.xmlhttp.onreadystatechange = target.async_fn;
    target.xmlhttp.send(null);
}

function SetupAutoSuggest(input, request, rowfunction, width, pretext) {
    // request and input are mandatory, rest are optional
    input.requestURL = request;
    input.rowfunction = rowfunction;
    input.suggBox = null;            // suggestion box (DIV)
    input.suggBoxWrapper = null;            // suggestion box frame (DIV)
    input.suggVisible = false;
    input.xmlhttp = null;
    input.lastHighlightedId = -1;
    input.suggCount = -1;
    input.searchDelay = searchDelay;        // ms until search is started
    input.minCharCount = minCharCount;      // min chars before search is started
    input.fixedwidth = -1;        // if -1, width is calculated automatically; can be set in the setup function
    input.callcounter = 0;
    input.suggVisible = false;
    input.pretext = pretext;
    
    if (typeof width != "undefined") input.fixedwidth = width;

    input.xmlhttp = getXMLHTTP();
    if (!input.xmlhttp) {
        //alert("kein iwXMLHttpRequest");
        return;
    }

    // setup input field
    input.autocomplete = "off";
    input.onblur = doBlur;
    input.onkeydown = doFieldKeyDown;
    input.onmousedown = doBlur;

    // remember input field
    inputs.push(input);
    // setup state change fn
    var fn_code = "" +
        "var target = inputs[" + refcnt + "];" +
        "if (target.xmlhttp.readyState == 4 && target.xmlhttp.responseText) {" +
        " if (target.xmlhttp.responseText.charAt(0) == \"<\") {" +
        " } else {" +
        "   try {" +
//      "   alert(target.xmlhttp.responseText);" +
        "      eval(target.xmlhttp.responseText);" +
        "  } catch (e) {" +
//        "    alert(e); " +
        "      var txt = target.xmlhttp.responseText.replace(/\'/g, \"''\");" +
        "      try {" +
        "          eval(txt);" +
        "      } catch (ie) {" +
        "        alert(ie);" +
        "          hideSuggBox(target);" +
        "    }" +
        "  }" +
        " }" +
        "}";


    input.async_fn = new Function("", fn_code);
    input.xmlhttp.onreadystatechange = input.async_fn;

    // create visual element
    input.suggBoxWrapper = document.createElement("div");
    input.suggBoxWrapper.className = "suggestwrap";
    input.suggBoxWrapper.name = "suggestwrap" + refcnt;
    input.suggBoxWrapper.id = "suggestwrap" + refcnt;
    
    input.suggBox = document.createElement("div");
    input.suggBox.className = "content";
    input.suggBox.name = "suggBox" + refcnt;
    input.suggBox.id = "suggBox" + refcnt;
    input.suggBox.innerHTML = input.pretext;
    input.refcnt = refcnt;
    refcnt++;
    setDivSize(input);
    
    input.suggBoxWrapper.appendChild(input.suggBox);
    document.body.appendChild(input.suggBoxWrapper);
    
    window.onresize = setDivSizes;
}

function showSuggBox(target) {
    //document.getElementById("suggBox" + target.refcnt).style.visibility = "visible";
    document.getElementById("suggestwrap" + target.refcnt).style.visibility = "visible";
    target.suggVisible = true;
}

function hideSuggBox(target) {
    //document.getElementById("suggBox" + target.refcnt).style.visibility = "hidden";
    document.getElementById("suggestwrap" + target.refcnt).style.visibility = "hidden";
    target.suggVisible = false;
}

function setDivSizes() {
    for (i = 0; i < inputs.length; i++) {
        setDivSize(inputs[i]);
    }
}