
(function(a) {
    a.widget("ui.dropdownchecklist", {
        _appendDropContainer: function() {
            var c = a("<div/>");
            c.addClass("ui-dropdownchecklist-dropcontainer-wrapper");
            c.css({
                position: "absolute", //HACK: compensate to be in a container (original value "fixed")
                left: "-3300",
                top: "-3300px",
                width: "3000px",
                height: "3000px"
            });
            var b = a("<div/>");
            b.addClass("ui-dropdownchecklist-dropcontainer").css("overflow-y", "auto");
            c.append(b);

            var oLocation = this.options.dropDownLocationObject
            //If the location is not defined then use the document body
            if (oLocation == null) { oLocation = document.body }
            else { oLocation.css("position", "relative"); }
            //a(document.body).append(c);
            a(this.options.dropDownLocationObject).append(c);  //HACK: place to put the hidden div container

            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 (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)
                }
            }
            
            //HACK: set the text to show custom words if empty
            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({                    
                    //alert(g.controlWrapper.outerHeight())
                    top: "0px", //HACK: use the container. Original was top: g.controlWrapper.offset().top + g.controlWrapper.outerHeight() + "px"
                    left: "0px" //HACK: use the container. Original was left: g.controlWrapper.offset().left + "px"
                });
                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: 90 //HACK: fix it to a specific index so it always goes under the header (original was: (h + 1) )
                    })
                }
                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() {
            //HACK:  line below commented because it caused error in all browsers
            //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
        }
    })
})(jQuery);
