﻿function addEvent(obj, event_name, func_name) {
        if (obj.attachEvent) {
            obj.attachEvent("on" + event_name, func_name);
        } else if (obj.addEventListener) {
            obj.addEventListener(event_name, func_name, true);
        } else {
            obj["on" + event_name] = func_name;
        }
    }
    function removeEvent(obj, event_name, func_name) {
        if (obj.detachEvent) {
            obj.detachEvent("on" + event_name, func_name);
        } else if (obj.removeEventListener) {
            obj.removeEventListener(event_name, func_name, true);
        } else {
            obj["on" + event_name] = null;
        }
    }
    function stopEvent(evt) {
        evt || window.event;
        if (evt.stopPropagation) {
            evt.stopPropagation();
            evt.preventDefault();
        } else if (typeof evt.cancelBubble != "undefined") {
            evt.cancelBubble = true;
            evt.returnValue = false;
        }
        return false;
    }
    function getElement(evt) {
        if (window.event) {
            return window.event.srcElement;
        } else {
            return evt.currentTarget;
        }
    }
    function getTargetElement(evt) {
        if (window.event) {
            return window.event.srcElement;
        } else {
            return evt.target;
        }
    }
    function stopSelect(obj) {
        if (typeof obj.onselectstart != 'undefined') {
            addEvent(obj, "selectstart", function() { return false; });
        }
    }
    function getCaretEnd(obj) {
        if (typeof obj.selectionEnd != "undefined") {
            return obj.selectionEnd;
        } else if (document.selection && document.selection.createRange) {
            var M = document.selection.createRange();
            try {
                var Lp = M.duplicate();
                Lp.moveToElementText(obj);
            } catch (e) {
                var Lp = obj.createTextRange();
            }
            Lp.setEndPoint("EndToEnd", M);
            var rb = Lp.text.length;
            if (rb > obj.value.length) {
                return -1;
            }
            return rb;
        }
    }
    function getCaretStart(obj) {
        if (typeof obj.selectionStart != "undefined") {
            return obj.selectionStart;
        } else if (document.selection && document.selection.createRange) {
            var M = document.selection.createRange();
            try {
                var Lp = M.duplicate();
                Lp.moveToElementText(obj);
            } catch (e) {
                var Lp = obj.createTextRange();
            }
            Lp.setEndPoint("EndToStart", M);
            var rb = Lp.text.length;
            if (rb > obj.value.length) {
                return -1;
            }
            return rb;
        }
    }
    function setCaret(obj, l) {
        obj.focus();
        if (obj.setSelectionRange) {
            obj.setSelectionRange(l, l);
        } else if (obj.createTextRange) {
            m = obj.createTextRange();
            m.moveStart('character', l);
            m.collapse();
            m.select();
        }
    }
    function setSelection(obj, s, e) {
        obj.focus();
        if (obj.setSelectionRange) {
            obj.setSelectionRange(s, e);
        } else if (obj.createTextRange) {
            m = obj.createTextRange();
            m.moveStart('character', s);
            m.moveEnd('character', e);
            m.select();
        }
    }
    String.prototype.addslashes = function() {
        return this.replace(/(["\\\.\|\[\]\^\*\+\?\$\(\)])/g, '\\$1');
    }
    String.prototype.trim = function() {
        return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
    };
    function curTop(obj) {
        toreturn = 0;
        while (obj) {
            toreturn += obj.offsetTop;
            obj = obj.offsetParent;
        }
        return toreturn;
    }
    function curLeft(obj) {
        toreturn = 0;
        while (obj) {
            toreturn += obj.offsetLeft;
            obj = obj.offsetParent;
        }
        return toreturn;
    }
    function isNumber(a) {
        return typeof a == 'number' && isFinite(a);
    }
    function replaceHTML(obj, text) {
        while (el = obj.childNodes[0]) {
            obj.removeChild(el);
        };
        obj.appendChild(document.createTextNode(text));
    }

    function actx(obj, ca) {
        /* ---- Public Variables ---- */
    
        this.actx_timeOut = -1; // Autocomplete Timeout in ms (-1: autocomplete never time out)
        this.actx_lim = 4;    // Number of elements autocomplete can show (-1: no limit)
        this.actx_firstText = false; // should the auto complete be limited to the beginning of keyword?
        this.actx_mouse = true; // Enable Mouse Support
        this.actx_delimiter = new Array(';', ',');  // Delimiter for multiple autocomplete. Set it to empty array for single autocomplete
        this.actx_startcheck = 1; // Show widget only after this number of characters is typed in.
        /* ---- Public Variables ----#2895a7   #FFFFFF  #f9f9f9 */

        /* --- Styles --- */
      this.actx_bgColor = '#E0E0E0';
        this.actx_textColor = '#2895a7';
        this.actx_hColor = '#FFFFFF';
        this.actx_fFamily = 'Tahoma';	
        this.actx_fSize = '13px';
        this.actx_hStyle = 'font-weight:bold';
        /* --- Styles --- */

        /* ---- Private Variables ---- */
        var actx_delimwords = new Array();
        var actx_cdelimword = 0;
        var actx_delimchar = new Array();
        var actx_display = false;
        var actx_pos = 0;
        var actx_total = 0;
        var actx_curr = null;
        var actx_rangeu = 0;
        var actx_ranged = 0;
        var actx_bool = new Array();
        var actx_pre = 0;
        var actx_toid;
        var actx_tomake = false;
        var actx_getpre = "";
        var actx_mouse_on_list = 1;
        var actx_kwcount = 0;
        var actx_caretmove = false;
        this.actx_keywords = new Array();
        /* ---- Private Variables---- */

        this.actx_keywords = ca;
        var actx_self = this;

        actx_curr = obj;

        addEvent(actx_curr, "focus", actx_setup);
        function actx_setup() {
            addEvent(document, "keydown", actx_checkkey);
            addEvent(actx_curr, "blur", actx_clear);
            addEvent(document, "keypress", actx_keypress);
        }

        function actx_clear(evt) {
            if (!evt) evt = event;
            removeEvent(document, "keydown", actx_checkkey);
            removeEvent(actx_curr, "blur", actx_clear);
            removeEvent(document, "keypress", actx_keypress);
            actx_removedisp();
        }
        function actx_parse(n) {
            if (actx_self.actx_delimiter.length > 0) {
                var t = actx_delimwords[actx_cdelimword].trim().addslashes();
                var plen = actx_delimwords[actx_cdelimword].trim().length;
            } else {
                var t = actx_curr.value.addslashes();
                var plen = actx_curr.value.length;
            }
            var tobuild = '';
            var i;

            if (actx_self.actx_firstText) {
                var re = new RegExp("^" + t, "i");
            } else {
                var re = new RegExp(t, "i");
            }
            var p = n.search(re);

            for (i = 0; i < p; i++) {
                tobuild += n.substr(i, 1);
            }
            tobuild += "<font style='" + (actx_self.actx_hStyle) + "'>"
            for (i = p; i < plen + p; i++) {
                tobuild += n.substr(i, 1);
            }
            tobuild += "</font>";
            for (i = plen + p; i < n.length; i++) {
                tobuild += n.substr(i, 1);
            }
            return tobuild;
        }
        function actx_generate() {
            if (document.getElementById('tat_table')) { actx_display = false; document.body.removeChild(document.getElementById('tat_table')); }
            if (actx_kwcount == 0) {
                actx_display = false;
                return;
            }
            a = document.createElement('table');
            a.cellSpacing = '1px';
            a.cellPadding = '2px';
            a.style.position = 'absolute';
            a.style.top = eval(curTop(actx_curr) + actx_curr.offsetHeight) + "px";
            a.style.left = curLeft(actx_curr) + "px";
            a.style.backgroundColor = actx_self.actx_bgColor;
            a.id = 'tat_table';
            document.body.appendChild(a);
            var i;
            var first = true;
            var j = 1;
            if (actx_self.actx_mouse) {
                a.onmouseout = actx_table_unfocus;
                a.onmouseover = actx_table_focus;
            }
            var counter = 0;
            for (i = 0; i < actx_self.actx_keywords.length; i++) {
                if (actx_bool[i]) {
                    counter++;
                    r = a.insertRow(-1);
                    if (first && !actx_tomake) {
                        r.style.backgroundColor = actx_self.actx_hColor;
                        first = false;
                        actx_pos = counter;
                    } else if (actx_pre == i) {
                        r.style.backgroundColor = actx_self.actx_hColor;
                        first = false;
                        actx_pos = counter;
                    } else {
                        r.style.backgroundColor = actx_self.actx_bgColor;
                    }
                    r.id = 'tat_tr' + (j);
                    c = r.insertCell(-1);
                    c.style.color = actx_self.actx_textColor;
                    c.style.fontFamily = actx_self.actx_fFamily;
                    c.style.fontSize = actx_self.actx_fSize;
                    c.innerHTML = actx_parse(actx_self.actx_keywords[i]);
                    c.id = 'tat_td' + (j);
                    c.setAttribute('pos', j);
                    if (actx_self.actx_mouse) {
                        c.style.cursor = 'pointer';
                        c.onclick = actx_mouseclick;
                        c.onmouseover = actx_table_highlight;
                    }
                    j++;
                }
                if (j - 1 == actx_self.actx_lim && j < actx_total) {
                    r = a.insertRow(-1);
                    r.style.backgroundColor = actx_self.actx_bgColor;
                    c = r.insertCell(-1);
                    c.style.color = actx_self.actx_textColor;
                    c.style.fontFamily = 'arial narrow';
                    c.style.fontSize = actx_self.actx_fSize;
                    c.align = 'center';
                    replaceHTML(c, '\\/');
                    if (actx_self.actx_mouse) {
                        c.style.cursor = 'pointer';
                        c.onclick = actx_mouse_down;
                    }
                    break;
                }
            }
            actx_rangeu = 1;
            actx_ranged = j - 1;
            actx_display = true;
            if (actx_pos <= 0) actx_pos = 1;
        }
        function actx_remake() {
            document.body.removeChild(document.getElementById('tat_table'));
            a = document.createElement('table');
            a.cellSpacing = '1px';
            a.cellPadding = '2px';
            a.style.position = 'absolute';
            a.style.top = eval(curTop(actx_curr) + actx_curr.offsetHeight) + "px";
            a.style.left = curLeft(actx_curr) + "px";
            a.style.backgroundColor = actx_self.actx_bgColor;
            a.id = 'tat_table';
            if (actx_self.actx_mouse) {
                a.onmouseout = actx_table_unfocus;
                a.onmouseover = actx_table_focus;
            }
            document.body.appendChild(a);
            var i;
            var first = true;
            var j = 1;
            if (actx_rangeu > 1) {
                r = a.insertRow(-1);
                r.style.backgroundColor = actx_self.actx_bgColor;
                c = r.insertCell(-1);
                c.style.color = actx_self.actx_textColor;
                c.style.fontFamily = 'arial narrow';
                c.style.fontSize = actx_self.actx_fSize;
                c.align = 'center';
                replaceHTML(c, '/\\');
                if (actx_self.actx_mouse) {
                    c.style.cursor = 'pointer';
                    c.onclick = actx_mouse_up;
                }
            }
            for (i = 0; i < actx_self.actx_keywords.length; i++) {
                if (actx_bool[i]) {
                    if (j >= actx_rangeu && j <= actx_ranged) {
                        r = a.insertRow(-1);
                        r.style.backgroundColor = actx_self.actx_bgColor;
                        r.id = 'tat_tr' + (j);
                        c = r.insertCell(-1);
                        c.style.color = actx_self.actx_textColor;
                        c.style.fontFamily = actx_self.actx_fFamily;
                        c.style.fontSize = actx_self.actx_fSize;
                        c.innerHTML = actx_parse(actx_self.actx_keywords[i]);
                        c.id = 'tat_td' + (j);
                        c.setAttribute('pos', j);
                        if (actx_self.actx_mouse) {
                            c.style.cursor = 'pointer';
                            c.onclick = actx_mouseclick;
                            c.onmouseover = actx_table_highlight;
                        }
                        j++;
                    } else {
                        j++;
                    }
                }
                if (j > actx_ranged) break;
            }
            if (j - 1 < actx_total) {
                r = a.insertRow(-1);
                r.style.backgroundColor = actx_self.actx_bgColor;
                c = r.insertCell(-1);
                c.style.color = actx_self.actx_textColor;
                c.style.fontFamily = 'arial narrow';
                c.style.fontSize = actx_self.actx_fSize;
                c.align = 'center';
                replaceHTML(c, '\\/');
                if (actx_self.actx_mouse) {
                    c.style.cursor = 'pointer';
                    c.onclick = actx_mouse_down;
                }
            }
        }
        function actx_goup() {
            if (!actx_display) return;
            if (actx_pos == 1) return;
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_bgColor;
            actx_pos--;
            if (actx_pos < actx_rangeu) actx_moveup();
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_hColor;
            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
        }
        function actx_godown() {
            if (!actx_display) return;
            if (actx_pos == actx_total) return;
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_bgColor;
            actx_pos++;
            if (actx_pos > actx_ranged) actx_movedown();
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_hColor;
            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
        }
        function actx_movedown() {
            actx_rangeu++;
            actx_ranged++;
            actx_remake();
        }
        function actx_moveup() {
            actx_rangeu--;
            actx_ranged--;
            actx_remake();
        }

        /* Mouse */
        function actx_mouse_down() {
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_bgColor;
            actx_pos++;
            actx_movedown();
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_hColor;
            actx_curr.focus();
            actx_mouse_on_list = 0;
            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
        }
        function actx_mouse_up(evt) {
            if (!evt) evt = event;
            if (evt.stopPropagation) {
                evt.stopPropagation();
            } else {
                evt.cancelBubble = true;
            }
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_bgColor;
            actx_pos--;
            actx_moveup();
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_hColor;
            actx_curr.focus();
            actx_mouse_on_list = 0;
            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
        }
        function actx_mouseclick(evt) {
            if (!evt) evt = event;
            if (!actx_display) return;
            actx_mouse_on_list = 0;
            actx_pos = this.getAttribute('pos');
            actx_penter();
        }
        function actx_table_focus() {
            actx_mouse_on_list = 1;
        }
        function actx_table_unfocus() {
            actx_mouse_on_list = 0;
            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
        }
        function actx_table_highlight() {
            actx_mouse_on_list = 1;
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_bgColor;
            actx_pos = this.getAttribute('pos');
            while (actx_pos < actx_rangeu) actx_moveup();
            while (actx_pos > actx_ranged) actx_movedown();
            document.getElementById('tat_tr' + actx_pos).style.backgroundColor = actx_self.actx_hColor;
            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
        }
        /* ---- */

        function actx_insertword(a) {
            if (actx_self.actx_delimiter.length > 0) {
                str = '';
                l = 0;
                for (i = 0; i < actx_delimwords.length; i++) {
                    if (actx_cdelimword == i) {
                        prespace = postspace = '';
                        gotbreak = false;
                        for (j = 0; j < actx_delimwords[i].length; ++j) {
                            if (actx_delimwords[i].charAt(j) != ' ') {
                                gotbreak = true;
                                break;
                            }
                            prespace += ' ';
                        }
                        for (j = actx_delimwords[i].length - 1; j >= 0; --j) {
                            if (actx_delimwords[i].charAt(j) != ' ') break;
                            postspace += ' ';
                        }
                        str += prespace;
                        str += a;
                        l = str.length;
                        if (gotbreak) str += postspace;
                    } else {
                        str += actx_delimwords[i];
                    }
                    if (i != actx_delimwords.length - 1) {
                        str += actx_delimchar[i];
                    }
                }
                actx_curr.value = str;
                setCaret(actx_curr, l);
            } else {
                actx_curr.value = a;
            }
            actx_mouse_on_list = 0;
            actx_removedisp();
        }
        function actx_penter() {
            if (!actx_display) return;
            actx_display = false;
            var word = '';
            var c = 0;
            for (var i = 0; i <= actx_self.actx_keywords.length; i++) {
                if (actx_bool[i]) c++;
                if (c == actx_pos) {
                    word = actx_self.actx_keywords[i];
                    break;
                }
            }
            actx_insertword(word);
            l = getCaretStart(actx_curr);
        }
        function actx_removedisp() {
            if (actx_mouse_on_list == 0) {
                actx_display = 0;
                if (document.getElementById('tat_table')) { document.body.removeChild(document.getElementById('tat_table')); }
                if (actx_toid) clearTimeout(actx_toid);
            }
        }
        function actx_keypress(e) {
            if (actx_caretmove) stopEvent(e);
            return !actx_caretmove;
        }
        function actx_checkkey(evt) {
            if (!evt) evt = event;
            a = evt.keyCode;
            caret_pos_start = getCaretStart(actx_curr);
            actx_caretmove = 0;
            switch (a) {
                case 38:
                    actx_goup();
                    actx_caretmove = 1;
                    return false;
                    break;
                case 40:
                    actx_godown();
                    actx_caretmove = 1;
                    return false;
                    break;
                case 13: case 9:
                    if (actx_display) {
                        actx_caretmove = 1;
                        actx_penter();
                        return false;
                    } else {
                        return true;
                    }
                    break;
                default:
                    setTimeout(function() { actx_tocomplete(a) }, 50);
                    break;
            }
        }

        function actx_tocomplete(kc) {
            if (kc == 38 || kc == 40 || kc == 13) return;
            var i;
            if (actx_display) {
                var word = 0;
                var c = 0;
                for (var i = 0; i <= actx_self.actx_keywords.length; i++) {
                    if (actx_bool[i]) c++;
                    if (c == actx_pos) {
                        word = i;
                        break;
                    }
                }
                actx_pre = word;
            } else { actx_pre = -1 };

            if (actx_curr.value == '') {
                actx_mouse_on_list = 0;
                actx_removedisp();
                return;
            }
            if (actx_self.actx_delimiter.length > 0) {
                caret_pos_start = getCaretStart(actx_curr);
                caret_pos_end = getCaretEnd(actx_curr);

                delim_split = '';
                for (i = 0; i < actx_self.actx_delimiter.length; i++) {
                    delim_split += actx_self.actx_delimiter[i];
                }
                delim_split = delim_split.addslashes();
                delim_split_rx = new RegExp("([" + delim_split + "])");
                c = 0;
                actx_delimwords = new Array();
                actx_delimwords[0] = '';
                for (i = 0, j = actx_curr.value.length; i < actx_curr.value.length; i++, j--) {
                    if (actx_curr.value.substr(i, j).search(delim_split_rx) == 0) {
                        ma = actx_curr.value.substr(i, j).match(delim_split_rx);
                        actx_delimchar[c] = ma[1];
                        c++;
                        actx_delimwords[c] = '';
                    } else {
                        actx_delimwords[c] += actx_curr.value.charAt(i);
                    }
                }

                var l = 0;
                actx_cdelimword = -1;
                for (i = 0; i < actx_delimwords.length; i++) {
                    if (caret_pos_end >= l && caret_pos_end <= l + actx_delimwords[i].length) {
                        actx_cdelimword = i;
                    }
                    l += actx_delimwords[i].length + 1;
                }
                var ot = actx_delimwords[actx_cdelimword].trim();
                var t = actx_delimwords[actx_cdelimword].addslashes().trim();
            } else {
                var ot = actx_curr.value;
                var t = actx_curr.value.addslashes();
            }
            if (ot.length == 0) {
                actx_mouse_on_list = 0;
                actx_removedisp();
            }
            if (ot.length < actx_self.actx_startcheck) return this;
            if (actx_self.actx_firstText) {
                var re = new RegExp("^" + t, "i");
            } else {
                var re = new RegExp(t, "i");
            }

            actx_total = 0;
            actx_tomake = false;
            actx_kwcount = 0;
            for (i = 0; i < actx_self.actx_keywords.length; i++) {
                actx_bool[i] = false;
                if (re.test(actx_self.actx_keywords[i])) {
                    actx_total++;
                    actx_bool[i] = true;
                    actx_kwcount++;
                    if (actx_pre == i) actx_tomake = true;
                }
            }

            if (actx_toid) clearTimeout(actx_toid);
            if (actx_self.actx_timeOut > 0) actx_toid = setTimeout(function() { actx_mouse_on_list = 0; actx_removedisp(); }, actx_self.actx_timeOut);
            actx_generate();
        }
        return this;
    }
