
/****************************************************
base64 stuff:
---------
A JavaScript library for base64 encoding and decoding
by Danny Goodman (http://www.dannyg.com).

Described in "JavaScript and DHTML Cookbook" published by
O'Reilly & Associates. Copyright 2003.

Release History
---------------
v.1.00    07Apr2003    First release

****************************************************/
// Global lookup arrays for base64 conversions
var enc64List, dec64List;
// Load the lookup arrays once
function initBase64() {
    enc64List = new Array();
    dec64List = new Array();
    var i;
    for (i = 0; i < 26; i++) {
        enc64List[enc64List.length] = String.fromCharCode(65 + i);
    }
    for (i = 0; i < 26; i++) {
        enc64List[enc64List.length] = String.fromCharCode(97 + i);
    }
    for (i = 0; i < 10; i++) {
        enc64List[enc64List.length] = String.fromCharCode(48 + i);
    }
    enc64List[enc64List.length] = "+";
    enc64List[enc64List.length] = "/";
    for (i = 0; i < 128; i++) {
        dec64List[dec64List.length] = -1;
    }
    for (i = 0; i < 64; i++) {
        dec64List[enc64List[i].charCodeAt(0)] = i;
    }
}

function base64Encode(str) {
    var c, d, e, end = 0;
    var u, v, w, x;
    var ptr = -1;
    var input = str.split("");
    var output = "";
    while(end == 0) {
        c = (typeof input[++ptr] != "undefined") ? input[ptr].charCodeAt(0) : 
            ((end = 1) ? 0 : 0);
        d = (typeof input[++ptr] != "undefined") ? input[ptr].charCodeAt(0) : 
            ((end += 1) ? 0 : 0);
        e = (typeof input[++ptr] != "undefined") ? input[ptr].charCodeAt(0) : 
            ((end += 1) ? 0 : 0);
        u = enc64List[c >> 2];
        v = enc64List[(0x00000003 & c) << 4 | d >> 4];
        w = enc64List[(0x0000000F & d) << 2 | e >> 6];
        x = enc64List[e & 0x0000003F];
        
        // handle padding to even out unevenly divisible string lengths
        if (end >= 1) {x = "=";}
        if (end == 2) {w = "=";}
        
        if (end < 3) {output += u + v + w + x;}
    }
    // format for 76-character line lengths per RFC
    var formattedOutput = "";
    var lineLength = 76;
    while (output.length > lineLength) {
    	formattedOutput += output.substring(0, lineLength) + "\n";
    	output = output.substring(lineLength);
    }
    formattedOutput += output;
    return formattedOutput;
}

function base64Decode(str) {
    var c=0, d=0, e=0, f=0, i=0, n=0;
    var input = str.split("");
    var output = "";
    var ptr = 0;
    do {
        f = input[ptr++].charCodeAt(0);
        i = dec64List[f];
        if ( f >= 0 && f < 128 && i != -1 ) {
            if ( n % 4 == 0 ) {
                c = i << 2;
            } else if ( n % 4 == 1 ) {
                c = c | ( i >> 4 );
                d = ( i & 0x0000000F ) << 4;
            } else if ( n % 4 == 2 ) {
                d = d | ( i >> 2 );
                e = ( i & 0x00000003 ) << 6;
            } else {
                e = e | i;
            }
            n++;
            if ( n % 4 == 0 ) {
                output += String.fromCharCode(c) + 
                          String.fromCharCode(d) + 
                          String.fromCharCode(e);
            }
        }
    }
    while (typeof input[ptr] != "undefined");
    output += (n % 4 == 3) ? String.fromCharCode(c) + String.fromCharCode(d) : 
              ((n % 4 == 2) ? String.fromCharCode(c) : "");
    return output;
}

// Self-initialize the global variables
initBase64();


/**
 * every heard of the return key?
 * http://xmlrpccom.sourceforge.net/scriptserver/scriptserver/examples/serialize.php
 *
 */
//Number.prototype.toPHP=function(){if(Math.round(this)==this){return 'i:'+this+';';}else{return 'd:'+this+';';};};String.prototype.toPHP=function(){var s=this;var utf8s="";for(var n=0;n<s.length;n++){var c=s.charCodeAt(n);if(c<128){utf8s+=String.fromCharCode(c);}else if((c>127)&&(c<2048)){utf8s+=String.fromCharCode((c>>6)|192);utf8s+=String.fromCharCode((c&63)|128);}else{utf8s+=String.fromCharCode((c>>12)|224);utf8s+=String.fromCharCode(((c>>6)&63)|128);utf8s+=String.fromCharCode((c&63)|128);}
//}
//return 's:'+utf8s.length+':"'+utf8s+'";';};Boolean.prototype.toPHP=function(){if(this==true){return 'b:1;';}else{return 'b:0;';};};Function.prototype.toPHP=function(){return 'N;';};Array.prototype.toPHP=function(){var a=this;var indexed=new Array();var count=a.length;var s='';for(var i=0;i<a.length;i++){indexed[i]=true;s+='i:'+i+';'+a[i].toPHP();};for(var prop in a){if(prop=='var_dump'||prop=='toPHP'){continue;};if(indexed[prop]){continue;};s+=prop.toPHP()+a[prop].toPHP();count++;};s='a:'+count+':{'+s;s+='}';return s;};Object.prototype.toPHP=function(){var o=this;var cname='ScriptServer_Object';if(o==null)return 'N;';var s='';var count=0;for(var prop in o){if(prop=='var_dump'||prop=='toPHP'){continue;};s+='s:'+prop.length+':"'+prop+'";';if(o[prop]!=null){s+=o[prop].toPHP();}else{s+='N;';};count++;};s='O:'+cname.length+':"'+cname.toLowerCase()+'":'+count+':{'+s+'}';return s;};Error.prototype.toPHP=function(){var e=this;var cname='ScriptServer_Error';var s='';s+='s:4:"name";';s+=e.name.toPHP();s+='s:7:"message";';s+=e.message.toPHP();s='O:'+cname.length+':"'+cname.toLowerCase()+'":2:{'+s+'}';return s;};


Number.prototype.toPHP=function(){
    if(Math.round(this)==this){
        return 'i:'+this+';';
    }else{
        return 'd:'+this+';';
    };
};
String.prototype.toPHP=function(){
    var s=this;
    var utf8s="";
    for(var n=0;n<s.length;n++){
        var c=s.charCodeAt(n);
        if(c<128){
            utf8s+=String.fromCharCode(c);
        }else if((c>127)&&(c<2048)){
            utf8s+=String.fromCharCode((c>>6)|192);
            utf8s+=String.fromCharCode((c&63)|128);
        }else{
            utf8s+=String.fromCharCode((c>>12)|224);
            utf8s+=String.fromCharCode(((c>>6)&63)|128);
            utf8s+=String.fromCharCode((c&63)|128);
        }
    }
    return 's:'+utf8s.length+':"'+s+'";';
};
Boolean.prototype.toPHP=function(){
    if(this==true){
        return 'b:1;';
    }else{
        return 'b:0;';
    };
};
Function.prototype.toPHP=function(){
    return 'N;';
};

function array2PHP(a){
    var indexed=new Array();
    var count=a.length;
    var s='';
    for(var i=0;i<a.length;i++){
        indexed[i]=true;s+='i:'+i+';'+a[i].toPHP();
    };
    /*
    for(var prop in a){
        if(prop=='var_dump'||prop=='toPHP'){
            continue;
        };
        if(indexed[prop]){
            continue;
        };
        s+=prop.toPHP()+a[prop].toPHP();
        count++;
    };
    */
    s='a:'+count+':{'+s;s+='}';
    return s;
}

/*
Array.prototype.toPHP=function(){
    var a=this;
    var indexed=new Array();
    var count=a.length;
    var s='';
    for(var i=0;i<a.length;i++){
        indexed[i]=true;s+='i:'+i+';'+a[i].toPHP();
    };
    for(var prop in a){
        if(prop=='var_dump'||prop=='toPHP'){
            continue;
        };
        if(indexed[prop]){
            continue;
        };
        s+=prop.toPHP()+a[prop].toPHP();
        count++;
    };
    s='a:'+count+':{'+s;s+='}';
    return s;
};
Object.prototype.toPHP=function(){
    var o=this;
    var cname='ScriptServer_Object';
    if(o==null)return 'N;';
    var s='';
    var count=0;
    for(var prop in o){
        if(prop=='var_dump'||prop=='toPHP'){
            continue;
        };
        s+='s:'+prop.length+':"'+prop+'";';
        if(o[prop]!=null){
            s+=o[prop].toPHP();
        }else{
            s+='N;';
        };
        count++;
    };
    s='O:'+cname.length+':"'+cname.toLowerCase()+'":'+count+':{'+s+'}';
        return s;
};
Error.prototype.toPHP=function(){
    var e=this;
    var cname='ScriptServer_Error';
    var s='';
    s+='s:4:"name";';s+=e.name.toPHP();s+='s:7:"message";';
    s+=e.message.toPHP();
    s='O:'+cname.length+':"'+cname.toLowerCase()+'":2:{'+s+'}';
    return s;
};
*/

/**
 * http://www.crockford.com/JSON/js.html
 */
function stringify(arg) {
    var i, o, v;

    switch (typeof arg) {
    case 'object':
        if (arg) {
            if (arg.constructor == Array) {

                o = '[';
                for (i = 0; i < arg.length; ++i) {
                    v = stringify(arg[i]);
                    if (v != 'function' && !isUndefined(v)) {
                        o += (o != '[' ? ',' : '') + v;
                    } else {
                        o += ',';
                    }
                }
                return o + ']';
            } else if (typeof arg.toString != 'undefined') {
                o = '{';
                for (i in arg) {
                    v = stringify(arg[i]);
                    if (v != 'function' && !isUndefined(v)) {
                        o += (o != '{' ? ',' : '') + 
                            i.quote() + ':' + v;
                    }
                }
                return o + '}';
            } else {
                return;
            }
        }
        return 'null';
    case 'unknown':
    case 'undefined':
        return;
    case 'string':
        return arg.quote();
    case 'function':
        return 'function';
    default:
        return String(arg);
    }
}

/**
 * needed for stringify above
 *
 */
function isUndefined(a) {
    return typeof a == 'undefined';
} 
