/**

 * The FlashSerializer serializes JavaScript variables of types object, array, string,

 * number, date, boolean, null or undefined into XML. 

 */



/**

 * Create a new instance of the FlashSerializer.

 * useCdata: Whether strings should be treated as character data. If false, strings are simply XML encoded.

 */

function FlashSerializer(useCdata)

{

    this.useCdata = useCdata;

}



/**

 * Serialize an array into a format that can be deserialized in Flash. Supported data types are object,

 * array, string, number, date, boolean, null, and undefined. Returns a string of serialized data.

 */

FlashSerializer.prototype.serialize = function(args)

{

    var qs = new String();



    for (var i = 0; i < args.length; ++i)

    {

        switch(typeof(args[i]))

        {

            case 'undefined':

                qs += 't'+(i)+'=undf';

                break;

            case 'string':

                qs += 't'+(i)+'=str&d'+(i)+'='+escape(args[i]);

                break;

            case 'number':

                qs += 't'+(i)+'=num&d'+(i)+'='+escape(args[i]);

                break;

            case 'boolean':

                qs += 't'+(i)+'=bool&d'+(i)+'='+escape(args[i]);

                break;

            case 'object':

                if (args[i] == null)

                {

                    qs += 't'+(i)+'=null';

                }

                else if (args[i] instanceof Date)

                {

                    qs += 't'+(i)+'=date&d'+(i)+'='+escape(args[i].getTime());

                }

                else // array or object

                {

                    try

                    {

                        qs += 't'+(i)+'=xser&d'+(i)+'='+escape(this._serializeXML(args[i]));

                    }

                    catch (exception)

                    {

                        throw new Exception("FlashSerializationException",

                                            "The following error occurred during complex object serialization: " + exception.getMessage());

                    }

                }

                break;

            default:

                throw new Exception("FlashSerializationException",

                                    "You can only serialize strings, numbers, booleans, dates, objects, arrays, nulls, and undefined.");

        }



        if (i != (args.length - 1))

        {

            qs += '&';

        }

    }



    return qs;

}



/**

 * Private

 */

FlashSerializer.prototype._serializeXML = function(obj)

{

    var doc = new Object();

    doc.xml = '<fp>'; 

    this._serializeNode(obj, doc, null);

    doc.xml += '</fp>'; 

    return doc.xml;

}



/**

 * Private

 */

FlashSerializer.prototype._serializeNode = function(obj, doc, name)

{

    switch(typeof(obj))

    {

        case 'undefined':

            doc.xml += '<undf'+this._addName(name)+'/>';

            break;

        case 'string':

            doc.xml += '<str'+this._addName(name)+'>'+this._escapeXml(obj)+'</str>';

            break;

        case 'number':

            doc.xml += '<num'+this._addName(name)+'>'+obj+'</num>';

            break;

        case 'boolean':

            doc.xml += '<bool'+this._addName(name)+' val="'+obj+'"/>';

            break;

        case 'object':

            if (obj == null)

            {

                doc.xml += '<null'+this._addName(name)+'/>';

            }

            else if (obj instanceof Date)

            {

                doc.xml += '<date'+this._addName(name)+'>'+obj.getTime()+'</date>';

            }

            else if (obj instanceof Array)

            {

                doc.xml += '<array'+this._addName(name)+'>';

                for (var i = 0; i < obj.length; ++i)

                {

                    this._serializeNode(obj[i], doc, null);

                }

                doc.xml += '</array>';

            }

            else

            {

                doc.xml += '<obj'+this._addName(name)+'>';

                for (var n in obj)

                {

                    if (typeof(obj[n]) == 'function')

                        continue;

                    this._serializeNode(obj[n], doc, n);

                }

                doc.xml += '</obj>';

            }

            break;

        default:

            throw new Exception("FlashSerializationException",

                                "You can only serialize strings, numbers, booleans, objects, dates, arrays, nulls and undefined");

            break;

    }

}



/**

 * Private

 */

FlashSerializer.prototype._addName= function(name)

{

    if (name != null)

    {

        return ' name="'+name+'"';

    }

    return '';

}



/**

 * Private

 */

FlashSerializer.prototype._escapeXml = function(str)

{

    if (this.useCdata)

        return '<![CDATA['+str+']]>';

    else

        return str.replace(/&/g,'&amp;').replace(/</g,'&lt;');

}



