jQuery.fn.extend({
    addSelectUI: function() {

        //droplist Manager
        $droplist_Manager = function() {
            var o = this;
            o.els = new Array(); // element type = jquery object
            o.activeName = null; // index of active droplist
        }

        //droplist class
        $droplist_UI = function(jEl, options) { //jEl = jquery element
            var o = this;
            //config
            o.config = {
                maxDropListHeight: options != undefined && options.maxDropListHeight != undefined ? options.maxDropListHeight : 300
            }
            //init
            o.options = {
                scrollbarWidth: options != undefined && options.scrollbarWidth != undefined ? parseInt(options.scrollbarWidth) : 10,
                scrollbarSide: options != undefined && options.scrollbarSide != undefined ? options.scrollbarSide : "right"
            }
            //max droplist height
            o.maxDropListHeight = options != undefined && options.maxDropListHeight != undefined ? options.maxDropListHeight : o.config.maxDropListHeight;

            /*<select>*/
            o.select = jEl;
            o.select.addClass("HasSelectUI");
            o.select.css({
                opacity: 0,
                position: "absolute",
                left: "-1000em",
                top: "-1000em"
            });
            o.reservedHolder = null;
            o.elUL = jQuery("<ul title=\"" + o.select.attr("title") + "\"></ul>");
            o.elUL.addClass(o.select.attr("class"));
            o.select.after(o.elUL);
            /*end. <select>*/

            /*Create UL reflect <select>*/
            var offset = 0;

            var numChars = o.select.attr("rel") != undefined ? o.select.attr("rel") : 30
            o.select.find("> *").each(function(index) {
                var el = jQuery(this);
                var count = index;

                if (this.tagName.toLowerCase() == "optgroup") {
                    //detected <optgroup>
                    el.each(function() {
                        var optgroup = jQuery(this);

                        var optName = optgroup.attr("label");
                        var optgroup_el = jQuery("<li></li>");
                        optgroup_el.prepend("<span class=\"OptgroupLabel\">" + optName + "</span>");
                        var optgroup_elsubUL = jQuery("<ul></ul>");
                        o.elUL.append(optgroup_el);
                        optgroup_el.append(optgroup_elsubUL);

                        optgroup.find("option").each(function(index) {
                            var self = jQuery(this);
                            if (self.attr("value") == "") {
                                optgroup_elsubUL.append("<li class=\"SelectUITitle\" value=\"" + parseInt(count + index + offset + 1) + "\"><a href=\"#\" title=\"" + self.text() + "\" rel=\"" + self.attr("label") + "\">" + self.text() + "</a></li>");
                            }
                            else {
                                optgroup_elsubUL.append("<li value=\"" + parseInt(count + index + offset + 1) + "\"><a href=\"#\" title=\"" + self.text() + "\" rel=\"" + self.attr("label") + "\">" + self.text() + "</a></li>");
                            }
                        });
                        offset += optgroup.find("option").length - 1;
                    });
                }
                else {
                    //detected select
                    if (el.attr("value") == "") {
                        o.elUL.append("<li class=\"SelectUITitle\" value=\"" + parseInt(index + offset + 1) + "\"><a href=\"#\" title=\"" + el.text() + "\" rel=\"" + el.attr("label") + "\">" + el.text() + "</a></li>");
                    }
                    else {
                        var text = el.text();
                        if (text.length > numChars) {
                            text = text.substring(0, Math.min(numChars, text.length)) + "...";
                        }
                        o.elUL.append("<li value=\"" + parseInt(index + offset + 1) + "\"><a href=\"#\" title=\"" + el.text() + "\" rel=\"" + el.attr("label") + "\">" + text + "</a></li>");
                    }
                }
            });

            //append to DOM
            o.el = jQuery("<div class=\"DropListUIContainer\"></div>");
            o.elUL.before(o.el);
            o.el.html(o.elUL);
            /*end. Create UL reflect <select>*/

            /*Wrapper*/
            o.elWrapper = jQuery("<div class=\"DropListUI\"></div>");
            o.el.before(o.elWrapper);
            var elClasses = o.elUL.attr("class").split(" ");
            var addDefaultTheme = true;
            for (i in elClasses) {
                if (elClasses[i].match(/^Theme/)) {
                    o.elWrapper.addClass(elClasses[i]);
                    addDefaultTheme = false;
                }
            }

            if (addDefaultTheme) {
                o.elWrapper.addClass("Theme_Default");
                o.elUL.addClass("Theme_Default");
            }
            o.elWrapper.html(o.el);
            /*end. Wrapper*/

            /*Title*/
            /*
            var title = o.elUL.children("li:first-child").text();

            o.select.find("option").each(function () {
            var option = jQuery(this);

                if ( option.attr("value") == o.select.val() ) {
            title = option.text();
            }
            });
            */
            var title = "";
            var hasValue = false;
            o.select.find("option").each(function() {
                var option = jQuery(this);

                if (option.attr("selected")) {
                    title = option.text();
                    hasValue = true;
                }
            });

            if (!hasValue) {
                title = o.select.attr("title") != "" ? o.select.attr("title") : o.select.find("option:first-child").text();
            }
            /*end. Title*/

            /*Disabled option*/
            if (!o.select.attr("disabled")) {
                o.droplistTITLE = jQuery("<p>" + title + "</p>");
            }
            else {
                o.droplistTITLE = jQuery("<p></p>");
                o.elWrapper.addClass("Disabled");
            }
            o.el.before(o.droplistTITLE);
            /*end. Disabled option*/

            o.el.css({
                position: "absolute",
                left: 0,
                display: "none",
                overflow: "hidden",
                width: o.elUL.width() || o.elUL.css("width")
            });

            /*Binding events*/
            o.el.find("ul > li").each(function(index) {

                var self = jQuery(this);

                self.bind("click", function() {
                    if (self.find("span.OptgroupLabel:first-child").length > 0) {
                        //o.el.hideList();
                        return false;
                    }
                    else {
                        if (!o.select.attr("disabled")) {
                            //o.droplistTITLE.text( self.text() );
                            o.el.find("ul > li").removeClass("Active");
                            self.addClass("Active");
                            o.droplistTITLE.text(self.text());
                            o.hideList();

                            o.select.val(o.select.find("option").eq(self.attr("value") - 1).val());

                            /*call Externall Function*/
                            var CarnetDeBordPage = "Carnet-de-bord.aspx";
                            var AutoCOntactedPage = "midas-centre-auto-contactez-nous.aspx";
                            var isCarnetDeBordPage = false;
                            var isAutoCOntactedPage = false;

                            var thisUrl = decodeURI(window.location);
                            var pairs = thisUrl.split("/");
                            for (var value in pairs) {
                                if (pairs[value] == CarnetDeBordPage) {
                                    isCarnetDeBordPage = true;
                                    isAutoCOntactedPage = false;
                                }
                                else if (pairs[value] == AutoCOntactedPage) {
                                    isCarnetDeBordPage = false;
                                    isAutoCOntactedPage = true;
                                }
                            }

                            if (!isCarnetDeBordPage & isAutoCOntactedPage) {
                                var evt = $.browser.msie ? "true" : "false";
                                if (evt == "true") // IE has a problem with the .change property, lets fix it
                                {
                                    //$(o.select).bind('propertyonchange, propertychange, change, onchange, select, onselect, click, onclick', callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel")));
                                    $(o.select).attr("onchange", callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel")));
                                    
                                }
                                else //else the rest are more smart enogh to call onchange
                                {
                                    $(o.select).change();
                                    callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
                                }
                            }
                            else {
                                // honnor select's onchange event
                                $(o.select).change();
                                callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
                            }

                            // honnor select's onchange event
                            //$(o.select).change();

                            /*
                            var evt = $.browser.msie ? "true" : "false";
                            if (evt == "true") // IE has a problem with the .change property, lets fix it
                            {
                            $(o.select).bind('propertyonchange, propertychange, change, onchange, select, onselect, click, onclick', callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel")));
                            }
                            else //else the rest are more smart enogh to call onchange
                            {
                            $(o.select).change();
                            callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
                            }
                            */

                            //callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
                            self.removeClass("Hover");
                            return false;
                        }
                    }
                });

                /* Little trick for IE6 Hover Problem */
                self.bind("mouseover", function() {
                    self.addClass("Hover");
                    return false;
                });

                self.bind("mouseout", function() {
                    self.removeClass("Hover");
                    return false;
                });
                /* end. Little trick for IE6 Hover Problem */
            });

            o.droplistTITLE.bind("click", function(evt) {
                if (!o.select.attr("disabled")) {
                    if (o.el.hasClass("DropListUIShow")) {
                        o.hideList();
                    }
                    else { //showlist
                        if (droplistManager.activeName != null) {
                            droplistManager.els[droplistManager.activeName].hideList();
                        }
                        o.showList();
                        droplistManager.activeName = o.select.attr("id");
                    }
                }
                return false; //prevent default action and stop bubble
            });

            jQuery(document).bind("click", function(evt) {
                if (droplistManager.activeName != null) {
                    droplistManager.els[droplistManager.activeName].hideList();
                }
                evt.stopPropagation();
                //return false;
            });

            jQuery(window).bind("resize", function(evt) {
                o.setDirection();
            });
            jQuery(document).bind("scroll", function(evt) {
                o.setDirection();
            });

            o.el.bind("click", function(evt) {
                return false; //prevent default action and stop bubble
            });

            /*end. Binding events*/

            /* 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"));

                /*Re-Create UL reflect <select>*/
                var offset = 0;
                o.select.find("> *").each(function(index) {
                    var el = jQuery(this);
                    var count = index;

                    if (this.tagName.toLowerCase() == "optgroup") {
                        //detected <optgroup>
                        el.each(function() {
                            var optgroup = jQuery(this);

                            var optName = optgroup.attr("label");
                            var optgroup_el = jQuery("<li></li>");
                            optgroup_el.prepend("<span class=\"OptgroupLabel\">" + optName + "</span>");
                            var optgroup_elsubUL = jQuery("<ul></ul>");
                            o.elUL.append(optgroup_el);
                            optgroup_el.append(optgroup_elsubUL);

                            optgroup.find("option").each(function(index) {
                                var self = jQuery(this);
                                if (self.attr("value") == "") {
                                    optgroup_elsubUL.append("<li class=\"SelectUITitle\" value=\"" + parseInt(count + index + offset + 1) + "\"><a href=\"#\" title=\"" + self.text() + "\" rel=\"" + self.attr("label") + "\">" + self.text() + "</a></li>");
                                }
                                else {
                                    optgroup_elsubUL.append("<li value=\"" + parseInt(count + index + offset + 1) + "\"><a href=\"#\" title=\"" + self.text() + "\" rel=\"" + self.attr("label") + "\">" + self.text() + "</a></li>");
                                }
                            });
                            offset += optgroup.find("option").length - 1;
                        });
                    }
                    else {
                        //detected select
                        if (el.attr("value") == "") {
                            o.elUL.append("<li class=\"SelectUITitle\" value=\"" + parseInt(index + offset + 1) + "\"><a href=\"#\" title=\"" + el.text() + "\" rel=\"" + el.attr("label") + "\">" + el.text() + "</a></li>");
                        }
                        else {
                            var text = el.text();
                            if (text.length > 30) {
                                text = text.substring(0, Math.min(25, text.length)) + "...";
                            }
                            o.elUL.append("<li value=\"" + parseInt(index + offset + 1) + "\"><a href=\"#\" title=\"" + el.text() + "\" rel=\"" + el.attr("label") + "\">" + text + "</a></li>");
                        }
                    }
                });
                /*end. Create UL reflect <select>*/

                /*Title*/
                /*
                var title = o.elUL.children("li:first-child").text();

                o.select.find("option").each(function () {
                var option = jQuery(this);

                    if ( option.attr("value") == o.select.val() ) {
                title = option.text();
                }
                });
                */
                var title = "";
                var hasValue = false;
                o.select.find("option").each(function() {
                    var option = jQuery(this);

                    if (option.attr("selected")) {
                        title = option.text();
                        hasValue = true;
                    }
                });

                if (!hasValue) {
                    title = o.select.attr("title") != undefined ? o.select.attr("title") : o.select.find("option:first-child").text();
                }
                /*end. Title*/

                /*Disabled option*/
                if (!o.select.attr("disabled")) {
                    o.droplistTITLE.text(title);
                }
                else {
                    o.droplistTITLE.text("");
                    o.elWrapper.addClass("Disabled");
                }
                o.el.before(o.droplistTITLE);
                /*end. Disabled option*/

                /*Re-Binding events*/
                o.el.find("ul > li").each(function(index) {

                    var self = jQuery(this);

                    self.bind("click", function() {
                        if (self.find("span.OptgroupLabel:first-child").length > 0) {
                            //o.hideList();
                            return false;
                        }
                        else {
                            if (!o.select.attr("disabled")) {
                                //o.droplistTITLE.text( self.text() );
                                o.el.find("ul > li").removeClass("Active");
                                self.addClass("Active");
                                o.droplistTITLE.text(self.text());
                                o.hideList();
                                o.select.val(o.select.find("option").eq(self.attr("value") - 1).val());
                                /*call Externall Function*/

                                
                                
                                var CarnetDeBordPage = "Carnet-de-bord.aspx";
                                var AutoCOntactedPage = "midas-centre-auto-contactez-nous.aspx";
                                var isCarnetDeBordPage = false;
                                var isAutoCOntactedPage = false;

                                var thisUrl = decodeURI(window.location);
                                var pairs = thisUrl.split("/");
                                for (var value in pairs) {
                                    if (pairs[value] == CarnetDeBordPage) {
                                        isCarnetDeBordPage = true;
                                        isAutoCOntactedPage = false;
                                    }
                                    else if (pairs[value] == AutoCOntactedPage) {
                                        isCarnetDeBordPage = false;
                                        isAutoCOntactedPage = true;
                                    }
                                }

                                if (!isCarnetDeBordPage & isAutoCOntactedPage) {
                                    var thisBrowser = $.browser.msie ? "true" : "false";

                                    if (thisBrowser == "true") // IE has a problem with onchange property, lets fix it
                                    {
                                        //$(o.select).bind('propertyonchange, change, select, onselect', callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel")));
                                        $(o.select).attr("onchange", callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel")));
                                    }
                                    else //else the rest are more smart enogh to call onchange
                                    {
                                        $(o.select).change();
                                        callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
                                    }
                                }
                                else {
                                    // honnor select's onchange event
                                    $(o.select).change();
                                    callExternalFunction(o, droplistManager.els, self.find("a:first").attr("rel"));
                                }

                                // honnor select's onchange event
                                //$(o.select).change();
                                //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;
                    });
                });
                /*end. Re-Binding events*/
            }

            this.showList = function() {
                o.elWrapper.addClass("TopLevel");
                o.el.addClass("DropListUIShow");

                var reservedTop = parseInt(o.elWrapper.offset().top);
                var reservedLeft = parseInt(o.elWrapper.offset().left);

                o.reservedHolder = o.elWrapper.clone(true).empty();
                o.reservedHolder.css({
                    visibility: "hidden"
                });

                o.elWrapper.before(o.reservedHolder);

                var isFF3 = (/Firefox\/3.*/).test(window.navigator.userAgent);
                //!!! if FF3, substract the border-left/top width of all parent wrapper: bugs in offset()

                if (isFF3) {
                    var parentWrapper = o.reservedHolder.parent();
                    var borderLeftWidth = 0;
                    var borderTopWidth = 0;
                    while (parentWrapper.attr("tagName").toLowerCase() != "body") {
                        borderLeftWidth += parseInt(parentWrapper.css("borderLeftWidth"));
                        borderTopWidth += parseInt(parentWrapper.css("borderTopWidth"));
                        parentWrapper = parentWrapper.parent();
                    }

                    reservedTop -= borderTopWidth;
                    reservedLeft -= borderLeftWidth;
                }
				
                o.elWrapper.appendTo("body");
                o.elWrapper.css({
                    position: "absolute",
                    top: reservedTop,
                    left: reservedLeft,
                    margin: 0
                });
				
                o.el.show();
                o.setDirection();

                //apply jScrollPane for scrolling
                if (o.el.height() > o.maxDropListHeight) {
                    o.elUL.height(o.maxDropListHeight);

                    o.elUL.jScrollPane({
                        scrollbarWidth: o.options.scrollbarWidth,
                        scrollbarOnLeft: o.options.scrollbarSide == "left" ? true : false
                    });
                }
            }

            this.hideList = function() {
                //remove jScrollPane
                o.el.prepend(o.elUL);
                o.elUL.removeAttr("style");
                o.elUL.next().remove();
                //end. remove jScrollPane

                o.elWrapper.removeClass("TopLevel");
                o.el.removeClass("DropListUIShow");
                o.select.after(o.elWrapper.removeAttr("style"));
                o.el.hide();
                o.reservedHolder.remove();
            }

            this.setDirection = function() {
                var windowHeight = jQuery(window).height() + jQuery(document).scrollTop();
                var elPostion_Top = o.elWrapper.offset().top;
                var elPostion_Bottom = o.elWrapper.offset().top + o.elWrapper.height();
                var elULHeight = o.elUL.outerHeight();
                var direction = "";

                if (elULHeight <= windowHeight - elPostion_Bottom - jQuery(document).scrollTop()) { //no need scroll
                    //decide to go down
                    direction = "down";
                }
                else if (elULHeight < elPostion_Top - jQuery(document).scrollTop()) {
                    //decide to go up
                    direction = "up";
                }
                else if (windowHeight - elPostion_Bottom >= elPostion_Top - jQuery(document).scrollTop()) { //need scroll
                    //go down better than go up
                    direction = "down";
                    o.maxDropListHeight = windowHeight - elPostion_Bottom;
                }
                else {
                    //go up better than go down
                    direction = "up";
                    o.maxDropListHeight = elPostion_Top - jQuery(document).scrollTop();
                }
                var borderTop = typeof o.el.css("borderTopWidth") == "number"
                                        ? parseInt(o.el.css("borderTopWidth"))
                                        : 0;
                var borderBottom = typeof o.el.css("borderBottomWidth") == "number"
                                        ? parseInt(o.el.css("borderBottomWidth"))
                                        : 0;

                if (o.maxDropListHeight < o.config.maxDropListHeight) {
                    o.maxDropListHeight -= (borderTop + borderBottom);
                }
                else {
                    o.maxDropListHeight = o.config.maxDropListHeight;
                }

                /*Act on direction decision*/
                if (direction == "up") { //go up
                    o.el.css({
                        bottom: o.elWrapper.height() + "px",
                        top: "auto"
                    });
                }
                else { // go down, direction == "down"
                    o.el.css({
                        top: "100%",
                        bottom: "auto"
                    });
                }
            }

            /* end. methods */
        }

        //setup
        if (window.droplistManager == undefined) {
            window.droplistManager = new $droplist_Manager();
        }
        var options = arguments[0];
        this.each(function() {
            if (!jQuery(this).hasClass("HasSelectUI")) {
                jQuery(this).addClass("HasSelectUI");
                droplistManager.els[jQuery(this).attr("id")] = new $droplist_UI(jQuery(this), options);
            }
        });

    }
});
