/*
        Alternative Select List v0.5 by frequency-decoder.com

        Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)

        Please credit frequency-decoder in any derivative work - thanks.

        You are free:

        * to copy, distribute, display, and perform the work
        * to make derivative works
        * to make commercial use of the work

        Under the following conditions:

                by Attribution.
                --------------
                You must attribute the work in the manner specified by the author or licensor.

                sa
                --
                Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.

        * For any reuse or distribution, you must make clear to others the license terms of this work.
        * Any of these conditions can be waived if you get permission from the copyright holder.
*/

var fdMultiSelect;

(function() {

function fdNewMultiSelect(selectList) {
        this.select = selectList;
        this.selectId = selectList.id;

        this.optGroupLabels = new Array();
        this.viewSequential = selectList.className.search("fd-auto-collapse") != -1;

        var o = this;

        o.createNewSelectOptions = function() {
                var wrapperType = o.select.className && o.select.className.search(/fd-wrapper-([u|o])l/) != -1 ? o.select.className.match(/fd-wrapper-([u|o])l/)[0].replace('fd-wrapper-', '') : 'div';
                var brackets    = o.select.multiple && o.select.className && o.select.className.search(/fd-add-square-brackets/) != -1 ? "[]" : "";
                var optGroups   = o.select.getElementsByTagName("optgroup");

                for(var i = 0, optGroup; optGroup = optGroups[i]; i++) {

                        o.optGroupLabels[o.optGroupLabels.length] = optGroup.label.toLowerCase();

                        var wrapperElem = document.createElement(wrapperType);
                        wrapperElem.className = "fd-multi-select-wrapper";
                        if(i % 2 == 0) wrapperElem.className += " fd-wrapper-alt";
                        wrapperElem.id = "fd-multi-select-optgroup-" + o.selectId + "-" + i;

                        var titleElem = document.createElement("div");
                        titleElem.className = "fd-multi-select-title";
                        titleElem.id = "fd-multi-select-title-" + o.selectId + "-" + i;
                        titleElem.appendChild(document.createTextNode(optGroup.label + String.fromCharCode(160)));

                        titleElem.appendChild(document.createElement("span"));

                        var optGroupButton = document.createElement("button");
                        optGroupButton.className = "fd-multi-select-button";
                        optGroupButton.id = "fd-multi-select-button-" + o.selectId + "-" + i;
                        optGroupButton.appendChild(document.createTextNode("Edit Selections"));
                        optGroupButton.onclick = o.expandCollapse;

                        o.select.parentNode.insertBefore(titleElem, o.select);
                        o.select.parentNode.insertBefore(optGroupButton, o.select);
                        o.select.parentNode.insertBefore(wrapperElem, o.select);

                        var options = optGroup.getElementsByTagName("option");

                        var checkBox, label;

                        // force a sequential view for radio buttons
                        if(!o.select.multiple && o.select.className.search(/fd-auto-collapse/) == -1) {
                                o.viewSequential = true;
                        }

                        for(var j = 0, option; option = options[j]; j++) {

                                var elemT = "input";
                                var value = option.value || option.text;

                                // Internet Explorer hackery (See http://channel9.msdn.com/wiki/default.aspx/Channel9.InternetExplorerProgrammingBugs)
                                /*@cc_on@*/
                                /*@if (@_jscript_version <= 5.6)
                                if(!o.select.multiple) elemT = "<input type='radio' name='"+o.select.name+"' value='"+ value +"' />";
                                /*@end@*/

                                checkBox         = document.createElement(elemT);

                                // Internet Explorer will throw an error if the element is a radio button - such is life...
                                try {
                                        checkBox.type = o.select.multiple ? "checkbox" : "radio";
                                } catch (e) {}

                                if(Boolean(option.selected)) {
                                        checkBox.defaultChecked = true;
                                }
                                
                                checkBox.name    = o.select.name + brackets;
                                checkBox.value   = value;
                                checkBox.id      = o.select.name + "-" + o.selectId + "-" + i + "-" + j;
                                label            = document.createElement("label");

                                label.appendChild(document.createTextNode(String.fromCharCode(160) + option.text));
                                label.htmlFor = o.select.name + "-" + o.selectId + "-" + i  + "-" + j;

                                var tmp = document.createElement(wrapperType != "div" ? "li" : "div");

                                tmp.appendChild(checkBox);
                                tmp.appendChild(label);
                                wrapperElem.appendChild(tmp);
                        }

                        o.collapseGroup(i);
                };
                o.removeSelect();
        };

        o.removeSelect = function() {
                // Remove the associated selectlist label and the selectlist from the DOM
                
                // 1. Select wrapped within the label tag (deprecated as of HTML4)
                // N.B. We just check the parent node and don't traverse the DOM (which we really should do)
                if(o.select.parentNode.tagName == "label") {
                        label.parentNode.removeChild(label);
                        o.select = null;
                        return;
                }
                
                // 2. Label with a "for" attribute equal to the selectlists id
                if(o.select.id) {
                        var labels = document.getElementsByTagName("label");
                        for(var i = 0, label; label = labels[i]; i++) {
                                // IE requires the htmlFor test
                                if(label.htmlFor && label.htmlFor == o.select.id) {
                                        label.parentNode.removeChild(label);
                                        break;
                                } else if(label.getAttribute("for") == o.select.id) {
                                        label.parentNode.removeChild(label);
                                        break;
                                }
                        }
                }

                // Remove the selectlist
                o.select.parentNode.removeChild(o.select);
                o.select = null;
        }

        o.collapseGroup = function(which) {
                var wrapper = document.getElementById("fd-multi-select-optgroup-" + o.selectId + "-" + which);
                var title   = document.getElementById("fd-multi-select-title-" + o.selectId + "-" + which);
                var button  = document.getElementById("fd-multi-select-button-" + o.selectId + "-" + which);
                var span    = title.getElementsByTagName("span")[0];
                var txt     = ": ";
                
                while(span.firstChild) span.removeChild(span.firstChild);
                var checkBoxs = wrapper.getElementsByTagName("input");

                for(var i = 0, checkBox; checkBox = checkBoxs[i]; i++) {
                        if(checkBox.checked) {
                                txt += o.trim(checkBox.parentNode.getElementsByTagName("label")[0].firstChild.nodeValue.toString()) + "; ";
                        }
                }

                // Remove the trailing semi-colon
                if(txt.length > 2) txt = txt.substring(0, txt.length - 2);

                span.appendChild(document.createTextNode(txt == ": " ? ": Please click \u201cEdit Selections\u201d to specify." : txt));

                wrapper.style.display = "none";
                button.removeChild(button.firstChild);
                button.appendChild(document.createTextNode("Edit Selections"));

                span.style.display = "inline";
        };

        o.expandGroup = function(which) {
                var wrapper = document.getElementById("fd-multi-select-optgroup-" + o.selectId + "-" + which);
                var title   = document.getElementById("fd-multi-select-title-" + o.selectId + "-" + which);
                var button  = document.getElementById("fd-multi-select-button-" + o.selectId + "-" + which);
                var span    = title.getElementsByTagName("span")[0];

                span.style.display = "none";

                wrapper.style.display = "block";
                button.removeChild(button.firstChild);
                button.appendChild(document.createTextNode("Close"));
        };

        o.expandCollapse = function() {
                var label = this.id.replace("fd-multi-select-button-" + o.selectId + "-", "");
                var id    = "fd-multi-select-optgroup-" + o.selectId + "-" + label;

                if(o.viewSequential) {
                        for(var i = 0; i < o.optGroupLabels.length; i++) {
                                if(i != label) {o.collapseGroup(i);};
                        };
                };

                if(document.getElementById(id).style.display == "block") o.collapseGroup(label);
                else o.expandGroup(label);

                return false;
        };

        o.trim = function(txt) {
                return txt.replace(/^\s+|\s+$/, '');
        };
        
        o.createNewSelectOptions();
};

fdMultiSelect = {
        uniqueId:0,
        init: function(e) {
                var selects = document.getElementsByTagName("select");
                var i = selects.length;
                var optGroups;
                
                while(i--) {
                        var select = selects[i];
                        if(select.disabled || select.className.search("fd-multi-select") == -1) continue;
                        if(!select.id) select.id = "fd-select-id-" + fdMultiSelect.uniqueId++;
                        if(select.getElementsByTagName("optgroup").length) (function() {new fdNewMultiSelect(select);})();
                };
        }
};

})();

window.onload = fdMultiSelect.init;


