﻿
// Declare a namespace.
Type.registerNamespace("WFControls");

// Define a simplified component.
WFControls.Combobox = function (element) {
    WFControls.Combobox.initializeBase(this, [element]);

    this.options = null;
    this.selectedIndex = -1;
    this.hoverIndex = -1;
    this.autovalidate = false;
    this.sValue = '';
    this.iSize = 20;
    this.bEnabled = true;

    this.divDropdown = null;
    this.tblListItems = null;

    this.containerid = null;
    this.container = null;

    this.buttonid = null;
    this.button = null;

    this.valuename = null;

    this.timeoutid = null;

    this.textchanged = false;

    this.displayas = 'dropdown';
    this.popup = true;
    this.columncount = 1;
}

// Create protytype.
WFControls.Combobox.prototype =
{
    initialize: function () {
        WFControls.Combobox.callBaseMethod(this, 'initialize');

        // other initialization
        var element = this.get_element();
        if (!element) return;

        var parent = element.parentNode;
        var doc = window.document;

        if (this.containerid != null)
            this.container = $get(this.containerid);

        if (this.buttonid != null)
            this.button = $get(this.buttonid);

        if (this.button != null)
            this.button.className = 'cbxButton' + (this.bEnabled ? '' : 'Disabled');

        if (element.type == 'text') {
            this.hiddenValue = doc.createElement('input');
            this.hiddenValue.name = this.valuename;
            this.hiddenValue.setAttribute('type', 'hidden');
            parent.appendChild(this.hiddenValue);
            element.name = null;
        } else if (element.type == 'hidden') {
            this.hiddenValue = element;
        }

        if (this.displayas == 'radiobuttons' || this.displayas == 'list') {
            this.popup = false;
            element.style.display = 'none';
        } else if (this.displayas == 'dropdown') {
            this.popup = true;
        }

        // initialize the value		
        this.selectedIndex = -1;
        this.set_value(this.sValue);

        this._element_onfocus_handler = Function.createDelegate(this, this._element_onFocus);
        this._element_onblur_handler = Function.createDelegate(this, this._element_onBlur);
        this._element_onkeydown_handler = Function.createDelegate(this, this._element_onKeyDown);
        this._element_onkeyup_handler = Function.createDelegate(this, this._element_onKeyUp);
        this._element_onchange_handler = Function.createDelegate(this, this._element_onChange);
        this._element_onclick_handler = Function.createDelegate(this, this.toggleShowListItems);
        this.checkListItemsMoved_handler = Function.createDelegate(this, this.checkListItemsMoved);

        $addHandler(element, 'focus', this._element_onfocus_handler);
        $addHandler(element, 'blur', this._element_onblur_handler);
        $addHandler(element, 'keydown', this._element_onkeydown_handler);
        $addHandler(element, 'keyup', this._element_onkeyup_handler);
        $addHandler(element, 'change', this._element_onchange_handler);
        if (this.autovalidate)
            $addHandler(element, 'click', this._element_onclick_handler);

        this.optionItem_onclick_handler = Function.createDelegate(this, this.optionItem_Click);
        this.optionTD_onmouseover_handler = Function.createDelegate(this, this.optionTD_MouseOver);
        this.optionTD_onmouseout_handler = Function.createDelegate(this, this.optionTD_MouseOut);
        this.refreshSelectedListItem_handler = Function.createDelegate(this, this.refreshSelectedListItem);
        this.mousedown_handler = Function.createDelegate(this, this.onMouseDown);

        if (this.container != null) {
            $addHandlers(this.container, {
                'mouseover': this.container_onMouseOver,
                'mouseout': this.container_onMouseOut
            }, this);
        }

        if (this.button != null) {
            this.button_onClick_handler = Function.createDelegate(this, this.toggleShowListItems);
            $addHandler(this.button, 'click', this.button_onClick_handler);
            $addHandler(this.button, 'mousedown', this.mousedown_handler);
        }

        if (!this.popup)
            this.showListItems();
    },

    dispose: function () {
        this.releaseListItems();

        $clearHandlers(this.get_element());
        if (this.divListItemsContainer != null) $clearHandlers(this.divListItemsContainer);
        if (this.button != null) $clearHandlers(this.button);
        if (this.container != null) $clearHandlers(this.container);

        WFControls.Combobox.callBaseMethod(this, 'dispose');
    },

    /* -- Property Methods -- */

    get_options: function () {
        return this.options;
    },

    get_option: function (index) {
        if (this.options != null && this.options.length > index && index >= 0)
            return this.options[index];
        return null;
    },

    add_option: function (option) {
        var index;

        if (this.options == null) {
            this.options = [option];
            index = 0;
        } else {
            index = this.options.length;
            this.options[index] = option;
        }
        this.refresh_options();
        return index;
    },

    get_options_count: function () {
        if (this.options != null)
            return this.options.length;
        return 0;
    },

    set_options: function (value) {
        this.options = value;
        this.refresh_options();
    },

    clear_options: function () {
        this.options = [];
        this.refresh_options();
    },

    refresh_options: function () {
        if (this.divListItemsContainer != null) {
            if (this.isListItemsContainerVisible()) {
                this.releaseListItems();
                this.createListItems();
                this.showListItems();
            } else {
                this.releaseListItems();
            }
        }
    },

    get_buttonid: function () {
        return this.buttonid;
    },

    set_buttonid: function (value) {
        this.buttonid = value;
    },

    get_button: function () {
        return this.button;
    },

    set_button: function (value) {
        this.button = value;
    },

    get_valuename: function () {
        return this.valuename;
    },

    set_valuename: function (value) {
        this.valuename = value;
    },

    get_containerid: function () {
        return this.containerid;
    },

    set_containerid: function (value) {
        this.containerid = value;
    },

    get_container: function () {
        return this.container;
    },

    set_container: function (value) {
        this.container = value;
    },

    get_autovalidate: function () {
        return this.autovalidate;
    },

    set_autovalidate: function (val) {
        this.autovalidate = val;
        this.get_element().readOnly = this.autovalidate || !this.bEnabled;
    },

    get_displayas: function () {
        return this.displayas;
    },

    set_displayas: function (value) {
        this.displayas = value;
    },

    get_columncount: function () {
        return this.columncount;
    },

    set_columncount: function (value) {
        if (value > 0)
            this.columncount = value;
        else
            this.columncount = 1;
    },

    get_enabled: function () {
        return this.bEnabled;
    },

    set_enabled: function (val) {
        this.bEnabled = val;
        if (this.get_element().type == 'text') {
            this.get_element().readOnly = this.autovalidate || !this.bEnabled;
            this.get_element().disabled = !this.bEnabled;
        }
        if (this.button != null)
            this.button.className = 'cbxButton' + (val ? '' : 'Disabled');
    },

    get_selectedIndex: function () {
        return this.selectedIndex;
    },

    set_selectedIndex: function (val) {
        if (val >= this.options.length) {
            throw new Error("Index Out of Bounds");
        } else {
            if (this.selectedIndex > -1)
                this.blurListItem(this.selectedIndex);
            this.selectedIndex = val;
            this.takeValueFromListItems();
            //				_selectedIndex.fireChange();
            //				_value.fireChange();
        }
    },

    get_value: function () {
        if (this.hiddenValue != null)
            return this.hiddenValue.value;
        else
            return this.sValue;
    },

    set_value: function (val) {
        if (val == null)
            val = "";
        else if (typeof (val) != 'string')
            val = val.toString();

        this.sValue = val;
        this.selectedIndex = -1;

        if (this.hiddenValue != null) {
            this.hiddenValue.value = val;
            var found = false;
            for (var i = 0; i < this.options.length; i++) {
                var itemval = this.options[i].Value;
                if (itemval == val || (itemval != null && itemval.toUpperCase() == val.toUpperCase())) {
                    this.selectedIndex = i;
                    this.hiddenValue.value = itemval;
                    this.sValue = this.options[i].Text;
                    break;
                    // this.options[i].Selected = true;
                } else {
                    // this.options[i].Selected = false;
                }
            }
            this.get_element().value = this.sValue;
        }
    },

    set_svalue: function (val) {
        if (val == null)
            val = "";
        else if (typeof (val) != 'string')
            val = val.toString();

        this.sValue = val;
        this.selectedIndex = -1;

        if (this.hiddenValue != null) {
            this.hiddenValue.value = val;
            var found = false;
            for (var i = 0; i < this.options.length; i++) {
                if (this.options[i].Text.toUpperCase() == val.toUpperCase()) {
                    this.selectedIndex = i;
                    this.hiddenValue.value = this.options[i].Value;
                    this.sValue = this.options[i].Text;
                    break;
                    // this.options[i].Selected = true;
                } else {
                    // this.options[i].Selected = false;
                }
            }
            this.get_element().value = this.sValue;
        }
    },

    get_size: function () {
        return this.iSize;
    },

    set_size: function (val) {
        this.iSize = val;
    },

    /* -- Exposed Event Handlers  -- */

    add_change: function (handler) {
        this.get_events().addHandler('change', handler);
        return this;
    },

    remove_change: function (handler) {
        this.get_events().removeHandler('change', handler);
        return this;
    },

    add_fill: function (handler) {
        this.get_events().addHandler('fill', handler);
        return this;
    },

    remove_fill: function (handler) {
        this.get_events().removeHandler('fill', handler);
        return this;
    },

    fire_fill: function () {
        var h = this.get_events().getHandler('fill');
        if (h) h(this, Sys.EventArgs.Empty);
    },

    add_textchange: function (handler) {
        this.get_events().addHandler('textchange', handler);
        return this;
    },

    remove_textchange: function (handler) {
        this.get_events().removeHandler('textchange', handler);
        return this;
    },

    fire_textchange: function () {
        this.textchanged = true;

        var h = this.get_events().getHandler('textchange');
        if (h) h(this, Sys.EventArgs.Empty);
    },


    /* Event Handlers */

    divListItemsContainer_onMouseOut: function (e) {
        this.selectListItem(this.selectedItem);
        return true;
    },

    divListItemsContainer_onMouseWheel: function (e) {
        this.checkListItems();

        e.cancelBubble = true;
        var iItemsLength = this.tblListItems.cells.length - 1;
        var lastcell = this.optionTD_getCell(iItemsLength);

        var iItemTop = this.getPixelTop(lastcell, "DIV") + lastcell.offsetHeight + 1;
        if (((iItemTop - this.divListItemsContainer.scrollTop) <= 150 && e.wheelDelta <= 0)
                || (this.divListItemsContainer.scrollTop <= 1 && e.wheelDelta >= 0))
            event.returnValue = false;
    },

    container_onMouseOver: function (e) {
        if (!this.bEnabled) return false;
        if (!this.isListItemsContainerVisible()) {
            if (this.button != null)
                this.button.className = 'cbxButtonHover';
        }
    },

    container_onMouseOut: function (e) {
        if (!this.bEnabled) return false;
        if (!this.isListItemsContainerVisible()) {
            if (this.button != null)
                this.button.className = 'cbxButton';
        }
    },

    hideListTimeoutID: null,
    schedule_hideListItemsContainer: function (e) {
        if (this.divListItemsContainer_onblur_handler)
            this.hideListTimeoutID = window.setTimeout(this.divListItemsContainer_onblur_handler, 500);
    },

    cancel_hideListItemsContainer: function (e) {
        if (this.hideListTimeoutID != null) {
            window.clearTimeout(this.hideListTimeoutID);
            this.hideListTimeoutID = null;
        }
    },

    divListItemsContainer_onBlur: function (e) {
        hideListTimeoutID = null;

        var bIsDirty = false;
        this.blurListItem(this.selectedIndex);

        // Hide ListItemsContainer on blur
        this.hideListItems();
    },

    schedule_change: function () {
        this.timeoutid = window.setTimeout(this._element_onchange_handler, 1000); //this.emitChangeEvent();
    },

    cancel_change: function () {
        if (this.timeoutid != null) {
            window.clearTimeout(this.timeoutid);
            this.timeoutid = null;
        }
    },

    elementHasFocus: false,
    elementKeepFocus: false,
    _element_onFocus: function (e) {
        if (!this.elementHasFocus) {
            this.cancel_change();
            try { this.get_element().select(); } catch (ex) { }
            this.elementHasFocus = true;
        }
    },

    _element_onBlur: function (e) {
        if (this.elementHasFocus && this.elementKeepFocus) {
            this.get_element().focus();
            this.elementKeepFocus = false;
        } else {
            this.schedule_hideListItemsContainer();

            this.elementHasFocus = false;
            if (this.textchanged)
                this.schedule_change();
        }
    },

    keepElementFocus: function () {
        if (paj_Chrome && this.elementHasFocus) {
            this.elementKeepFocus = true;
        }
    },

    onMouseDown: function (e) {
        this.keepElementFocus();
    },

    _element_onKeyDown: function (e) {
        this.checkListItems();

        if (!this.isListItemsContainerVisible())
            this.hoverIndex = this.selectedIndex;
        switch (e.keyCode) {
            case 40: // Down Arrow
                if (this.hoverIndex < this.options.length - 1) {
                    this.blurListItem(this.hoverIndex);
                    this.hoverIndex += 1;
                    if (this.isListItemsContainerVisible()) {
                        var cell = this.optionTD_getCell(this.hoverIndex);
                        var iItemTop = this.getPixelTop(cell, "DIV") + cell.offsetHeight + 1;
                        if (iItemTop >= 150)
                            this.divListItemsContainer.scrollTop = this.divListItemsContainer.scrollTop + cell.offsetHeight + 1;
                    }
                    this.selectedIndex = this.hoverIndex;
                    this.takeValueFromListItems();
                    this.schedule_change();
                    e.stopPropagation();
                    e.preventDefault();
                }
                break;
            case 38: // Up Arrow
                if (this.hoverIndex > 0) {
                    this.blurListItem(this.hoverIndex);
                    this.hoverIndex -= 1;
                    if (this.isListItemsContainerVisible()) {
                        var cell = this.optionTD_getCell(this.hoverIndex);
                        if (this.hoverIndex > -1)
                            this.divListItemsContainer.scrollTop = this.getPixelTop(cell, "DIV") - 1;
                    }
                    this.selectedIndex = this.hoverIndex;
                    this.takeValueFromListItems();
                    this.schedule_change();
                    e.stopPropagation();
                    e.preventDefault();
                }
                break;
            case 13:
                var isMidEditing = false;
                var start;

                if (document.selection) { // for IE
                    var seltext = document.selection.createRange().text;
                    var alltext = e.target.createTextRange().text;

                    start = alltext.indexOf(seltext);
                } else if (typeof e.target.selectionStart != 'undefined') { // for FF, Opera etc...
                    start = e.target.selectionStart;
                } else {
                    start = 0;
                }

                if (start && start > 0) {
                    this.get_element().select();
                    this.hideListItems();
                    e.stopPropagation();
                    e.preventDefault();
                    return;
                } else
                    if (this.hoverIndex > -1 && this.isListItemsContainerVisible()) {
                        if (this.selectedIndex != this.hoverIndex) {
                            this.selectedIndex = this.hoverIndex;
                        }
                        var item = this.optionTD_getCell(this.selectedIndex);
                        this.get_element().value = item.innerText;
                        this.get_element().select();
                        if (this.hiddenValue.value != item.value) {
                            this.hiddenValue.value = item.value;
                            this.emitChangeEvent();
                        }
                        this.hideListItems();
                        e.stopPropagation();
                        e.preventDefault();
                        return;
                    }
        }
        if (this.selectedIndex > -1 && e.keyCode != 13)
            this.selectListItem(this.selectedIndex);
    },

    _element_onKeyUp: function (e) {
        if (e.keyCode < 0x2f && e.keyCode != 32 && e.keyCode != 8 && e.keyCode != 46) {
            return;
        }
        var text = this.get_element().value;
        var utext = text.toUpperCase();
        var bMatch = false;
        this.blurListItem(this.selectedIndex);

        this.fire_textchange();

        if (e.target.createTextRange || e.target.setSelectionRange) {
            if (e.keyCode != 8 && e.keyCode != 46) {
                for (var i = 0; i < this.options.length; i++) {
                    var newtxt = this.options[i].Text;
                    if (newtxt != null) {
                        var uopt = newtxt.toUpperCase();
                        if (uopt != utext && 0 == uopt.indexOf(utext) && utext.length > 0) {
                            bMatch = true;

                            this.get_element().value = text + newtxt.substr(text.length);

                            if (e.target.createTextRange) {
                                var txtrange = e.target.createTextRange();
                                txtrange.moveStart("character", text.length);
                                txtrange.select();
                            } else {
                                e.target.setSelectionRange(text.length, newtxt.length);
                            }
                            this.selectedIndex = i;
                            this.hoverIndex = i;
                            if (this.doesListItemsContainerExist())
                                this.divListItemsContainer.scrollTop = this.getPixelTop(this.optionTD_getCell(this.hoverIndex), "DIV") - 1;
                            this.selectListItem(i);
                            if (this.hiddenValue.value != this.options[i].Value) {
                                this.hiddenValue.value = this.options[i].Value;
                            }
                            break;
                        } else if (uopt == utext) {
                            bMatch = true;
                            this.selectedIndex = i;
                            this.hoverIndex = i;
                            if (this.doesListItemsContainerExist())
                                this.divListItemsContainer.scrollTop = this.getPixelTop(this.optionTD_getCell(this.hoverIndex), "DIV") - 1;
                            this.selectListItem(i);
                            if (this.hiddenValue.value != this.options[i].Value) {
                                this.hiddenValue.value = this.options[i].Value;
                            }
                        }
                    }
                }
            }
            if (!bMatch) {
                this.selectedIndex = -1;
                this.hiddenValue.value = this.get_element().value;
            }
        }
    },

    _element_onChange: function (e) {
        if (this.textchanged) {
            //if (this.sValue != this.get_element().value) {
            var value = this.get_element().value;
            this.cancel_change();
            this.set_svalue(value);
            this.emitChangeEvent(e);
            //}
        }
    },

    emitChangeEvent: function (e) {
        this.hideListItems();

        var h = this.get_events().getHandler('change');
        if (h) h(this, Sys.EventArgs.Empty);
    },

    isValid: function () {
        for (var i = 0; i < this.options.length; i++) {
            if (this.options[i].Text.toUpperCase() == this.get_element().value.toUpperCase()) {
                return true;
            }
        }
        return false;
    },

    repaint: function () {
        this.selectedIndex = -1;
        this.createListItems();
        for (var i = 0; i < this.options.length; i++) {
            if (this.get_element().value == this.options[i].Text) {
                this.selectedIndex = i;
                this.hiddenValue.value = this.options[i].Value;
            }
        }
    },

    checkListItems: function () {
        if (this.divListItemsContainer == null)
            this.createListItemsContainer();
        if (this.tblListItems == null)
            this.createListItems();
    },

    releaseListItems: function () {
        if (this.tblListItems != null) {
            for (var i = 0; i < this.tblListItems.rows.count; i++)
                $clearHandlers(this.tblListItems.rows[i].cell[0]);

            this.tblListItems.parentNode.removeChild(this.tblListItems);
            this.tblListItems = null;
        }
    },

    doesListItemsContainerExist: function () {
        return this.divListItemsContainer != null;
    },

    isListItemsContainerVisible: function () {
        return this.doesListItemsContainerExist() && this.divListItemsContainer.style.display == 'block';
    },

    createListItemsContainer: function () {
        var element = this.get_element();
        if (!element) return;

        this.divListItemsContainer = window.document.createElement('div');
        this.divListItemsContainer.setAttribute('UNSELECTABLE', 'on');
        if (this.popup) {
            var parent = element;
            this.divListItemsContainer.className = 'cbxDropDown';
            while (parent.parentNode != null && parent.tagName != 'FORM' && parent.tagName != 'BODY')
                parent = parent.parentNode;
            parent.insertBefore(this.divListItemsContainer, null);

            this.schedule_hideListItemsContainer_handler = Function.createDelegate(this, this.schedule_hideListItemsContainer);
            this.divListItemsContainer_onblur_handler = Function.createDelegate(this, this.divListItemsContainer_onBlur);
            // $addHandler(this.divListItemsContainer, 'blur', this.schedule_hideListItemsContainer_handler);
            this.divListItemsContainer_onmouseout_handler = Function.createDelegate(this, this.divListItemsContainer_onMouseOut);
            $addHandler(this.divListItemsContainer, 'mouseout', this.divListItemsContainer_onmouseout_handler);
        } else {
            element.parentNode.insertBefore(this.divListItemsContainer, element.nextSibling);
        }

        this.divListItemsContainer_onmousewheel_handler = Function.createDelegate(this, this.divListItemsContainer_onMouseWheel);
        $addHandler(this.divListItemsContainer, 'mousewheel', this.divListItemsContainer_onmousewheel_handler);
        $addHandler(this.divListItemsContainer, 'keydown', this._element_onkeydown_handler); // use same handler as element

        $addHandler(this.divListItemsContainer, 'mousedown', this.mousedown_handler);
    },

    createListItems: function () {
        var element = this.get_element();
        if (!element) return;

        this.divListItemsContainer.style.display = 'block';
        this.tblListItems = window.document.createElement('table');
        this.tblListItems.setAttribute('cellspacing', '0');
        this.tblListItems.setAttribute('cellpadding', '0');
        this.tblListItems.setAttribute('UNSELECTABLE', 'on');

        var column = 0;
        var row = 0;
        if (this.options.length > 0) {
            var tr = this.tblListItems.insertRow(row++);

            for (var i = 0; i < this.options.length; i++) {
                var optitem = this.options[i];

                if (column >= this.columncount) {
                    tr = this.tblListItems.insertRow(row++);
                    column = 0;
                }

                var tc = tr.insertCell(column++);
                tc.setAttribute('UNSELECTABLE', 'on');
                tc.className = "cbxItem";

                tc.Value = optitem.Value;
                var text = this.options[i].Text;

                if (this.displayas == 'radiobuttons') {
                    var rb = window.document.createElement('input');
                    rb.name = this.hiddenValue.name + '$rb';
                    rb.value = tc.Value;
                    rb.type = 'radio';
                    rb.id = element.id + '_rb' + i.toString();
                    rb.disabled = !this.bEnabled;

                    //                    if (i == this.selectedIndex)
                    //                        rb.selected = true;
                    //                        
                    $addHandler(rb, "click", this.optionItem_onclick_handler);
                    //rb.onclick = function(dome) { var e = new Sys.UI.DomEvent(dome ? dome : event); e.preventDefault(); e.stopPropagation(); return e.returnValue; }
                    tc.appendChild(rb);

                    if (text == '' || text == null)
                        ;
                    else {
                        var label = window.document.createElement('label');
                        label.htmlFor = rb.id;
                        if (Sys.Browser.agent !== Sys.Browser.Firefox)
                            label.innerText = text;
                        else
                            label.textContent = text;

                        label.onclick = function () { return true; }
                        tc.appendChild(label);
                    }
                } else
                    tc.innerHTML = (text == '' || text == null) ? '&nbsp;' : text;

                tc.style.color = (this.options[i].Color != null ? this.options[i].Color : "black");

                if (typeof (optitem.Enabled) === 'undefined' || optitem.Enabled) {
                    $addHandler(tc, "click", this.optionItem_onclick_handler);
                    $addHandler(tc, "mouseover", this.optionTD_onmouseover_handler);
                    $addHandler(tc, "mouseout", this.optionTD_onmouseout_handler);
                }

                if (i == this.selectedIndex) {
                    //this.selectedIndex = i;
                    this.selectListItem(i);
                }
            }
        } else {
        }

        this.divListItemsContainer.appendChild(this.tblListItems);

        if (this.popup) {
            this.divListItemsContainer.className = 'clsDropDownDiv';
            this.tblListItemsWidth = this.tblListItems.offsetWidth;
            this.tblListItems.style.width = '100%';

            if (this.tblListItems.offsetHeight > 150) {
                this.divListItemsContainer.style.height = 150;
            } else {
                this.divListItemsContainer.style.height = '';
            }
        }


        //this.setPopupSize();

        if (this.popup)
            this.divListItemsContainer.style.display = 'none';
        this.divListItemsContainer.id = this.get_element().id + '_lic';
    },

    showListItems: function () {
        this.checkListItems();

        if (this.popup) {
            this.divListItemsContainer.style.display = 'block';
            this.divListItemsContainer.style.zIndex = 20003;

            this.setPopupSize();

            this.elementPos = null;
            this.setPopupPosition(null);
            window.setTimeout(this.checkListItemsMoved_handler, 10);

            if (this.button != null)
                this.button.className = 'cbxButtonActive';
            //this.get_element().select();
            this.divListItemsContainer.scrollTop = this.getPixelTop(this.optionTD_getCell(this.hoverIndex), "DIV") - 1;
            this.get_element().focus();
            //$addHandler(this.get_element(), 'blur', this.schedule_hideListItemsContainer_handler);
        }
    },

    setPopupPosition: function (lastPosition) {
        var container = (this.container ? this.container : this.get_element());
        var pos = Sys.UI.DomElement.getLocation(container);

        if (!lastPosition || pos.x != lastPosition.x || pos.y != lastPosition.y) {
            var divpos = Sys.UI.DomElement.getLocation(this.divListItemsContainer.parentNode);

            if (pos.x + this.divListItemsContainer.offsetWidth > $(window).width())
                pos.x = Math.max(0, $(window).width() - this.divListItemsContainer.offsetWidth);

            if (pos.y + container.offsetHeight + this.divListItemsContainer.offsetHeight > $(window).height() &&
                pos.x > this.divListItemsContainer.offsetHeight)
                pos.y = pos.y - this.divListItemsContainer.offsetHeight;
            else
                pos.y += container.offsetHeight

            Sys.UI.DomElement.setLocation(this.divListItemsContainer,
			        pos.x - divpos.x, pos.y - divpos.y);
        }
    },

    setPopupSize: function () {
        var container = (this.container ? this.container : this.get_element());
        this.divListItemsContainer.style.width = container.offsetWidth;
        this.divListItemsContainer.style.width = Math.max(this.tblListItemsWidth + 20, container.offsetWidth);
        //this.divListItemsContainer.style.width = this.tblListItems.style.width+20;
    },

    checkListItemsMoved: function () {
        var element = this.get_element();

        if (element && this.isListItemsContainerVisible()) {
            if (this.elementPos == null) {
                var container = (this.container ? this.container : this.get_element());
                this.elementPos = Sys.UI.DomElement.getLocation(container);
            } else {
                this.setPopupPosition(this.elementPos);
            }
            window.setTimeout(this.checkListItemsMoved_handler, 100);
        }
    },

    hideListItems: function () {
        if (this.popup && this.isListItemsContainerVisible()) {
            //$removeHandler(this.get_element(), 'blur', this.schedule_hideListItemsContainer_handler);

            this.divListItemsContainer.style.display = 'none';
            if (this.button != null)
                this.button.className = 'cbxButton';
        }
    },

    toggleShowListItems: function (e) {
        if (!this.bEnabled || !this.popup)
            return;

        this.keepElementFocus();
        this.cancel_hideListItemsContainer();

        if (!this.isListItemsContainerVisible()) {
            this.fire_fill();
        }

        if (this.selectedIndex > -1) {
            this.selectListItem(this.selectedIndex);
            this.hoverIndex = this.selectedIndex;
        }
        if (this.isListItemsContainerVisible()) {
            //hoverIndex = -1;
            this.hideListItems();
            this.get_element().select();
        } else {
            this.cancel_change();
            this.checkListItems();
            this.showListItems();
        }
    },

    getPixelTop: function (elem, tagName) {
        if (elem == null)
            return -1;

        var top = 0;
        while (elem != null && elem.tagName != tagName) {
            top += elem.offsetTop - elem.scrollTop;
            elem = elem.offsetParent;
        }
        return top;
    },

    getPixelLeft: function (elem, tagName) {
        var left = 0;
        while (elem != null && elem.tagName != tagName) {
            left += elem.offsetLeft;
            elem = elem.offsetParent;
        }
        return left;
    },

    getFormElement: function () {
        var elem = element;
        while (elem.tagName != "FORM") {
            elem = elem.offsetParent;
        }
        return elem;
    },

    takeValueFromListItems: function () {
        var bIsDirty = false;
        if (this.selectedIndex > -1) {
            bIsDirty = (this.hiddenValue.value != this.options[this.selectedIndex].Value);
            this.get_element().value = this.options[this.selectedIndex].Text;
            this.hiddenValue.value = this.options[this.selectedIndex].Value;
        }
        return bIsDirty;
    },

    selectListItem: function (index) {
        this.checkListItems();

        if (index >= 0) {
            var item = this.optionTD_getCell(index);
            if (item != null) {
                if (this.displayas == 'radiobuttons') {
                    item.firstChild.checked = true;
                } else {
                    item.style.backgroundColor = 'Highlight';
                    item.style.color = 'HighlightText';
                }
            }
            this.hoverIndex = index;
        }
    },

    highlightListItem: function (index) {
        this.checkListItems();

        if (index >= 0) {
            var item = this.optionTD_getCell(index);
            if (item != null) {
                if (this.displayas == 'radiobuttons') {
                } else if (this.displayas == 'dropdown') {
                    item.style.backgroundColor = 'Highlight';
                    item.style.color = 'HighlightText';
                }
            }
            this.hoverIndex = index;
        }
    },

    blurListItem: function (index) {
        if (index > -1) {
            this.checkListItems();

            var item = this.optionTD_getCell(index);
            if (item != null) {
                if (this.displayas == 'radiobuttons') {
                } else {
                    item.style.backgroundColor = 'transparent';
                    item.style.color = (this.options[index].Color ? this.options[index].Color : "black");
                }
            }
        }
    },

    optionTD_getIndex: function (e) {
        var target = e.target;
        if (target.tagName != 'TD')
            target = target.parentNode;

        return target.parentNode.rowIndex * this.columncount + target.cellIndex;
    },

    optionTD_getCell: function (index) {
        if (index < 0 || this.tblListItems == null)
            return null;

        if (!this.tblListItems.cells || this.tblListItems.cells.length == 0)
            return this.tblListItems.getElementsByTagName('td')[index];
        else
            return this.tblListItems.cells[index];
    },

    optionItem_Click: function (e) {
        if (!this.bEnabled) return;

        var index = this.optionTD_getIndex(e);
        if (index >= 0 && index < this.options.length) {
            var item = this.options[index];

            if (this.hoverIndex > -1)
                this.blurListItem(this.hoverIndex);

            this.selectedIndex = index;

            if (e.target.tagName != 'INPUT')
                this.selectListItem(index);
            else
                window.setTimeout(this.refreshSelectedListItem_handler, 10);

            this.get_element().value = item.Text;
            this.get_element().select();
            if (this.hiddenValue.value != item.Value) {
                this.hiddenValue.value = item.Value;
                this.emitChangeEvent();
            }
        }
        e.stopPropagation();
        e.preventDefault();
    },

    refreshSelectedListItem: function () {
        this.selectListItem(this.selectedIndex);
    },

    optionTD_MouseOver: function (e) {
        if (!this.bEnabled) return true;

        if (this.displayas == 'dropdown') {
            var index = this.optionTD_getIndex(e);
            if (this.selectedIndex > -1)
                this.blurListItem(this.selectedIndex);
            this.highlightListItem(index);
            this.hoverIndex = index;

        }

        //e.stopPropagation();
        //e.preventDefault();
        return true;
    },

    optionTD_MouseOut: function (e) {
        if (!this.bEnabled) return true;

        var index = this.optionTD_getIndex(e);
        this.blurListItem(index);
        this.hoverIndex = -1;
        this.selectListItem(this.selectedIndex);
        //e.stopPropagation();
        //e.preventDefault();
        return true;
    }
};

// descriptor for JSON serialization.
WFControls.Combobox.descriptor = {
    properties: [
        { name: 'options', type: Object },
        { name: 'enabled', type: Boolean },
        { name: 'autovalidate', type: Boolean },
        { name: 'size', type: Number },
        { name: 'containerid', type: String },
        { name: 'container', type: Object },
        { name: 'valuename', type: String },
        { name: 'value', type: String },
        { name: 'buttonid', type: String },
        { name: 'button', type: Object },
        { name: 'displayas', type: String },
        { name: 'columncount', type: Number }
        ],
    events: [
        { name: 'change' }, { name: 'fill' }, { name: 'textchange' }
        ]
}

// the base this class inherits from
WFControls.Combobox.inheritsFrom(Sys.UI.Behavior);

// Register the class as derived from UI.Behavior.
WFControls.Combobox.registerClass('WFControls.Combobox', Sys.UI.Behavior);

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();


