$.widget( "ui.combobox", {
    options : {
        selectbox : false,
        genID : false,
        appendTo: 'body'
    },
    reload : function () {
        if (this.element.find('option').length == 0) {
            this.element.next(":input").val("");
        } else {
            this.element.next(":input").val(this.element.find("option:first").val());
        }
    },
    _create: function() {
        var width = this.element.css("width").replace(/(px|em|cm|\s)/gi, '');
        var title = this.element.attr("title");
        var className = this.element.attr("class");
        var options = this.options;
        var select = this.element;
        	select.hide();
            selected = select.children( ":selected" );
            value = selected.text();
        var span = $('<span>');
        	span.insertAfter( select ).css({
        		 "vertical-align": "top",
        		 position: "relative",
        		 display: "inline-block"
        	});
        var input = $( "<input style='margin:0; padding:0; position:absolute; top:0; left: 0'>" )
            .appendTo( span )
            .val( value )
            .autocomplete({
            	appendTo: options.appendTo,
                delay: 0,
                minLength: 0,
                open : function () {
                    var top = $(this).offset().top + $(this).height();
                    var maxHeight = $(window).height() - top - 50;
                    $(".ui-menu").css({
                        "max-height" : maxHeight+"px",
                        "width" : width+"px",
                        "overflow" : "auto"
                    });
                },
                source: function(request, response) {
                    var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
                    response( select.children( "option" ).map(function() {
                            var text = $( this ).text();
                            if ( this.value && ( !request.term || matcher.test(text) ) )
                                    return {
                                            label: text.replace(
                                                    new RegExp(
                                                            "(?![^&;]+;)(?!<[^<>]*)(" +
                                                            $.ui.autocomplete.escapeRegex(request.term) +
                                                            ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                                    ), "<strong>$1</strong>" ),
                                            value: text,
                                            option: this
                                    };
                    }) );
                },
                select: function( event, ui ) {
                    select.val(ui.item.option.value);
                    select.change();
                }
            })
            .addClass(className)
            .addClass("ui-widget ui-widget-content ui-corner-left ");
        
        if (options.selectbox) {
            input.attr("readonly", "readonly");
            input.css("cursor", "default");
            input.css("borderRight", "none");
            input.click(function () {
                button.click();
            })
            .keypress(function (e) {
            	if (e.keyCode == 40 || e.keyCode == 39 || e.keyCode == 38 || e.keyCode == 37)
            		input.autocomplete("search", "");
            });
        }

        if (options.genID) {
        	input[0].id = "ui-combobox-" + (new Date()).getTime();
        }

        input.data( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
                .append( "<a>" + item.label + "</a>" )
                .appendTo( ul );
        };

        var button = $( '<button type="button" style="position:absolute; top:0; right:0;">&nbsp;</button>' )
            .attr( {"tabIndex": -1, "title" : title} )
            .css( { margin: 0 })
            .appendTo( span )
            .button({ icons: { primary: "ui-icon-triangle-1-s" }, text: false })
            .removeClass( "ui-corner-all" )
            .addClass( "ui-corner-right ui-button-icon" )
            .click(function() {
                // close if already visible
                if (input.autocomplete("widget").is(":visible")) {
                    input.autocomplete("close");
                    button.blur();
                    return false;
                }
                // pass empty string as value to search for, displaying all results
                input.autocomplete("search", "");
                input.focus();
                $(".ui-autocomplete").css("max-height", "300px");
                return false;
            });

        if (this.element.attr("title").length<=0) { button.removeAttr("title"); }
        input.blur(function () { button.blur(); });

        var bt_width = parseInt(button.css("width").toString().replace(/(px|em|cm|\s)/gi, ''));
        
        input.css("width", (width - bt_width).toString() + "px");
        input.css("height", button.height());
        span.width( select.width() );
        span.css("height", input.css("height"));
        select.change(function () {
        	var tml = select.find("option:selected").text();
        	if (tml.length == 0) {
        		var tml = select.find("option:first").text();
        		if (tml.length == 0) {
        			var tml = '';
        		}
        	}
        	input.val(tml);
        });
    },
    disable : function () {
    	this.element.next("span").find("input").attr("disabled", "disbaled");
    	this.element.next("span").find("button").button("option", "disabled", true);
    },
    enable : function () {
    	this.element.next("span").find("input").removeAttr("disabled");
    	this.element.next("span").find("button").button("option", "disabled", false);
    }
});
