/**
 * Javascript tool of suggested input field.
 *
 * Usage : see the 'suggestInputField' macro in vm_global_libary.vm :)
 *
 * @depend sofia-dom.js sofia-listcrtl.js
 *
 * @param inputFieldId destination text input field of suggesting.
 * @param suggestListContainerId the container of suggested values.
 * @param iteratorName my:iterator attribute value of iterated element.
 * @param method the soap method name.
 * @param length of suggest items list.
 */
 var openedSuggestedListContainer = null;

function SuggestFieldHelper(inputFieldId, suggestListContainerId, iteratorName, method, length, onSelectMethodName, otherParams) {
    // construct
    this.method = method;
    this.length = length;
    this.otherParams = otherParams;
    this.iteratorName = iteratorName;
    this.selectedValueIndex = null;
    this.lastProcessedResponse = null;
    this.onSelectMethodName = onSelectMethodName;

    if (inputFieldId != null) {
        this.inputField = document.getElementById(inputFieldId);
    }
    if (suggestListContainerId != null) {
        this.suggestListContainer = document.getElementById(suggestListContainerId);
        this.listControl = new ListControl(this.suggestListContainer);
    }
    // regists event hander
    if (this.inputField != null && this.suggestListContainer != null && method != null && length != null) {
        var _this = this;
        this.inputField.onkeyup = function (e) {return suggestedFieldOnKeyUp(e, _this)};

        this.inputField.onkeydown = function (e) {return suggestedFieldOnKeyDown(e, _this)};

        this.inputField.suggestFieldHelper = this;

        this.suggestListContainer.onclick = suggestListContainerClick;
        this.suggestListContainer.suggestFieldHelper = this;
    }

    //send request
    this.sendRequest = function (keyword) {
        this.deselect();
        var url = "sid/suggest?method=" + encodeURIComponent(this.method) + "&keyword=" + encodeURIComponent(keyword) + "&length=" + this.length + this.otherParams
        var _this = this;
        if (window.XMLHttpRequest) {
            this.req = new XMLHttpRequest();
            this.req.onreadystatechange = function(){_this.processRequest()};
            this.req.open("GET", url, true);
            this.req.send(null);
        } else if (window.ActiveXObject) {
            this.req = new ActiveXObject("Microsoft.XMLHTTP");
            this.req.onreadystatechange = function(){_this.processRequest()};
            this.req.open("GET", url, true);
            this.req.send();
        }
    }

    this.processRequest = function () {
        if (this.req.readyState == 4) {
            if (this.req.status == 200) {
                this.lastProcessedResponse = processResponse(this.req.responseXML);
                if (this.lastProcessedResponse.length > 0) {
                    this.listControl.build(this.iteratorName, this.lastProcessedResponse, true);
                    this.suggestListContainer.style.display = "block";
                } else {
                    this.suggestListContainer.style.display = "none";
                }
                openedSuggestedListContainer = this.suggestListContainer;
            }
        }
    }

    this.insertSelectedValue = function () {
        if (this.selectedValueIndex != null && this.lastProcessedResponse != null) {
            var row = this.lastProcessedResponse[this.selectedValueIndex];
            this.inputField.value = row.value;
            this.inputField.focus();
            if (this.onSelectMethodName != null) {
                this.onSelectMethodName(row.value, row.id)
            }
        }
        this.selectedValueIndex = null;
        this.suggestListContainer.style.display = "none";
    }

    this.isSelected = function () {
        return (this.selectedValueIndex != null);
    }

    this.deselect = function() {
        this.selectedValueIndex = null;
        this.suggestListContainer.style.display = "none";
    }

    this.moveSelected = function (e) {
        if (this.suggestListContainer.style.display == "none" || this.lastProcessedResponse == null) {
            this.selectedValueIndex = null;
            return;
        }
        if (isKeyCode(e, 38)) {
            if (this.selectedValueIndex != null && this.selectedValueIndex > 0) {
                this.selectedValueIndex = this.selectedValueIndex - 1;
            } else {
                this.selectedValueIndex = null;
            }
        } else if (isKeyCode(e, 40)){
            if (this.selectedValueIndex == null) {
                this.selectedValueIndex = 0;
            } else {
                this.selectedValueIndex = this.selectedValueIndex + 1;
                if (this.selectedValueIndex > this.lastProcessedResponse.length - 1) {
                    this.selectedValueIndex = this.lastProcessedResponse.length - 1;
                }
            }
        }
        var rowList = this.suggestListContainer.childNodes;
        if (this.lastProcessedResponse != null && this.selectedValueIndex != null) {
            this.inputField.value = this.lastProcessedResponse[this.selectedValueIndex].value;
            this.highlighting(rowList, this.selectedValueIndex);
        }
    }

    this.highlighting = function(rowList, index) {
        for (var i = 0; i < rowList.length; i++) {
            var row = rowList.item(i);
            if (row.nodeType == 1) {
                if (row.getAttribute("suggestIndex") == index) {
                    row.style.color = "white";
                    row.style.background = "darkblue";
                    for (var j = 0; j < row.childNodes.length; j++) {
                        if (row.childNodes.item(j).nodeType == 1) {
                            row.childNodes.item(j).style.color = row.style.color;
                            row.childNodes.item(j).style.background = row.style.background;
                        }
                    }
                } else {
                    row.style.color = "black";
                    row.style.background = "white";
                    for (var j = 0; j < row.childNodes.length; j++) {
                        if (row.childNodes.item(j).nodeType == 1) {
                            row.childNodes.item(j).style.color = row.style.color;
                            row.childNodes.item(j).style.background = row.style.background;
                        }
                    }
                }
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
 * Event handlers
 *
 */
function suggestedFieldOnKeyUp (e, suggestFieldHelper) {
    if (isTab(e) || isKeyCode(e, 37) || isKeyCode(e, 38) || isKeyCode(e, 39) || isKeyCode(e, 40) || isKeyCode(e, 27)) {
        return false;
    } else if (isEnter(e)) {
        suggestFieldHelper.insertSelectedValue();
        return false;
    } else if (suggestFieldHelper instanceof SuggestFieldHelper) {
        suggestFieldHelper.sendRequest(suggestFieldHelper.inputField.value);
        return false;
    }
    return true;
}

function suggestedFieldOnKeyDown (e, suggestFieldHelper) {
    if (isTab(e) || isKeyCode(e, 27)) {
        suggestFieldHelper.deselect();
        return true;
    } else if (isEnter(e)) {
        return false;
    } else if (isKeyCode(e, 38) || isKeyCode(e, 40)) {
        suggestFieldHelper.moveSelected(e);
        return false;
    }
    return true;
}

function suggestedFieldOnMouseOver (e) {
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) targ = targ.parentNode;

    var container = targ.parentNode;
    var index = -1;
    if (container.suggestFieldHelper instanceof SuggestFieldHelper) {
        if (targ.nodeType == 1 && targ.getAttribute("suggestIndex")) {
            index = targ.getAttribute("suggestIndex");
            var rowList = container.childNodes;
            container.suggestFieldHelper.highlighting(rowList, index)
        }

    }
}

function suggestListContainerClick(e) {
    if (this.suggestFieldHelper instanceof SuggestFieldHelper) {
        // getting event target.
        var targ;
        if (!e) var e = window.event;
        if (e.target) targ = e.target;
        else if (e.srcElement) targ = e.srcElement;
        if (targ.nodeType == 3) targ = targ.parentNode;

        var index;
        while (targ == this.suggestFieldHelper.suggestListContainer || targ.parentNode != null) {
            if (targ.nodeType == 1 && targ.getAttribute("suggestIndex")) {
                index = targ.getAttribute("suggestIndex");
                break;
            }
            targ = targ.parentNode;
        }
        // if event source of parent has not suggestIalue attribute return
        if (index != null) {
            this.suggestFieldHelper.selectedValueIndex = index;
            this.suggestFieldHelper.insertSelectedValue();
        }
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * Respose proccessor method
 *
 */
function processResponse(responseXML) {
    var rows = new Array();
    var rowNodes = responseXML.getElementsByTagName("row");
    if (rowNodes != null) {
        for (var i = 0; i < rowNodes.length; i++) {
            var row = new SuggestRow(i, rowNodes.item(i));
            rows.push(row);
        }
    }
    return rows;
}
function SuggestRow(index, rowNode) {
    this.index = index;
    var valueNodes = rowNode.getElementsByTagName("value");
    this.value = valueNodes.item(0).firstChild.nodeValue;

    var descritionNodes = rowNode.getElementsByTagName("description");
    this.description = descritionNodes.item(0).firstChild.nodeValue;

    var idNodes = rowNode.getElementsByTagName("id");
    this.id = idNodes.item(0).firstChild.nodeValue;
}
