// ###### <select> element utilities ######
{
    // --- SORTING OPTIONS ---
    {
        function compareOptionText(a, b) {
            var aText = a.text; 
            var bText = b.text;
            
            if(!compareOptionText.isCaseSensitive) {
                aText = a.text.toLowerCase();
                bText = b.text.toLowerCase();
            }
            
            /*
             * return >0 if a>b
             * 0 if a=b
             * <0 if a<b
             */
            // textual comparison
            return aText != bText ? aText < bText ? -1 : 1 : 0;
            //return a.text!=b.text ? a.text<b.text ? -1 : 1 : 0;
            // numerical comparison
            // return a.text - b.text;
        }
        compareOptionText.isCaseSensitive = false;
        
        function sortOptions(list, isCaseSensitive) {
            var items    = list.options.length;
            var tmpArray = new Array(items);
            
            for(i = 0; i < items; i++) {
                tmpArray[i] = new Option(list.options[i].text, list.options[i].value);
            }
            
            compareOptionText.isCaseSensitive = isCaseSensitive;
            tmpArray.sort(compareOptionText);
            
            // make copies of sorted options back to list
            for(i = 0; i < items; i++) {
                list.options[i] = new Option(tmpArray[i].text, tmpArray[i].value);
            }
        }
    }
    
    // --- INDEX AND SEARCHING OPTIONS ---
    {
        /** Returns the index of the option that corresponds to the given option value.
         * If no such option exists in the given <select> element, the function will
         * return -1.
         * @param idSelect the ID of the <select> element whose options we want to look in.
         * @param optionValue the value of the option we're looking for.
         * @return the index of the requested option if it could be found ; -1 otherwise. */
        function findIndexOfOption(idSelect, optionValue) {
            var functionResult = -1;
            
            var oSelect = document.getElementById(idSelect);
            if(oSelect.options.length > 0) {
                for(var i = 0; i < oSelect.options.length; i++) {
                    var oOption = oSelect.options[i];
                    if(oOption.value === optionValue) {
                        // keep the index in memory (to return it) and exit the loop
                        functionResult = i;
                        i              = oSelect.options.length;
                    }
                }
            }
            
            return functionResult;
        }
    }
    
    // --- OPTIONS MANAGEMENT ---
    {
        function select_clearOptions(idSelect) {
            var oSelect = document.getElementById(idSelect);
            if(oSelect) {
                var iIndex;
                var oChild;
                
                for(iIndex = 0; iIndex < oSelect.childNodes.length;) {
                    oChild = oSelect.childNodes[iIndex];
                    if(oChild.value) {
                        oSelect.removeChild(oChild);
                    }
                    else {
                        ++iIndex;
                    }
                }
            }
        }
    }
    
    // --- SWITCH LIST MANAGEMENT ---
    function switchList(from,removeFrom,to,appendTo)
    {
        var oFrom = document.getElementById(from);
        var oTo = document.getElementById(to);
        
        var arrFrom = new Array();
        var arrTo = new Array();
        
        for(iOption=0; iOption < oFrom.options.length; iOption++)
        {
            if(oFrom.options[iOption].selected)
            {
                arrFrom[arrFrom.length] = oFrom.options[iOption];
                arrTo[arrTo.length] = new Option(oFrom.options[iOption].text, oFrom.options[iOption].value);
            }
        }
        
        for(iOption=0; iOption < arrFrom.length; iOption++)
        {
            if(removeFrom == 1)
            {
                oFrom.removeChild(arrFrom[iOption]);
            }
            if(appendTo == 1)
            {
                oTo.appendChild(arrTo[iOption]);
            }
        }
    }
    
    // --- MOVE LIST MANAGEMENT ---
    function moveList(p_field, p_way)
    {
        var oIndexes = new Array();
        
        var oSelect = document.getElementById(p_field);
        for(iOption=0; iOption < oSelect.options.length; iOption ++)
        {
            if(oSelect.options[iOption].selected)
            {
                oIndexes[oIndexes.length] = iOption;    
            }
        }
        
        if(p_way == 'up')
        {
            for(iOption=0; iOption < oIndexes.length; iOption ++)
            {
                iIndex = oIndexes[iOption];
                if(iIndex > 0)
                {
                    pIndex = iIndex - 1;
                    sValue = oSelect.options[pIndex].value;
                    sText = oSelect.options[pIndex].text;
                    
                    oSelect.options[pIndex].value = oSelect.options[iIndex].value;
                    oSelect.options[pIndex].text = oSelect.options[iIndex].text;
                    
                    oSelect.options[pIndex].selected = true;
                    
                    oSelect.options[iIndex].value = sValue;
                    oSelect.options[iIndex].text = sText;
                    
                    oSelect.options[iIndex].selected = false;
                }
            }
        }
        else if(p_way == 'down')
        {
            for(iOption = (oIndexes.length-1); iOption >= 0; iOption --)
            {
                iIndex = oIndexes[iOption];
                pIndex = iIndex + 1;
                if(pIndex < oSelect.options.length)
                {
                    sValue = oSelect.options[pIndex].value;
                    sText = oSelect.options[pIndex].text;
                    
                    oSelect.options[pIndex].value = oSelect.options[iIndex].value;
                    oSelect.options[pIndex].text = oSelect.options[iIndex].text;
                    
                    oSelect.options[pIndex].selected = true;
                    
                    oSelect.options[iIndex].value = sValue;
                    oSelect.options[iIndex].text = sText;
                    
                    oSelect.options[iIndex].selected = false;
                }
            }        
        }
    }
}

// ###### Children nodes management ######
{
    function deleteChildNodes(oElement) {
        if(oElement) {
            var childCount = oElement.childNodes.length;
            if(childCount > 0) {
                for(var iChild = 0; iChild < childCount; iChild += 1) {
                    var oChild = oElement.childNodes[0];
                    if(oChild) {
                        oElement.removeChild(oChild);
                    }
                }
            }
        }
    }
}

// ###### Dynamic create element ######
{
    function createElement(p_element, p_type, p_name, p_id, p_value, p_class)
    {
        var oElement = document.createElement(p_element);
        if(p_id != '')
        {
            oElement.id = p_id;
        }
        
        if(p_name != '')
        {
            oElement.name = p_name;
        }
        
        if(p_class != '')
        {
            oElement.className = p_class;
        }
        
        if(p_element == 'img')
        {
            oElement.alt = p_type;
            oElement.src = p_value;
            oElement.border = 0;
        }
        else if(p_element == 'input')
        {
            oElement.type = p_type;
            oElement.value = p_value;
        }
        else if(p_element == 'a')
        {
            oElement.href = p_value;
            oElement.title = p_type;
        }
        return oElement;
    }
    
    function createNamedElement(type, name) {
        var element = null;
        // Try the IE way; this fails on standards-compliant browsers
        try {
            element = document.createElement('<'+type+' name="'+name+'">');
        }
        catch (e) {
        }
        
        if (!element || element.nodeName != type.toUpperCase()) {
            // Non-IE browser; use canonical method to create named element
            element = document.createElement(type);
            element.name = name;
        }
        
        return element;
    }
}

// ###### Output HTML from an XML source (page description) #####
{
    function HtmlEntities(texte) {
        texte = texte.replace(/"/g,'&quot;'); // 34 22
        texte = texte.replace(/&/g,'&amp;'); // 38 26
        texte = texte.replace(/\'/g,'&#39;'); // 39 27
        texte = texte.replace(/</g,'&lt;'); // 60 3C
        texte = texte.replace(/>/g,'&gt;'); // 62 3E
        texte = texte.replace(/\^/g,'&circ;'); // 94 5E
        texte = texte.replace(//g,'&lsquo;'); // 145 91
        texte = texte.replace(//g,'&rsquo;'); // 146 92
        texte = texte.replace(//g,'&ldquo;'); // 147 93
        texte = texte.replace(//g,'&rdquo;'); // 148 94
        texte = texte.replace(//g,'&bull;'); // 149 95
        texte = texte.replace(//g,'&ndash;'); // 150 96
        texte = texte.replace(//g,'&mdash;'); // 151 97
        texte = texte.replace(//g,'&tilde;'); // 152 98
        texte = texte.replace(//g,'&trade;'); // 153 99
        texte = texte.replace(//g,'&scaron;'); // 154 9A
        texte = texte.replace(//g,'&rsaquo;'); // 155 9B
        texte = texte.replace(//g,'&oelig;'); // 156 9C
        texte = texte.replace(//g,'&#357;'); // 157 9D
        texte = texte.replace(//g,'&#382;'); // 158 9E
        texte = texte.replace(//g,'&Yuml;'); // 159 9F
        // texte = texte.replace(/ /g,'&nbsp;'); // 160 A0
        texte = texte.replace(//g,'&iexcl;'); // 161 A1
        texte = texte.replace(//g,'&cent;'); // 162 A2
        texte = texte.replace(//g,'&pound;'); // 163 A3
        //texte = texte.replace(/ /g,'&curren;'); // 164 A4
        texte = texte.replace(//g,'&yen;'); // 165 A5
        texte = texte.replace(//g,'&brvbar;'); // 166 A6
        texte = texte.replace(//g,'&sect;'); // 167 A7
        texte = texte.replace(//g,'&uml;'); // 168 A8
        texte = texte.replace(//g,'&copy;'); // 169 A9
        texte = texte.replace(//g,'&ordf;'); // 170 AA
        texte = texte.replace(//g,'&laquo;'); // 171 AB
        texte = texte.replace(//g,'&not;'); // 172 AC
        texte = texte.replace(//g,'&shy;'); // 173 AD
        texte = texte.replace(//g,'&reg;'); // 174 AE
        texte = texte.replace(//g,'&macr;'); // 175 AF
        texte = texte.replace(//g,'&deg;'); // 176 B0
        texte = texte.replace(//g,'&plusmn;'); // 177 B1
        texte = texte.replace(//g,'&sup2;'); // 178 B2
        texte = texte.replace(//g,'&sup3;'); // 179 B3
        texte = texte.replace(//g,'&acute;'); // 180 B4
        texte = texte.replace(//g,'&micro;'); // 181 B5
        texte = texte.replace(//g,'&para'); // 182 B6
        texte = texte.replace(//g,'&middot;'); // 183 B7
        texte = texte.replace(//g,'&cedil;'); // 184 B8
        texte = texte.replace(//g,'&sup1;'); // 185 B9
        texte = texte.replace(//g,'&ordm;'); // 186 BA
        texte = texte.replace(//g,'&raquo;'); // 187 BB
        texte = texte.replace(//g,'&frac14;'); // 188 BC
        texte = texte.replace(//g,'&frac12;'); // 189 BD
        texte = texte.replace(//g,'&frac34;'); // 190 BE
        texte = texte.replace(//g,'&iquest;'); // 191 BF
        texte = texte.replace(//g,'&Agrave;'); // 192 C0
        texte = texte.replace(//g,'&Aacute;'); // 193 C1
        texte = texte.replace(//g,'&Acirc;'); // 194 C2
        texte = texte.replace(//g,'&Atilde;'); // 195 C3
        texte = texte.replace(//g,'&Auml;'); // 196 C4
        texte = texte.replace(//g,'&Aring;'); // 197 C5
        texte = texte.replace(//g,'&AElig;'); // 198 C6
        texte = texte.replace(//g,'&Ccedil;'); // 199 C7
        texte = texte.replace(//g,'&Egrave;'); // 200 C8
        texte = texte.replace(//g,'&Eacute;'); // 201 C9
        texte = texte.replace(//g,'&Ecirc;'); // 202 CA
        texte = texte.replace(//g,'&Euml;'); // 203 CB
        texte = texte.replace(//g,'&Igrave;'); // 204 CC
        texte = texte.replace(//g,'&Iacute;'); // 205 CD
        texte = texte.replace(//g,'&Icirc;'); // 206 CE
        texte = texte.replace(//g,'&Iuml;'); // 207 CF
        texte = texte.replace(//g,'&ETH;'); // 208 D0
        texte = texte.replace(//g,'&Ntilde;'); // 209 D1
        texte = texte.replace(//g,'&Ograve;'); // 210 D2
        texte = texte.replace(//g,'&Oacute;'); // 211 D3
        texte = texte.replace(//g,'&Ocirc;'); // 212 D4
        texte = texte.replace(//g,'&Otilde;'); // 213 D5
        texte = texte.replace(//g,'&Ouml;'); // 214 D6
        texte = texte.replace(//g,'&times;'); // 215 D7
        texte = texte.replace(//g,'&Oslash;'); // 216 D8
        texte = texte.replace(//g,'&Ugrave;'); // 217 D9
        texte = texte.replace(//g,'&Uacute;'); // 218 DA
        texte = texte.replace(//g,'&Ucirc;'); // 219 DB
        texte = texte.replace(//g,'&Uuml;'); // 220 DC
        texte = texte.replace(//g,'&Yacute;'); // 221 DD
        texte = texte.replace(//g,'&THORN;'); // 222 DE
        texte = texte.replace(//g,'&szlig;'); // 223 DF
        texte = texte.replace(//g,'&aacute;'); // 224 E0
        texte = texte.replace(//g,'&aacute;'); // 225 E1
        texte = texte.replace(//g,'&acirc;'); // 226 E2
        texte = texte.replace(//g,'&atilde;'); // 227 E3
        texte = texte.replace(//g,'&auml;'); // 228 E4
        texte = texte.replace(//g,'&aring;'); // 229 E5
        texte = texte.replace(//g,'&aelig;'); // 230 E6
        texte = texte.replace(//g,'&ccedil;'); // 231 E7
        texte = texte.replace(//g,'&egrave;'); // 232 E8
        texte = texte.replace(//g,'&eacute;'); // 233 E9
        texte = texte.replace(//g,'&ecirc;'); // 234 EA
        texte = texte.replace(//g,'&euml;'); // 235 EB
        texte = texte.replace(//g,'&igrave;'); // 236 EC
        texte = texte.replace(//g,'&iacute;'); // 237 ED
        texte = texte.replace(//g,'&icirc;'); // 238 EE
        texte = texte.replace(//g,'&iuml;'); // 239 EF
        texte = texte.replace(//g,'&eth;'); // 240 F0
        texte = texte.replace(//g,'&ntilde;'); // 241 F1
        texte = texte.replace(//g,'&ograve;'); // 242 F2
        texte = texte.replace(//g,'&oacute;'); // 243 F3
        texte = texte.replace(//g,'&ocirc;'); // 244 F4
        texte = texte.replace(//g,'&otilde;'); // 245 F5
        texte = texte.replace(//g,'&ouml;'); // 246 F6
        texte = texte.replace(//g,'&divide;'); // 247 F7
        texte = texte.replace(//g,'&oslash;'); // 248 F8
        texte = texte.replace(//g,'&ugrave;'); // 249 F9
        texte = texte.replace(//g,'&uacute;'); // 250 FA
        texte = texte.replace(//g,'&ucirc;'); // 251 FB
        texte = texte.replace(//g,'&uuml;'); // 252 FC
        texte = texte.replace(//g,'&yacute;'); // 253 FD
        texte = texte.replace(//g,'&thorn;'); // 254 FE
        texte = texte.replace(//g,'&yuml;'); // 255 FF
        
        return texte;
    }
    
    function html_entity_decode(text, receiverId) {
        var result = "";
        
        // get the receiver and put only a textarea inside of it
        var oReceiver       = document.getElementById(receiverId);
        oReceiver.innerHTML = "<textarea id='html_entity_decoder'>" + text + "</textarea>";
        
        // get the textarea we just created
        var oTextArea = document.getElementById("html_entity_decoder");
        
        // get the decoded string
        result = oTextArea.value;
        
        // reset the receiver's contents
        oReceiver.innerHTML = "";
        
        return result;
    }
}

// ###### Converse file size to string ######
{
    function convertFileSize(sSize)
    {
        iSize = sSize;
        if(iSize > 1000000)
        {
            strSize = (iSize / 1000 / 1000).toFixed(2) + " Mo";    
        }
        else
        {
            strSize = (iSize / 1000).toFixed(2) + " Ko";    
        }
        return strSize;
    }
}

// ###### String prototype ######
{
    /* From : http://www.somacon.com/p355.php */
    String.prototype.trim = function() {
    	return this.replace(/^\s+|\s+$/g,"");
    }
    String.prototype.ltrim = function() {
    	return this.replace(/^\s+/,"");
    }
    String.prototype.rtrim = function() {
    	return this.replace(/\s+$/,"");
    }
}

// ###### Array prototype ######
{    
    Array.prototype.in_array = function ( obj ) {
        var len = this.length;
        for(var x = 0; x <= len; x++) {
            if(this[x] == obj) {
                return true;
            }
        }
        return false;
    }
    
    Array.prototype.removeItems = function(itemsToRemove) {
        if (!/Array/.test(itemsToRemove.constructor)) {
            itemsToRemove = [ itemsToRemove ];
        }
        
        var j;
        for(var i = 0; i < itemsToRemove.length; i++) {
            j = 0;
            while(j < this.length) {
                if(this[j] == itemsToRemove[i]) {
                    this.splice(j, 1);
                }
                else {
                    j++;
                }
            }
        }
    }
}

// ##### INPUT UTILITIES #####
{
    function stopReturnKey(evt) {
        var evt  = (evt) ? evt : ((event) ? event : null);
        var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
        if ((evt.keyCode == 13) && (node.type=="text")) { return false; }
    }
}

// ###### Number prototype ######
{
    Number.prototype.formatMoney = function(c, d, t) {
        var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
        return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t)
        + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
    };
}
