dojo.provide("util.AutoComplete");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dojox.data.dom");

dojo.declare("util.AutoComplete",  [ dijit._Widget, dijit._Templated],
{
    templateString: "<div style='z-index:2;'><div class='choices' dojoAttachPoint='choices'></div></div>",
    formId: "",
    textboxId: "",
    action: "",
    textbox: "",
    form: "",
    SELECTED_CLASS: "selected",

    postCreate: function() {
        this.form = document.getElementById(this.formId);
        this.textbox = document.getElementById(this.textboxId);
        this.choices.style.width = this.textbox.style.width;

        dojo.connect(document, "onclick", this, "documentOnClick");
        dojo.connect(this.textbox, "onkeypress", this, "textboxOnKeyPress");
        dojo.connect(this.textbox, "onkeydown", this, "textboxOnKeyDown");
        dojo.connect(this.textbox, "onkeyup", this, "textboxOnKeyUp");
    },

    documentOnClick: function(evt) {
        this.choices.style.display = "none";
    },

    textboxOnKeyPress: function(evt) {
        if (evt.keyCode == 13 && this.choices.style.display != "none") {
            this.choices.style.display = "none";
            evt.preventDefault();
            for (var i=0; i<this.form.elements.length; i++) {
                if (this.textbox.name == this.form.elements[i].name && (i+1 < this.form.elements.length)) {
                    this.form.elements[i+1].focus();
                    break;
                }
            }
        }
    },

    textboxOnKeyDown: function(evt) {
        if (this.choices.style.display != "none" && evt.keyCode == 9) {
            this.choices.style.display = "none";
        }
    },

    textboxOnKeyUp: function(evt) {
        if (this.isKey(evt.keyCode, 38, 40)) {
            this.checkUpDownArrows(evt.keyCode);
        } else {
            var retdata = null;
        	var xhrArgs = {
            	url: this.action + '?search=' + this.textbox.value,
            	sync: true,
            	timeout: 5000,
                handleAs: "json",
                load: function(data, event) {
                    retdata = data;
                }
            };
            dojo.xhrGet(xhrArgs);

            if (retdata != null) {
            	var value = eval(  retdata  );
				this.populateChoices(value);
            }
        }
    },

    populateChoices: function(data) {
		var value = data;
		dojox.data.dom.removeChildren(this.choices); 
        for (var i=0; i<value.length; i++) {
            this.addItem(value[i]);
        }
        this.choices.style.display = (this.choices.childNodes.length > 0) ? "block" : "none";
    },

    isKey: function () {
        if (arguments.length < 2) return false;
        for (var i=1;i<arguments.length;i++) {
            if (arguments[0] == arguments[i]) return true;
        }
        return false;
    },

    checkUpDownArrows: function(characterCode) {
        if (this.choices.style.display == "none") return;

        var selIndex = this.getSelected();
        var children = this.choices.childNodes;

        if (selIndex == -1) {

            if (characterCode == 38) {
                this.setSelected(0, children.length-1);
            } else if (characterCode == 40){
                this.setSelected(0, 0);
            }


        } else if (characterCode == 38) {

             if (selIndex-1 >= 0) {
                this.setSelected(selIndex,selIndex-1);
             } else if (children.length > 0) {
                this.setSelected(selIndex,children.length-1);
             }

        } else if (characterCode == 40) {

             if (selIndex+1 < children.length) {
                this.setSelected(selIndex,selIndex+1);
             } else {
                this.setSelected(selIndex,0);
             }
        }
    },

    setSelected: function(oldIndex, newIndex) {
        var children = this.choices.childNodes;
        if (children) {
            children[oldIndex].className = "";
            children[newIndex].className = this.SELECTED_CLASS;
            this.textbox.value = children[newIndex].innerHTML;
        }
    },

    getSelected: function() {
        var size = (this.choices.childNodes == null) ? 0 : this.choices.childNodes.length;
        for (var i=0; i<size; i++) {
            if (this.choices.childNodes[i].className == this.SELECTED_CLASS) return i;
        }
        return -1;
    },

    addItem: function(item) {
        var itemDiv = document.createElement("div");
        itemDiv.innerHTML = item;
        itemDiv.style.width = "100%";
        this.choices.appendChild(itemDiv);
        dojo.connect(itemDiv, "onmouseover", this, "itemOnMouseOver");
        dojo.connect(itemDiv, "onclick", this, "itemOnClick");
    },

    itemOnMouseOver: function(evt) {
        var selIndex = this.getSelected();
        if (selIndex != -1) this.choices.childNodes[selIndex].className = "";
        evt.target.className = this.SELECTED_CLASS;
    },

    itemOnClick: function(evt) {
        this.textbox.value = evt.target.innerHTML;
        this.choices.style.display = "none";
    }
}); 
