(function (a) {
    a.widget("ui.dropdownchecklist", {
        _appendDropContainer: function () {
            var c = a("<div/>");
            c.addClass("ui-dropdownchecklist-dropcontainer-wrapper");
            c.css({
                position: "absolute",
                left: "-3300",
                top: "-3300px",
                width: "3000px",
                height: "3000px"
            });
            var b = a("<div/>");
            b.addClass("ui-dropdownchecklist-dropcontainer").css("overflow-y", "auto");
            c.append(b);
            a(document.body).append(c);
            c.drop = false;
            return c
        },
        _isDropDownKeyShortcut: function (b) {
            return b.altKey && (a.ui.keyCode.DOWN == (b.keyCode || b.which))
        },
        _isDroDownCloseKey: function (b) {
            return a.ui.keyCode.ESCAPE == (b.keyCode || b.which)
        },
        _handleKeyboard: function (c) {
            var b = this;
            if (b._isDropDownKeyShortcut(c)) {
                c.stopPropagation();
                b._toggleDropContainer();
                b.dropWrapper.find("input:first").focus()
            } else {
                if (b.dropWrapper.drop && b._isDroDownCloseKey(c)) {
                    b._toggleDropContainer()
                }
            }
        },
        _appendControl: function () {
            var b = this,
                c = this.sourceSelect;
            var f = a("<span/>");
            f.addClass("ui-dropdownchecklist-wrapper");
            f.css({
                display: "inline-block",
                cursor: "default"
            });
            var e = a("<span/>");
            e.addClass("ui-dropdownchecklist");
            e.css({
                display: "inline-block"
            });
            e.attr("tabIndex", 0);
            e.keyup(function (g) {
                b._handleKeyboard(g)
            });
            f.append(e);
            var d = a("<span/>");
            d.addClass("ui-dropdownchecklist-text");
            d.css({
                display: "inline-block",
                overflow: "hidden"
            });
            e.append(d);
            f.hover(function () {
                if (!b.disabled) {
                    e.toggleClass("ui-dropdownchecklist-hover")
                }
            }, function () {
                if (!b.disabled) {
                    e.toggleClass("ui-dropdownchecklist-hover")
                }
            });
            f.click(function (g) {
                if (!b.disabled) {
                    g.stopPropagation();
                    b._toggleDropContainer()
                }
            });
            f.insertAfter(c);
            return f
        },
        _createDropItem: function (h, k, m, l, f, d) {
            var o = this;
            var n = a("<div/>");
            n.addClass("ui-dropdownchecklist-item");
            n.css({
                whiteSpace: "nowrap"
            });
            var c = l ? ' checked="checked"' : "";
            var j = f ? ' disabled="disabled"' : "";
            var p = (o.sourceSelect.attr("id") || "ddcl");
            var b = p + h;
            var g;
            if (o.initialMultiple) {
                g = a('<input type="checkbox" id="' + b + '"' + c + j + "/>")
            } else {
                g = a('<input type="radio" id="' + b + '" name="' + p + '"' + c + j + "/>")
            }
            g = g.attr("index", h).val(k);
            n.append(g);
            var i = a("<label for=" + b + "/>");
            i.addClass("ui-dropdownchecklist-text").css({
                cursor: "default",
                width: "100%"
            }).text(m);
            if (d) {
                n.addClass("ui-dropdownchecklist-indent")
            }
            if (f) {
                n.addClass("ui-dropdownchecklist-item-disabled")
            }
            n.append(i);
            n.hover(function () {
                n.addClass("ui-dropdownchecklist-item-hover")
            }, function () {
                n.removeClass("ui-dropdownchecklist-item-hover")
            });
            g.click(function (q) {
                q.stopPropagation();
                if (!f) {
                    o._syncSelected(a(this));
                    o.sourceSelect.trigger("change", "ddcl_internal")
                }
            });
            var e = function (r) {
                r.stopPropagation();
                if (!f) {
                    var q = g.attr("checked");
                    g.attr("checked", !q);
                    o._syncSelected(g);
                    o.sourceSelect.trigger("change", "ddcl_internal")
                }
            };
            i.click(function (q) {
                q.stopPropagation()
            });
            n.click(e);
            n.keyup(function (q) {
                o._handleKeyboard(q)
            });
            return n
        },
        _createGroupItem: function (d) {
            var c = a("<div />");
            c.addClass("ui-dropdownchecklist-group");
            c.css({
                whiteSpace: "nowrap"
            });
            var b = a("<span/>");
            b.addClass("ui-dropdownchecklist-text").css({
                cursor: "default",
                width: "100%"
            }).text(d);
            c.append(b);
            return c
        },
        _appendItems: function () {
            var d = this,
                g = this.sourceSelect,
                f = this.dropWrapper;
            var b = f.find(".ui-dropdownchecklist-dropcontainer");
            b.css({
                "float": "left"
            });
            g.children().each(function (h) {
                var i = a(this);
                if (i.is("option")) {
                    d._appendOption(i, b, h, false)
                } else {
                    var k = i.attr("label");
                    var j = d._createGroupItem(k);
                    b.append(j);
                    d._appendOptions(i, b, h, true)
                }
            });
            var c = b.outerWidth();
            var e = b.outerHeight();
            b.css({
                "float": ""
            });
            return {
                width: c,
                height: e
            }
        },
        _appendOptions: function (f, c, e, b) {
            var d = this;
            f.children("option").each(function (g) {
                var h = a(this);
                var i = (e + "." + g);
                d._appendOption(h, c, i, b)
            })
        },
        _appendOption: function (f, b, g, c) {
            var k = this;
            var i = f.text();
            var h = f.val();
            var e = f.attr("selected");
            var d = f.attr("disabled");
            var j = k._createDropItem(g, h, i, e, d, c);
            b.append(j)
        },
        _syncSelected: function (g) {
            var h = this,
                i = this.options,
                c = this.sourceSelect,
                d = this.dropWrapper;
            var f = d.find("input:not([disabled])");
            if (i.firstItemChecksAll) {
                if (g.attr("index") == 0) {
                    f.attr("checked", g.attr("checked"))
                } else {
                    var e;
                    e = true;
                    f.each(function (k) {
                        if (k > 0) {
                            var l = a(this).attr("checked");
                            if (!l) {
                                e = false
                            }
                        }
                    });
                    var j = f.filter(":first");
                    j.attr("checked", false);
                    if (e) {
                        j.attr("checked", true)
                    }
                }
            }
            var b = c.get(0).options;
            f.each(function (k) {
                a(b[k]).attr("selected", a(this).attr("checked"))
            });
            h._updateControlText()
        },
        _sourceSelectChangeHandler: function (c) {
            var b = this,
                d = this.dropWrapper;
            d.find("input").val(b.sourceSelect.val());
            b._updateControlText()
        },
        _updateControlText: function () {
            var h = this,
                b = this.sourceSelect,
                i = this.options,
                e = this.controlWrapper;
            var j = b.find("option:first");
            var f = null != j && j.attr("selected");
            var c = b.find("option");
            var g = h._formatText(c, i.firstItemChecksAll, f);
            var d = e.find(".ui-dropdownchecklist-text");
            d.text(g);
            d.attr("title", g)
        },
        _formatText: function (c, d, b) {
            var e;
            if ( $.isFunction(this.options.textFormatFunction) ) {
            	// let the callback do the formatting, but do not allow it to fail
            	try {
                	e = this.options.textFormatFunction(c);
                } catch(ex) {
                	alert( 'textFormatFunction failed: ' + ex );
                }
            }else if (d && b) {
                e = c.filter(":first").text()
            } else {
                e = "";
                c.each(function () {
                    if (a(this).attr("selected")) {
                        e += a(this).text() + ", "
                    }
                });
                if (e.length > 0) {
                    e = e.substring(0, e.length - 2)
                }
                if (e == "") e = this.options.emptyText;
            }
            return e
        },
        _toggleDropContainer: function () {
            var c = this,
                f = this.dropWrapper,
                e = this.controlWrapper;
            var d = function () {
                var g = a.ui.dropdownchecklist.drop;
                if (null != g) {
                    g.dropWrapper.css({
                        top: "-3300px",
                        left: "-3300px"
                    });
                    g.controlWrapper.find(".ui-dropdownchecklist").toggleClass("ui-dropdownchecklist-active");
                    g.dropWrapper.find("input").attr("tabIndex", -1);
                    g.dropWrapper.drop = false;
                    a.ui.dropdownchecklist.drop = null;
                    a(document).unbind("click", d);
                    c.sourceSelect.trigger("blur")
                }
            };
            var b = function (g) {
                if (null != a.ui.dropdownchecklist.drop) {
                    d()
                }
                g.dropWrapper.css({
                    top: g.controlWrapper.offset().top + g.controlWrapper.outerHeight() + "px",
                    left: g.controlWrapper.offset().left + "px",
					zIndex: '999'
                });
                var i = e.parents().map(function () {
                    var j = a(this).css("z-index");
                    return isNaN(j) ? 0 : j
                }).get();
                var h = Math.max.apply(Math, i);
                if (h > 0) {
                    g.dropWrapper.css({
                        //zIndex: (h + 1)
						zIndex: '999'
                    })
                }
                g.controlWrapper.find(".ui-dropdownchecklist").toggleClass("ui-dropdownchecklist-active");
                g.dropWrapper.find("input").attr("tabIndex", 0);
                g.dropWrapper.drop = true;
                a.ui.dropdownchecklist.drop = g;
                a(document).bind("click", d);
                c.sourceSelect.trigger("focus")
            };
            if (f.drop) {
                d(c)
            } else {
                b(c)
            }
        },
        _setSize: function (b) {
            var j = this.options,
                e = this.dropWrapper,
                h = this.controlWrapper;
            var g;
            if (j.width) {
                g = parseInt(j.width)
            } else {
                g = b.width;
                var c = j.minWidth;
                if (g < c) {
                    g = c
                }
            }
            h.find(".ui-dropdownchecklist-text").css({
                width: g + "px"
            });
            var i = h.outerWidth();
            var f = j.maxDropHeight ? parseInt(j.maxDropHeight) : b.height;
            var d = b.width < i ? i : b.width;
            a(e).css({
                width: d + "px",
                height: f + "px"
            });
            e.find(".ui-dropdownchecklist-dropcontainer").css({
                height: f + "px"
            })
        },
        _init: function () {
            var c = this,
                d = this.options;
            var g = c.element;
            c.initialDisplay = g.css("display");
            g.css("display", "none");
            c.initialMultiple = g.attr("multiple");
            g.attr("multiple", "multiple");
            c.sourceSelect = g;
            var f = c._appendDropContainer();
            c.dropWrapper = f;
            var b = c._appendItems();
            var e = c._appendControl();
            c.controlWrapper = e;
            c._updateControlText(e, f, g);
            c._setSize(b);
            if (d.bgiframe && typeof c.dropWrapper.bgiframe == "function") {
                c.dropWrapper.bgiframe()
            }
            c.sourceSelect.change(function (i, h) {
                if (h != "ddcl_internal") {
                    c._sourceSelectChangeHandler(i)
                }
            })
        },
        enable: function () {
            this.controlWrapper.find(".ui-dropdownchecklist").removeClass("ui-dropdownchecklist-disabled");
            this.disabled = false
        },
        disable: function () {
            this.controlWrapper.find(".ui-dropdownchecklist").addClass("ui-dropdownchecklist-disabled");
            this.disabled = true
        },
        destroy: function () {
            a.widget.prototype.destroy.apply(this, arguments);
            this.sourceSelect.css("display", this.initialDisplay);
            this.sourceSelect.attr("multiple", this.initialMultiple);
            this.controlWrapper.unbind().remove();
            this.dropWrapper.remove()
        }
    });
    a.extend(a.ui.dropdownchecklist, {
        defaults: {
            width: null,
            maxDropHeight: null,
            firstItemChecksAll: false,
            minWidth: 50,
            bgiframe: false,
            emptyText: ""
        }
    })
})(jQuery);
