/*

/**
 * Create a new Exception object.
 * name: The name of the exception.
 * message: The exception message.
 */
function Exception(name, message){
    if (name)	this.name = name;
    if (message)this.message = message;
};
Exception.prototype.setName=function(name){  	this.name=name;			};
Exception.prototype.getName=function(){    		return this.name;		};
Exception.prototype.setMessage=function(msg){   this.message=msg;		};
Exception.prototype.getMessage=function(){    	return this.message;	};



/**
 * Generates a browser-specific Flash tag. Create a new instance, set whatever
 * properties you need, then call either toString() to get the tag as a string, or
 * call write() to write the tag out.
 */

/**
 * Creates a new instance of the FlashTag.
 * src: The path to the SWF file.
 * width: The width of your Flash content.
 * height: the height of your Flash content.
 */
function FlashTag(src,width,height){
    this.src       	= src;
    this.width     	= width;
    this.height    	= height;
    this.version   	= '7,0,14,0';
    this.id        	= null;
	this.bgcolor   	= '#FFFFFF';
    //this.wmode	   	= 'opaque'; // transparent
	this.quality	= 'high';
    this.flashVars 	= null;
	this.addDate	= false;
	this.date 	 	= new Date();
};

FlashTag.prototype.setVersion=function(v){ 	 		this.version=v;			};
FlashTag.prototype.setId=function(id){	    		this.id=id;				};
FlashTag.prototype.setBgcolor=function(bgc){   	 	this.bgcolor=bgc;		};
FlashTag.prototype.setFlashvars=function(fv){   	this.flashVars=fv;		};
FlashTag.prototype.setWidth=function(w){    		this.width=w;			};
FlashTag.prototype.setHeight=function(h){    		this.height=h;			};
//FlashTag.prototype.setOpacity=function(opacity){	this.wmode=opacity;		};
FlashTag.prototype.setQuality=function(quality){	this.quality=quality;	};
FlashTag.prototype.addDate=function(addDate){   	this.addDate=addDate;	};

/**
 * Get the Flash tag as a string. 
 */
FlashTag.prototype.toString = function(){
    var ie=(navigator.appName.indexOf("Microsoft")!=-1)?1:0;
    var flashTag=new String();
    if(ie){
        flashTag += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
        if (this.id!=null)
            flashTag += 'id="'+this.id+'" ';
        flashTag += 'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version='+this.version+'" ';
        flashTag += 'width="'+this.width+'" ';
        flashTag += 'height="'+this.height+'">';
       	if(!this.addDate)
        	flashTag += '<param name="movie" value="'+this.src+'"/>';
		else
			flashTag += '<param name="movie" value="'+this.src+'?t='+this.date.getTime()+'"/>';
        flashTag += '<param name="quality" value="'+this.quality+'"/>';
        //if(this.wmode=='transparent')
		//	flashTag += '<param name="wmode" value="'+this.wmode+'"/>';
		//else {
			if(this.bgcolor.match('#'))
				flashTag += '<param name="bgcolor" value="'+this.bgcolor+'"/>';
		//}
        if (this.flashVars!=null)
            flashTag += '<param name="flashvars" value="'+this.flashVars+'"/>';
        flashTag += '</object>';
    } else {
       	if(!this.addDate)
			flashTag += '<embed src="'+this.src+'" ';
   		else 
			flashTag += '<embed src="'+this.src+'?t='+this.date.getTime()+'" ';
        flashTag += 'quality="'+this.quality+'" '; 
        flashTag += 'width="'+this.width+'" ';
        flashTag += 'height="'+this.height+'" ';
		//if(this.wmode=='transparent')
		//	flashTag += 'wmode="'+this.wmode+'" ';
        //else {
			if(this.bgcolor.match('#'))
				flashTag += 'bgcolor="'+this.bgcolor+'" ';
		//}
		flashTag += 'type="application/x-shockwave-flash" ';
        if (this.flashVars != null)
            flashTag += 'flashvars="'+this.flashVars+'" ';
        if (this.id != null)
            flashTag += 'name="'+this.id+'" ';
        flashTag += 'pluginspage="http://www.macromedia.com/go/getflashplayer">';
        flashTag += '</embed>';
    }
    return flashTag;
}

/**
 * Write the Flash tag out. Pass in a reference to the document to write to. 
 */
FlashTag.prototype.write=function(doc){
    doc.write(this.toString());
};

/**
 * 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;');
}

/**
 * The FlashProxy object is what proxies function calls between JavaScript and Flash.
 * It handles all argument serialization issues.
 */

/**
 * Instantiates a new FlashProxy object. Pass in a uniqueID and the name (including the path)
 * of the Flash proxy SWF. The ID is the same ID that needs to be passed into your Flash content as lcId.
 */
function FlashProxy(uid, proxySwfName)
{
    this.uid = uid;
    this.proxySwfName = proxySwfName;
    this.flashSerializer = new FlashSerializer(false);
}

/**
 * Call a function in your Flash content.  Arguments should be:
 * 1. ActionScript function name to call,
 * 2. any number of additional arguments of type object,
 *    array, string, number, boolean, date, null, or undefined. 
 */
FlashProxy.prototype.call = function()
{

    if (arguments.length == 0)
    {
        throw new Exception("Flash Proxy Exception",
                            "The first argument should be the function name followed by any number of additional arguments.");
    }

    var qs = 'lcId=' + escape(this.uid) + '&functionName=' + escape(arguments[0]);

    if (arguments.length > 1)
    {
        var justArgs = new Array();
        for (var i = 1; i < arguments.length; ++i)
        {
            justArgs.push(arguments[i]);
        }
        qs += ('&' + this.flashSerializer.serialize(justArgs));
    }

    var divName = '_flash_proxy_' + this.uid;
    if(!document.getElementById(divName))
    {
        var newTarget = document.createElement("div");
        newTarget.id = divName;
        document.body.appendChild(newTarget);
    }
    var target = document.getElementById(divName);
    var ft = new FlashTag(this.proxySwfName, 1, 1);
    ft.setVersion('6,0,65,0');
    ft.setFlashvars(qs);
    target.innerHTML = ft.toString();
}

/**
 * This is the function that proxies function calls from Flash to JavaScript.
 * It is called implicitly.
 */
FlashProxy.callJS = function()
{
    var functionToCall = eval(arguments[0]);
    var argArray = new Array();
    for (var i = 1; i < arguments.length; ++i)
    {
        argArray.push(arguments[i]);
    }
    functionToCall.apply(functionToCall, argArray);
}


