jQuery.fn.extend({
    addSelectUI: function() {
        //config
        var maxDropListHeight = 300;

        //droplist Manager
        $droplist_Manager = function () {
            var o = this;
            o.els = new Array(); // element type = jquery object
            o.activeIndex = null; // index of active droplist
        }

        //droplist class
        $droplist_UI = function (jEl) { //jEl = jquery element
            var o = this;
            //init
            o.select = jEl;
            o.select.css({
                opacity: 0,
                position: "absolute",
                left: "-1000em",
                top: "-1000em"
            });
            o.elUL = $("<ul title=\"" + o.select.attr("title") + "\"></ul>");
            o.elUL.addClass(o.select.attr("class"));
            o.select.after(o.elUL);

            o.select.find("option").each(function () {
                var self = $(this);
                o.elUL.append("<li><a href=\"#\" title=\"" + self.text() + "\" rel=\"" + self.attr("label") + "\">" + self.text() +"</a></li>");
            });

            o.el = $("<div></div>");
            o.elUL.before(o.el);
            o.el.html(o.elUL);

            o.el.css({
                position: "absolute",
                left: 0,
                display: "none",
                width: "100%"
            });
            o.elWrapper = $("<div class=\"DropListUI\"></div>");
            o.el.before(o.elWrapper);
            var elClasses = o.elUL.attr("class").split(" ");
            for (i in elClasses) {
                if ( elClasses[i].match(/^Theme/) ) {
                    o.elWrapper.addClass(elClasses[i]);
                }
                else {
                    o.elWrapper.addClass("DefaultTheme");
                }
            }
            o.elWrapper.html(o.el);
            var title = ( o.elUL.attr("title") != "" && typeof(o.elUL.attr("title")) != "undefined" )
                        ? o.elUL.attr("title")
                        : o.elUL.children("li:first-child").text();
			if ( !o.select.attr("disabled") ) {			
            	o.droplistTITLE = $("<p>" + title + "</p>");
			}
			else {
				o.droplistTITLE = $("<p></p>");
				o.elWrapper.addClass("Disabled");
			}
            o.el.before(o.droplistTITLE);


            //binding events
            $(document).bind("click", function (evt) {
                if (droplistManager.activeIndex != null) {
                    droplistManager.els[droplistManager.activeIndex].el.hideList();
                }
                evt.stopPropagation();
                //return false;
            });
            o.el.bind("click", function (evt) {
                return false; //prevent default action and stop bubble
            });
            o.droplistTITLE.bind("click", function (evt) {
				if ( !o.select.attr("disabled") ) {
					if ( o.el.hasClass("DropListUIShow") ) {
						o.el.hideList();
					}
					else { //showlist
						if ( droplistManager.activeIndex != null ) {
							droplistManager.els[droplistManager.activeIndex].el.hideList();
						}
						o.el.showList();
						droplistManager.activeIndex = $.inArray(o, droplistManager.els);
					}
				}
                return false; //prevent default action and stop bubble
            });
            o.el.find("ul:first-child > li").each(function (index) {
                var self = $(this);

                self.bind("click", function () {
					if ( !o.select.attr("disabled") ) {
						//o.droplistTITLE.text( self.text() );
						o.el.find("ul:first-child > li").removeClass("Active");
						self.addClass("Active");
						o.droplistTITLE.text( self.text() );
						o.el.hideList();
						o.select.val(o.select.find("option").eq(index).val());
						/*call Externall Function*/
						callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
						self.removeClass("Hover");
						return false;
					}
                });
                self.bind("mouseover", function () {
                    self.addClass("Hover");
                    return false;
                });
                self.bind("mouseout", function () {
                    self.removeClass("Hover");
                    return false;
                });
            });

            /* methods */
            this.reset = function () {
                //refresh
                o.elUL.empty();
                o.elUL.removeAttr("class");
                //re-create
                o.elUL.attr("title", o.select.attr("title"));
                o.elUL.addClass(o.select.attr("class"));
                o.select.val("select");
                o.select.find("option").each(function () {
                    var self = $(this);
					o.elUL.append("<li><a href=\"#\" title=\"" + self.text() + "\" rel=\"" + self.attr("label") + "\">" + self.text() +"</a></li>");
                });
                var title = ( o.elUL.attr("title") != "" && typeof(o.elUL.attr("title")) != "undefined" )
                            ? o.elUL.attr("title")
                            : o.elUL.children("li:first-child").text();
                
				if ( !o.select.attr("disabled") ) {			
					o.droplistTITLE.html(title);
				}
				else {
					o.droplistTITLE.html("");
					o.elWrapper.addClass("Disabled");
				}
                //re-binding events
                o.el.find("ul:first-child > li").each(function (index) {
                    var self = $(this);

                    self.bind("click", function () {
                        //o.droplistTITLE.text( self.text() );
                        o.el.find("ul:first-child > li").removeClass("Active");
                        self.addClass("Active");
                        o.droplistTITLE.html( self.text() );
                        o.el.hideList();
                        o.select.val(o.select.find("option").eq(index).val());
                        /*call Externall Function*/
                        callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
						self.removeClass("Hover");
                        return false;
                    });
                    self.bind("mouseover", function () {
                        self.addClass("Hover");
                        return false;
                    });
                    self.bind("mouseout", function () {
                        self.removeClass("Hover");
                        return false;
                    });
                });
            }

            //extends function of el
            o.el.extend({
                showList: function () {
                    o.elWrapper.addClass("TopLevel");
                    o.el.addClass("DropListUIShow");

                    var maxHeight = $(window).height();
                    var height = o.elWrapper.offset().top + o.elWrapper.height() + o.el.height();

                    //check whether show up or down
                    if ( maxHeight < height && (o.elWrapper.offset().top > o.el.height() || o.elWrapper.offset().top > maxDropListHeight ) ) { //show up
                        o.el.css({
                            bottom: o.elWrapper.height() + "px",
                            top: "auto"
                        });
                    }
                    else { //show down
                        o.el.css({
                            top: "100%",
                            bottom: "auto"
                        });
                    }
                    o.el.show();

                    //apply jScrollPane for scrolling
                    if (o.el.height() > maxDropListHeight) {
                        o.elUL.height(maxDropListHeight);
                        o.elUL.jScrollPane();
                    }
                },
                hideList: function () {
                    //remove jScrollPane
                    o.el.prepend(o.elUL);
                    o.elUL.removeAttr("style");
                    o.elUL.next().remove();

                    o.elWrapper.removeClass("TopLevel");
                    o.el.removeClass("DropListUIShow");
                    o.el.hide();
                }
            });
        }

        //setup
        var droplistManager = new $droplist_Manager();

        this.each(function () {
            droplistManager.els.push( new $droplist_UI($(this)) );
        });
    }
});

function callExternalFunction (o/*caller*/, droplist/*all droplists*/, val/*rel in <a>*/) {
}