window.ch_sbox = function($){
    return {
        build: function(id, config){
            var elm = null;
            var body = null;
            var head = null;
            var ipt = null;
            var c = {
                onChange: null,
                onOpen: null,
                onClose: null,
                width: null,
                height: null,
                value: null
            };
            var h = [];
            var idx = -1;
            // parameter checking
            if (!id || (elm = $("#" + id)) == null) 
                throw "Element not existed.";
            // extend the default configuration
            $.extend(c, config);
            // get the width of the select box
            c.width = c.width || elm.outerWidth();
            // set the button width
            c._btnWidth = 20;
            // loop through the options
            var opt = null;
            var opts = elm.children("option");
            var selOpt = elm.find("option:selected");
            idx = selOpt[0].index;
            h = [];
            h.push("<div id='" + id + "_sbox' style='width:" + c.width + "px' class='" + "sbox_cont'><div class='header'><div style='width:" + (c.width - c._btnWidth) + "px' class='lbl'><div>");
            h.push(c.value || selOpt.text());
            h.push("</div></div><div style='width:" + c._btnWidth + "px' class='btn'><div>&diams;</div></div></div><div class='body'><ul class='sbox_ul'>");
            for (var i = 0; i < opts.length; i++) {
                opt = $(opts[i]);
                h.push("<li><a href='#' style='width:" + (c.width - 10) + "px' idx='" + i + "' class='sbLink" + (((c.value != null && opt.attr("value") == c.value) || (c.value == null && i == idx)) ? " selected" : "") + "' value='" + opt.attr("value") + "'>" + opt.text() + "</a></li>");
            }
            h.push("</ul></div></div><input type='hidden' name='" + elm.attr("name") + "' id='" + elm.attr("id") + "' value='" + elm.val() + "'/>");
            elm.replaceWith(h.join(""));
            // update the element
            elm = $("#" + id + "_sbox");
            body = $("#" + id + "_sbox > div.body > ul");
            head = $("#" + id + "_sbox > div.header > div.lbl > div");
            ipt = $("#" + id);
            // add event handlers
            elm.click(function(e){
                var t = $(e.target);
                var d = $(document);
                var handleMd = function(e){
                    var t = $(e.target);
                    var ol = body.find("li > a[class*='selected']");
                    
                    if (t.hasClass("sbLink")) {
                        ol.removeClass("selected");
                        head.html(t.text());
                        ipt.val(t.text());
                        c.value = t.attr("value");
                        t.addClass("selected");
                        if (c.onChange) 
                            c.onChange();
                    }
                    
                    if(!t.hasClass("sbox_ul")){
                        if(c.onClose)
                            c.onClose();
                        body.hide();
                        d.unbind("mousedown", handleMd);
                    }
                    
                }
                
                if (t.is("div")) {
                    if(c.onOpen)
                        c.onOpen();
                    body.css("top", ((c.height || head.height()) + 4)).show();
                    d.mousedown(handleMd);
                }
            });
        }
    };
}(jQuery);