/**
 * Fonctions pour chaînes
 */

/**
*
* Javascript trim, ltrim, rtrim
* http://www.webtoolkit.info/
*
*
*/
function trim(str, chars) {
    return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}


/**
 * Tronque une chaîne et ajoute éventuellement " [...]".
 *
 * N'ajoute " [...]" que si la chaîne est effectivement tronquée. Dans ce cas,
 * " [...]" est inclus dans le calcul de la longueur maximale.
 *
 * Exemple :
 * <code>
 * var sChaine = "Salut les terriens !";
 *
 * alert(sChaine.tronquer(10));
 * // Affiche : Salu [...]
 *
 * alert(sChaine.tronquer(50));
 * // Affiche : Salut les terriens !
 * </code>
 *
 * @author Régis
 * @param int iLongueur longueur max de la chaîne renvoyée, " [...]" inclus
 * @return str la chaîne tronquée
 */
String.prototype.tronquer=function(iLongueur) {
    var sChaine = this;
    if (iLongueur != undefined && sChaine.length > iLongueur) {
        return sChaine.substr(0, iLongueur-6)+" [...]";
    } else {
        return sChaine;
    }
}

/**
 * Fonction serialize compatible PHP.
 *
 * Linéarise un objet, le transformant en chaîne.
 *
 * ATTENTION : PHP a un bogue d'encodage UTF-8.
 * En PHP, serialize('Olé') renvoie 's:4:"Olé";' et non 's:3:"Olé";' car
 * le caractère 'é' est codé sur 2 octets, en UTF-8.
 * Pour parer aux bogues des caractères multi-octets, PHP a réécrit un certain
 * nombre de fonctions (cf. http://fr.php.net/mb_string). Mais serialize() n'a
 * pas été réécrit.
 * Pour être compatible PHP, cette fonction Javascript accepte un second
 * paramètre. S'il est passé à TRUE, il reproduit l'erreur de PHP (nécessite
 * la fonction Javascript Utf8.encode()).
 *
 * Exemple :
 * <code>
 * var sChaine = "Olé";
 *
 * alert(serialize(sChaine));
 * // Affiche : s:3:"Olé";
 *
 * alert(serialize(sChaine, true));
 * // Affiche : s:4:"Olé";
 * </code>
 *
 *
 * @author XoraX <xxorax@gmail.com> & Régis
 * @url http://www.xorax.info/blog/programmation/40-javascript-serialize-php.html
 * @version 1.2 - 2007/04/23
 * @todo vérifier si prend en compte les objects
 */
function serialize(oObj, bPhpCompatible)
{
    if (bPhpCompatible == undefined) {
        bPhpCompatible = false;
    }

    switch (typeof(oObj)) {
        case 'string':
            if (bPhpCompatible) {
                return 's:'+Utf8.encode(oObj).length+':"'+oObj+'";';
            } else {
                return 's:'+oObj.length+':"'+oObj+'";';
            }
        case 'number':
            if(oObj>=0 && String(oObj).indexOf('.') == -1 && oObj < 65536) return 'i:'+oObj+';';
            return 'd:'+oObj+';';
        case 'boolean':
            return 'b:'+( (oObj)?'1':'0' )+';';
        case 'object':
            var i=0,k,ret='';
            for(k in oObj){
                if (!isNaN(k)) {
                    k = Number(k);
                }
                ret += serialize(k, bPhpCompatible)+serialize(oObj[k], bPhpCompatible);
                i++;
            }
            return 'a:'+i+':{'+ret+'}';
        default:
            return 'N;';
            alert('var undefined: '+typeof(oObj));return undefined;
    }
}

/**
 * Fonction de délinéarisation compatible PHP.
 *
 * Bogué avec la valeur undefined, notamment dans tableaux.
 *
 * @see serialize()
 */
function unserialize(txt, bPhpCompatible){
    var level=0,arrlen=new Array(),del=0,final=new Array(),key=new Array(),save=txt;
    while(1){
        switch(txt.substr(0,1)){
            case 'N':
                del = 2;
                ret = null;
            break;
            case 'b':
                del = txt.indexOf(';')+1;
                ret = (txt.substring(2,del-1) == '1')?true:false;
            break;
            case 'i':
                del = txt.indexOf(';')+1;
                ret = Number(txt.substring(2,del-1));
            break;
            case 'd':
                del = txt.indexOf(';')+1;
                ret = Number(txt.substring(2,del-1));
            break;
            case 's':
                del = txt.substr(2,txt.substr(2).indexOf(':'));
                if (bPhpCompatible) {
                    ret = Utf8.decode(Utf8.encode(txt).substr( 1+Utf8.encode(txt).indexOf('"'),del));
                } else {
                    ret = txt.substr( 1+txt.indexOf('"'),del);
                }
                del = txt.indexOf('"')+ 1 + ret.length + 2;
            break;
            case 'a':
                del = txt.indexOf(':{')+2;
                ret = new Array();
                arrlen[level+1] = Number(txt.substring(txt.indexOf(':')+1, del-2))*2;
            break;
            case 'O':
                txt = txt.substr(2);
                var tmp = txt.indexOf(':"')+2;
                var nlen = Number(txt.substring(0, txt.indexOf(':')));
                name = txt.substring(tmp, tmp+nlen );
                //alert(name);
                txt = txt.substring(tmp+nlen+2);
                del = txt.indexOf(':{')+2;
                ret = new Object();
                arrlen[level+1] = Number(txt.substring(0, del-2))*2;
            break;
            case '}':
                txt = txt.substr(1);
                if(arrlen[level] != 0){alert('var missed : '+save); return undefined;};
                //alert(arrlen[level]);
                level--;
            continue;
            default:
                if(level==0) return final;
                alert('syntax invalid(1) : '+save+"\nat\n"+txt+"level is at "+level);
                return undefined;
        }
        if(arrlen[level]%2 == 0){
            if(typeof(ret) == 'object'){alert('array index object no accepted : '+save);return undefined;}
            if(ret == undefined){alert('syntax invalid(2) : '+save);return undefined;}
            key[level] = ret;
        } else {
            var ev = '';
            for(var i=1;i<=level;i++){
                if(typeof(key[i]) == 'number'){
                    ev += '['+key[i]+']';
                }else{
                    ev += '["'+key[i]+'"]';
                }
            }
            eval('final'+ev+'= ret;');
        }
        arrlen[level]--;//alert(arrlen[level]-1);
        if(typeof(ret) == 'object') level++;
        txt = txt.substr(del);
        continue;
    }
}

/**
 * Encode/décode une chaîne en UTF-8.
 *
 * Source : http://www.webtoolkit.info/
 *
 * Exemple :
 * <code>
 * var sChaine = "Olé";
 * alert(Utf8.encode(sChaine));
 * // Affiche : OlÃ©
 * </code>
 *
 * @url http://www.webtoolkit.info/javascript-utf8.html
 * @author Régis
 */
var Utf8 = {
    // public method for url encoding
    encode : function (string)
    {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
        }
        return utftext;
    },

    // public method for url decoding
    decode : function (utftext)
    {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;
        while ( i < utftext.length ) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return string;
    }
}
