﻿
Type.registerNamespace('BIT.WebControls');

BIT.WebControls.DropDownEditClickEventArgs = function(itemValue) {
    this._itemValue = itemValue;
};


BIT.WebControls.DropDownEditClickEventArgs.prototype =
{
    get_itemValue: function() {
        return this._itemValue;
    },

    set_itemValue: function(value) {
        this._itemValue = value;
    }
};

BIT.WebControls.DropDownEditClickEventArgs.registerClass('BIT.WebControls.DropDownEditClickEventArgs', Sys.EventArgs);


BIT.WebControls.DropDownEdit = function(element) {
    BIT.WebControls.DropDownEdit.initializeBase(this, [element]);

    this.addProperty('text', null);
    this.addProperty('selectedValue', null);

    this.addProperty('selectedIndexField', null);

    this.addProperty('dropImageUrl', null);
    this.addProperty('dropHoverImageUrl', null);
    this.addProperty('dropClickedImageUrl', null);

    this.addProperty('cssClass', null);

    this.addProperty('controlCssClass', null);
    this.addProperty('textCssClass', null);

    this.addProperty('dropBlockCssClass', null);
    this.addProperty('selectedItemCssClass', null);
    this.addProperty('disabledItemCssClass', null);
    this.addProperty('itemCssClass', null);

    this.addProperty('dropBlockWidth', null);
    this.addProperty('dropBlockHeight', null);

    this.addProperty('dropped', false);
    this.addProperty('readOnly', false);
    this.addProperty('autoSuggest', false);
    this.addProperty('autoPostBack', false);

    this.addProperty('useIframe', (Sys.Browser.agent === Sys.Browser.InternetExplorer) && (Sys.Browser.version < 7));

    this.addProperty('animationType', BIT.WebControls.AnimationType.exp);
    this.addProperty('animationLength', 35);

    this.addProperty('maxLength', null);

    this.addProperty('selectedIndex', null);

    this.addProperty('uniqueID', null);

    this.addProperty('items', []);

    this.addEvent('itemClick');

    this._animator = null;

    this._href = null;
    this._input = null;
    this._text = null;

    this._block = null;
    this._cursorIndex = null;
    this._cursorValue = null;
    this._cursorRow = null;

    this._selectedValue = null;

    this._blockHeight = 0;

    this._postbackPending = false;
}

BIT.WebControls.DropDownEdit.prototype =
{
    set_useIframe: function(value) {
        if (this.get_isInitialized())
            throw Error.invalidOperation();

        this.useIframe = value;
    },

    get_inputValue: function() {
        return this._input.value;
    },

    set_selectedIndex: function(value) {
        if (value === 0)
            value = 0;
        else if ((!value) || (value < 0))
            value = -1;

        if (this.get_items().length <= value)
            return;

        if (this.selectedIndex == value)
            return;

        if (this.get_isInitialized()) {
            if (this.selectedIndexField)
                this.selectedIndexField.value = value;
        }

        this._selectedValue = (value >= 0) ? this.items[value].text : null;
        this.selectedIndex = value;
    },

    set_maxLength: function(value) {
        if (this.maxLength == value)
            return;

        this.maxLength = value;

        if (this._input && !this.readOnly)
            this._input.maxLength = (value || null);

    },

    set_textCssClass: function(value) {
        if (this.textCssClass == value)
            return;

        this.textCssClass = value;

        if (this._text)
            this._text.className = (value || '');
    },

    set_controlCssClass: function(value) {
        if (this.controlCssClass == value)
            return;

        this.controlCssClass = value;

        if (this._input && !this.readOnly)
            this._input.className = (value || '');
    },

    get_items: function() {
        if (!this.items)
            this.items = [];

        return this.items;
    },

    get_dropBlockWidth: function() {
        if (!this.dropBlockWidth && this.dropBlockWidth !== 0)
            this.dropBlockWidth = -1;

        return this.dropBlockWidth;
    },

    get_dropBlockHeight: function() {
        if (!this.dropBlockHeight && this.dropBlockHeight !== 0)
            this.dropBlockHeight = -1;

        return this.dropBlockHeight;
    },

    set_dropped: function(value) {
        if (this.dropped == value)
            return;

        if (this.get_isInitialized()) {
            var img = this._href.childNodes[0];

            if (value) {
                if (!this._block) {
                    this.dropping = true;
                    this._renderItems(this.get_items());
                    this.dropping = false;
                }


                var elm = this.get_element();

                var bounds = $getBounds((typeof (Sys.UI.DomElement.getAttribute(elm, 'adapted')) == 'undefined') ? elm : elm.offsetParent);

                if (bounds.width == 0 || bounds.height == 0)
                    return;

                bounds.y = bounds.y + bounds.height;

                var tmpw = (this.get_dropBlockWidth() < 0 ? bounds.width : this.get_dropBlockWidth());

                with (this._block.style) {
                    top = bounds.y + 'px';
                    left = bounds.x + 'px';
                    width = tmpw + 'px';
                    height = '1px';
                }

                this._block.style.display = 'block';

                this._block.className = (this.dropBlockCssClass || '');

                this._blockHeight = Math.min((this.get_dropBlockHeight() < 0 ? bounds.height : this.get_dropBlockHeight()), this._block.scrollHeight);


                this._block.style.overflow = (this._blockHeight < this._block.scrollHeight) ? 'auto' : 'hidden';

                if (this.dropClickedImageUrl)
                    img.src = this.dropClickedImageUrl;

                this._cursorIndex = this._prevIndex = this.selectedIndex;
                this._cursorValue = this._prevValue = this._input.value;
                this._cursorRow = this._getRow(this.selectedIndex);

                this._updateRowLook(this._cursorRow);
                this._adjustRowPos(this._cursorRow, new Sys.UI.Bounds(bounds.x, bounds.y, tmpw, this._blockHeight));
            }
            else {
                if (value === null) {
                    if (this.dropHoverImageUrl)
                        img.src = this.dropHoverImageUrl;
                }
                else if (value === false) {
                    if (this.dropImageUrl)
                        img.src = this.dropImageUrl;
                }

                this._cursorIndex = this._prevIndex = null;
                this._cursorValue = this._prevValue = null;

                this._updateRowLook(this._cursorRow);
                this._cursorRow = null;

                this._prevPos = null;
            }

            this._focusElement();

            if (!this.dropping) {
                this._animator.set_reverse(this.dropped);
                this._animator.set_steps(this.animationLength / this._animator.get_delay());
                this._animator.set_type(this.animationType);

                this._animator.start();
            }
        }

        this.dropped = value;
    },

    _setInputValue: function(value) {
        this._input.value = (value || '');
        this._text.childNodes[0].innerHTML = this._input.value.escapeHTML();

        if (typeof (this._input.Validators) != 'undefined')
            ValidatorOnChange({ target: this._input });
    },

    _dropImgOver: function(evt) {
        if (this.dropHoverImageUrl)
            this._href.childNodes[0].src = this.dropHoverImageUrl;
    },

    _dropImgOut: function(evt) {
        var img = this._href.childNodes[0];

        if (this.dropped && this.dropClickedImageUrl)
            img.src = this.dropClickedImageUrl;
        else if (this.dropImageUrl)
            img.src = this.dropImageUrl;
    },

    _dropImgDown: function(evt) {
        this.set_dropped(this.dropped ? null : true);
    },


    _documentDown: function(evt) {
        if (!this.dropped)
            return;

        var tgt = evt.target
        var hcell = this._href.parentNode;
        var icell = this._input.parentNode;

        while (tgt) {
            if ((tgt == hcell) || (tgt == this._block) || (this.readOnly && (tgt == icell)))
                return;

            tgt = tgt.parentNode;
        }

        this.set_dropped(false);
    },

    _skipEvent: function(evt) {
        evt.preventDefault();
        evt.stopPropagation();
    },

    _dropImgChange: function(evt) {
        if (!this.dropped && (this.selectedIndex >= 0) && (this._input.value != this._selectedValue))
            this.set_selectedIndex(-1);
    },

    _dropImgKeyUp: function(evt) {
        if (!evt.ctrlKey && !evt.altKey) {
            var keyCode = evt.keyCode;

            if (keyCode == 27)
                this._skipEvent(evt);

            if (!(keyCode < 32 || (keyCode >= 33 && keyCode <= 46) || (keyCode >= 112 && keyCode <= 123))) {
                if (this.dropped && (this._prevValue != this._input.value)) {
                    this._prevIndex = -1;
                    this._prevValue = this._input.value;
                }

                if (this.autoSuggest)
                    this._findSuggestion((this.readOnly) ? String.fromCharCode(keyCode) : this._input.value);
            }
        }

        this._dropImgChange(evt);
    },


    _dropTextDown: function(evt) {
        this.set_dropped(this.dropped ? false : true);
    },

    _elementKeyPress: function(evt) {
        var keyCode = evt.charCode;

        if (!evt.ctrlKey && !evt.shiftKey) {
            if ((keyCode == 27) || (keyCode == 13 && this.dropped)) {
                this.set_dropped(false);
                this._skipEvent(evt);

                if ((keyCode != 27) && this.autoPostBack)
                    this._raisePostBack();
            }
        }
    },

    _focusElement: function() {
        try {
            if (this.readOnly) {
                if (this._text.focus)
                    this._text.focus();
            }
            else {
                if (this._input.focus)
                    this._input.focus();
            }
        }
        catch (e) {
        }
    },

    _dropImgKeyDownSkip: function(evt) {
        if (Sys.Browser.agent !== Sys.Browser.InternetExplorer)
            this._skipEvent(evt);

        if (this.readOnly || ((this._input != evt.target) && (Sys.Browser.agent === Sys.Browser.InternetExplorer))) {
            this._skipEvent(evt);
            this.set_dropped(false);
        }
    },

    _dropImgKeyDown: function(evt) {
        var keyCode = evt.keyCode;


        if (!evt.ctrlKey && !evt.shiftKey) {
            if (evt.altKey) {
                if (keyCode == 40)
                    this.set_dropped(true);
                else if (keyCode == 38)
                    this.set_dropped(false);
            }
            else {
                if (this.dropped) {
                    switch (keyCode) {
                        case 27:
                            {
                                this.set_selectedIndex(this._prevIndex);
                                this._setInputValue(this._prevValue);
                                this._dropImgKeyDownSkip(evt);

                                break;
                            }
                        case 9:
                        case 13:
                            {
                                if (this._cursorIndex !== null) {
                                    this.set_selectedIndex(this._cursorIndex);
                                    this._setInputValue(this._cursorValue);
                                }
                                this._dropImgKeyDownSkip(evt);

                                if (keyCode == 9)
                                    this.set_dropped(false);
                                else if (this.autoPostBack)
                                    this._raisePostBack();

                                break;
                            }
                        case 40:
                            {
                                var tmp = (this._cursorIndex > 0 || this._cursorIndex === 0) ? this._cursorIndex + 1 : 0;
                                this._itemMove(null, this._getRow(tmp));

                                this._skipEvent(evt);
                                break;
                            }
                        case 38:
                            {
                                var tmp = (this._cursorIndex > 0 || this._cursorIndex === 0) ? this._cursorIndex - 1 : 0;
                                this._itemMove(null, this._getRow(tmp));
                                this._skipEvent(evt);
                                break;
                            }
                    }
                }
                else if (keyCode == 27) {
                    this._skipEvent(evt);
                }
            }
        }
    },

    _adjustRowPos: function(row, blockBnds) {
        if (row && (typeof (this._block.scrollTop) != 'undefined')) {
            blockBnds = (blockBnds || $getBounds(this._block));
            var rowBnds = $getBounds(row);

            if (rowBnds.y + rowBnds.height >= blockBnds.y + blockBnds.height)
                this._block.scrollTop += (rowBnds.y + rowBnds.height) - (blockBnds.y + blockBnds.height);
            else if (rowBnds.y <= blockBnds.y)
                this._block.scrollTop -= blockBnds.y - rowBnds.y;
        }
    },

    _itemMove: function(evt, row) {
        if (!row)
            return;

        var item = row.item;
        var index = row.itemIndex;

        if (index < 0)
            return;

        var tmp = this._cursorIndex;

        this._cursorIndex = index;
        this._cursorValue = item.text;

        if (tmp == index)
            return;

        if (!evt) {
            this._setInputValue(this._cursorValue);
            this._adjustRowPos(row);
        }
        else {
            evt.preventDefault();
            evt.stopPropagation();
        }
        this._updateRowLook(row);
        this._updateRowLook(this._cursorRow);

        this._cursorRow = row;
    },

    _getRow: function(index) {
        if (!index && (index !== 0))
            return null;

        var rows = this._block.table.rows;

        if ((index < 0) || (index > rows.length - 1))
            return null;

        return rows[index];
    },

    _typeAhead: function(suggestion) {
        if (this._input.createTextRange || this._input.setSelectionRange) {
            var len = this._input.value.length;

            this._setInputValue(suggestion);
            this.selectRange(len, suggestion.length);
        }
    },


    _findSuggestion: function(inpvalue) {
        if (!inpvalue)
            return;

        if (!this._block)
            this._renderItems(this.get_items());

        var rows = this._block.table.rows;

        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];

            var item = row.item;
            var itemIndex = row.itemIndex;

            if (isUndefinedOrTrue(item.enabled) && (item.text || '').toLowerCase().indexOf(inpvalue.toLowerCase()) == 0) {
                this.set_dropped(true);

                var tmp = this._cursorIndex;

                this._cursorIndex = itemIndex;
                this._cursorValue = item.text;

                if (tmp != this._cursorIndex)
                    this._updateRowLook(this._cursorRow);

                this._updateRowLook(row);
                this._adjustRowPos(row);

                if (!this.readOnly)
                    this._typeAhead(item.text);

                this._cursorRow = row;
                return;
            }
        }

        if (this._cursorRow) {
            this._cursorIndex = null;
            this._cursorValue = null;

            this._updateRowLook(this._cursorRow);

            this._cursorRow = null;
        }
    },

    _itemClick: function(evt, row) {
        this.set_selectedIndex(this._cursorIndex);
        this._setInputValue(this._cursorValue);

        if (this._input.select)
            this._input.select();

        this.set_dropped(false);

        if (this.autoPostBack)
            this._raisePostBack();

        this.raiseEvent("itemClick", new BIT.WebControls.DropDownEditClickEventArgs(this._cursorValue));
    },


    _doPostBack: function() {
        __doPostBack(this.get_uniqueID(), '');
    },

    _raisePostBack: function(arg) {
        if ((this._pageRequestManager === null) || (!this._pageRequestManager.get_isInAsyncPostBack())) {
            this._doPostBack();
            this._postbackPending = false;
        }
        else {
            this._postbackPending = true;
        }
    },

    _renderItems: function(items) {
        if (!this._block && !items)
            return;

        var table;
        if (!this._block) {
            table = document.createElement('table');
            table.cellPadding = 0;
            table.cellSpacing = 0;
            table.border = 0;
            table.style.tableLayout = 'fixed';
            table.style.backgroundColor = 'white';

            this._block = document.createElement('div');
            with (this._block.style) {
                overflow = 'hidden';
                position = 'absolute';
                padding = '0';
                margin = '0';
                width = '1px';
                height = '1px';
                zIndex = '100000';
                display = 'none';
            }

            document.body.appendChild(this._block);

            if (Sys.Browser.agent === Sys.Browser.InternetExplorer)
                table.style.width = '';
            else
                table.style.width = '100%';

            if (this.useIframe && !this._block.iframe)
                this._block.iframe = $addIframe(this._block);

            this._block.table = table;
            this._block.appendChild(table);
        }
        else {
            table = this._block.table;
        }


        var dropped = this.dropped;
        this.dropped = !dropped;
        this.set_dropped(dropped);

        if (!items)
            items = [];

        for (var i = 0; i < Math.max(items.length, table.rows.length); i++) {
            var row = (i > table.rows.length - 1) ? table.insertRow(i) : table.rows[i];

            if (row.cells.length == 0) {
                var elm = document.createElement('div');
                with (elm.style) { overflow = 'hidden'; width = '100%'; }

                row.insertCell(-1).appendChild(elm);


                $addContextualHandlers(row, {
                    mouseover: this._itemMove,
                    click: this._itemClick
                }, this, row);

            }

            if (i > items.length - 1) {
                $clearHandlers(row);

                table.deleteRow(i);
                i--;
                continue;
            }

            var item = items[i];
            row.cells[0].childNodes[0].innerHTML = (item.text || '').escapeHTML() + '&nbsp;';

            row.item = item;
            row.itemIndex = i;

            this._updateRowLook(row);
        }
    },

    _updateRowLook: function(row) {
        if (!row)
            return;

        var item = row.item;
        var index = Array.indexOf(this.get_items(), item);

        var className = (isUndefinedOrTrue(item.enabled) || !this.disabledItemCssClass) ? (this.itemCssClass || '') : (this.disabledItemCssClass || '');


        if (isUndefinedOrTrue(item.enabled) && (index == this._cursorIndex))
            className += ' ' + (this.selectedItemCssClass || '');

        row.cells[0].className = className;
    },

    _animStepChanged: function(obj, args) {
        if (this._block) {
            var val = obj.calc(0, 1);

            this._block.style.height = this._blockHeight * val + 'px';

            Sys.UI.DomElement.setOpacity(this._block, val);
        }
    },

    _animStateChanged: function(obj, args) {
        if (this._block) {
            if (args.get_state() == BIT.WebControls.AnimationState.stopped) {
                with (this._block.style) {
                    height = (this.dropped) ? this._blockHeight + 'px' : '1px';
                    display = (this.dropped) ? 'block' : 'none';
                }


                Sys.UI.DomElement.setOpacity(this._block, (this.dropped) ? 1 : 0);
            }
        }
    },

    selectRange: function(iStart, iLength) {
        if (this.readOnly)
            return;

        if (this._input.createTextRange) {
            var range = this._input.createTextRange();
            range.moveStart('character', iStart);
            range.moveEnd('character', iLength - this._input.value.length);
            range.select();
        }
        else if (this._input.setSelectionRange) {
            this._input.setSelectionRange(iStart, iLength);
        }

        this._focusElement();
    },

    initialize: function() {
        BIT.WebControls.DropDownEdit.callBaseMethod(this, 'initialize');

        var elm = this.get_element();
        var row = elm.rows[0];

        this._href = row.cells[1].childNodes[0];
        this._input = row.cells[0].childNodes[0];
        this._text = row.cells[0].childNodes[1];

        this._documentDownDelegate = Function.createDelegate(this, this._documentDown);
        this._skipEventDelegate = Function.createDelegate(this, this._skipEvent);

        this._animStepDelegate = Function.createDelegate(this, this._animStepChanged);
        this._animStateDelegate = Function.createDelegate(this, this._animStateChanged);

        this._animator = $create(BIT.WebControls.Animator);

        this._animator.add_stateChanged(this._animStateDelegate);
        this._animator.add_stepChanged(this._animStepDelegate);

        $addHandler(document, 'mousedown', this._documentDownDelegate);


        var tmp = this.get_selectedIndex();
        this.selectedIndex = !tmp;
        this.set_selectedIndex(tmp);

        elm._object = window[this.get_id()] = this;

        if (Sys.WebForms && Sys.WebForms.PageRequestManager)
            this._pageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
    },

    dispose: function() {
        this.get_element()._object = window[this.get_id()] = null;

        $removeHandler(document, 'mousedown', this._documentDownDelegate);

        this.set_dropped(false);

        this._renderItems(null);

        this._pageRequestManager = null;

        if (this._animator) {
            this._animator.remove_stateChanged(this._animStateDelegate);
            this._animator.remove_stepChanged(this._animStepDelegate);

            this._animator.dispose();
            this._animator = null;
        }

        if (this._block) {
            if (this._block.iframe) {
                $removeFromParent(this._block.iframe);
                this._block.iframe = null;
            }

            if (this._block.table) {
                $removeFromParent(this._block.table);
                this._block.table = null;
            }

            $removeFromParent(this._block);
            this._block = null;
        }



        this._href = null;
        this._input = null;
        this._text = null;

        this._cursorRow = null;

        this.selectedIndexField = null;

        this._animStateDelegate = null;
        this._animStepDelegate = null;

        BIT.WebControls.DropDownEdit.callBaseMethod(this, 'dispose');
    }
}

BIT.WebControls.DropDownEdit.registerClass('BIT.WebControls.DropDownEdit', Sys.UI.Control);
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();