﻿Type.registerNamespace("Framework.Controls");
Framework.Controls.TextBoxCompleteExtender = function(element) {
    Framework.Controls.TextBoxCompleteExtender.initializeBase(this, [element]);
    this._keyupHandler = Function.createDelegate(this, this._onKeyUp);
    this._completeHandler = Function.createDelegate(this, this.complete);
    this._hideHandler = Function.createDelegate(this, this._hide);
    this._Items = [];
    this._timeoutid = null;
    this._delay = 300;
    this._value = null;
    this._minLength = 3;
    this._bounds = null;
    this._UI = null;
    this._CssClass = "TextBoxComplete";
    this._Cache = new Object();
    this._ServiceMethod = null;
    this._AutoSubmitID = null;
    this._SubmitURL = null;
    this._el = null;
    this._MatchFoundText = null;
    this._NoMatchFoundText = null;
    this._ResultHighlight = true;
    this._windowResizeHandler = Function.createDelegate(this, this._windowResize);
    this._MinWidth = 0;
    this._Params = "";
};
Framework.Controls.TextBoxCompleteExtender.prototype =
{
    get_CssClass: function() { return this._CssClass; },
    set_CssClass: function(value) { this._CssClass = value; },
    get_ServiceMethod: function() { return this._ServiceMethod; },
    set_ServiceMethod: function(value) { this._ServiceMethod = value; },
    get_AutoSubmitID: function() { return this._AutoSubmitID; },
    set_AutoSubmitID: function(value) { this._AutoSubmitID = value; },
    get_SubmitURL: function() { return this._SubmitURL; },
    set_SubmitURL: function(value) { this._SubmitURL = value; },
    get_MatchFoundText: function() { return this._MatchFoundText; },
    set_MatchFoundText: function(value) { this._MatchFoundText = value; },
    get_NoMatchFoundText: function() { return this._NoMatchFoundText; },
    set_NoMatchFoundText: function(value) { this._NoMatchFoundText = value; },
    get_Delay: function() { return this._delay; },
    set_Delay: function(value) { this._delay = value; },
    get_MinWidth: function() { return this._MinWidth; },
    set_MinWidth: function(value) { this._MinWidth = value; },
    get_Params: function() { return this._Params; },
    set_Params: function(value) { this._Params = value; },

    initialize: function() {
        Framework.Controls.TextBoxCompleteExtender.callBaseMethod(this, "initialize");
        this._el = this.get_element();
        $addHandler(this._el, "keyup", this._keyupHandler);
        $addHandler(document, "click", this._hideHandler);
        $addHandler(window, "resize", this._windowResizeHandler);
    },
    dispose: function() {
        $removeHandler(this._el, "keyup", this._keyupHandler);
        $removeHandler(document, "click", this._hideHandler);
        $removeHandler(window, "resize", this._windowResizeHandler);
        if (this._timeoutid) clearTimeout(this._timeoutid);
        this._timeoutid = null;
        Framework.Controls.TextBoxCompleteExtender.callBaseMethod(this, "dispose");
    },
    _onKeyUp: function() {
        if (this._timeoutid) {
            clearTimeout(this._timeoutid);
            this._timeoutid = null;
        }
        this._timeoutid = setTimeout(this._completeHandler, this._delay);
    },
    complete: function() {
        this._value = this._getKeyword();
        if (this._value != "" && this._value.length >= this._minLength) {
            this._loadData();
        } else {
            this._hideData();
        }
    },
    select: function(value) {
        if (value) this._el.value = value;
        else this._el.value = this._value;
        this.hide();
        if (this._AutoSubmitID) {
            eval(this._AutoSubmitID);
            return;
        }
        if (this._SubmitURL) {
            window.location = this._SubmitURL + this._el.value;
        }
    },
    _getKeyword: function() {
        return this._el.value;
    },
    _hide: function(ev) {
        if (!this._UI) return;
        var scroll = Utils.getScrollOffset(document.body, true);
        var cursor = { width: 5, height: 5, x: ev.clientX, y: ev.clientY };
        var UIbounds = Sys.UI.DomElement.getBounds(this._UI);

        if (Utils.overlaps(cursor, this._bounds)) return;
        if (Utils.overlaps(cursor, UIbounds)) return;
        this.hide();
    },
    hide: function() {
        this._hideData();
    },
    _windowResize: function() {
        if (this._UI) {
            this._bounds = Sys.UI.DomElement.getBounds(this._el);
            if (this._MinWidth > 0 && this._bounds.width < this._MinWidth) this._bounds.width = this._MinWidth;
            this._UI.style.width = this._bounds.width + "px";
            Sys.UI.DomElement.setLocation(this._UI, this._bounds.x, this._bounds.y + this._bounds.height);
        }
    },
    _loadData: function() {
        if (this._timeoutid) clearTimeout(this._timeoutid);
        if (!this._ServiceMethod) return;
        var key = this._getKeyword() + this._Params;

        if (this._webRequest) {
            this._webRequest.get_executor().abort();
            this._webRequest = null;
        }

        if (this._Cache && this._Cache[key]) {
            this._Items = this._Cache[key];
            // Delay show data, to override hide when called "complete" from outside the extender
            setTimeout(Function.createDelegate(this, this._showData), 50);
        } else {
            this._webRequest = Services.Public.AjaxCallShort(
                        this._ServiceMethod,
                        new Array(this._value, this._Params),
                        Function.createDelegate(this, this._loadDataCallback)
                    );
        }
    },
    _loadDataCallback: function(result, e) {
        var key = this._getKeyword() + this._Params;
        this._Cache[key] = result;
        this._Items = result;
        this._webRequest = null;
        this._showData();
    },
    _showData: function() {
        this._bounds = Sys.UI.DomElement.getBounds(this._el);

        if (!this._UI) {
            this._UI = document.createElement("div");
            this._UI.className = this._CssClass;
            this._UI.style.position = "absolute";
            this._el.parentNode.appendChild(this._UI);
        } else {
            this._UI.innerHTML = "";
            this._UI.style.height = "";
            this._UI.style.display = "";
        }

        this._UI.style.zIndex = 10000;
        this._UI.style.overflowX = "hidden";
        if (this._MinWidth > 0 && this._bounds.width < this._MinWidth) this._bounds.width = this._MinWidth;
        this._UI.style.width = this._bounds.width + "px";
        Sys.UI.DomElement.setLocation(this._UI, this._bounds.x, this._bounds.y + this._bounds.height);

        if (this._Items && this._Items.length > 0) {
            if (this._MatchFoundText) {
                var info = document.createElement("span");
                info.innerHTML = this._MatchFoundText;
                this._UI.appendChild(info);
            }

            var keys = this._value.replace(/\"/g, "").toUpperCase().split(' ');
            for (var i = 0; i < this._Items.length; i++) {
                var rsp = document.createElement("a");

                if (this._Items[i].value) {
                    rsp.href = "javascript:$find('" + this.get_id() + "').select('" + this._Items[i].value + "')";
                    rsp.innerHTML = this._Items[i].name.toLowerCase();
                } else {
                    rsp.href = "javascript:$find('" + this.get_id() + "').select('" + this._Items[i] + "')";
                    rsp.innerHTML = this._Items[i].toLowerCase();
                }

                // Higlight search string in results
                if (this._ResultHighlight) {
                    var val = rsp.innerHTML.toUpperCase();
                    for (var j = 0; j < keys.length; j++) {
                        var key = keys[j].toLowerCase();
                        rsp.innerHTML = rsp.innerHTML.replace(key, "<b>" + key + "</b>");
                    }
                }

                rsp.style.display = "block";
                rsp.style.width = "100%";
                rsp.className = this._CssClass + "Link";
                this._UI.appendChild(rsp);
            }
        } else {
            if (this._NoMatchFoundText) {
                var info = document.createElement("span");
                info.innerHTML = this._NoMatchFoundText;
                this._UI.appendChild(info);
            } else {
                this._hideData();
                return;
            }
        }

        var UIbounds = Sys.UI.DomElement.getBounds(this._UI);
        if (UIbounds.height > 200) {
            this._UI.style.overflow = "auto";
            this._UI.style.overflowY = "scroll";
            this._UI.style.overflowX = "hidden";
            this._UI.style.height = "200px";
        }
    },
    _hideData: function() {
        if (this._UI) {
            this._UI.style.display = "none";
            this._UI.innerHTML = "";
        }
    }
}
Framework.Controls.TextBoxCompleteExtender.registerClass('Framework.Controls.TextBoxCompleteExtender', AjaxControlToolkit.BehaviorBase);
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();