/*Written 2003 Johannes Hauf (hauf@arsnavigandi.de)
Version 2.0 - Last modified 15.11.2005
These are JS-methods to connect Javascript and Flash
When You embed your movie be sure you have the following in the "object" tag:
id="myMovie" (DO NOT SET the name-attribute in the "object"-tag (Mozilla)
In the "embed"-tag you need both: id and name.
If you want use a othe name than "myMovie" You have to replace all items.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
This version is not compatible to the versions prior 2.0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Version history:
1.0 initial release
1.1 added support for multiple Arguments from AS to JS, removed some bugs
1.2 Fixed a bug in transferring special cahracters from flash to js
1.3 Allowed communication between browser and the flash movie on mac
1.4 Fixed a compile bug with Flash 7. Call onFlashInit in JS when loaded
2.0 Added handshaking, call Backs from Flash etc.,
*/


/*Check if client is a mac. If this is true we need very
special methods to allow communication between actionscript and javascript*/
var isMac = false;
if (navigator.platform.indexOf('Mac') > -1) {
	isMac = true;
}

/**
 * Method Caller
 * This javascript function calls any actionscript-method/-function
 * whithin a given movie
 * 
 * @param movieId the movieId on which to call the method
 * @param method this is the full name of the function within the movie (_root.myFunction)
 * @param callBackMethod optional parameter - the name of the method called by flash when flash
 *        made the function call
 * @param argument0-9 up to 10 arguments which are passed to the function
 *        (if you need more arguments just copy and paste ;-))
 **/
function methodCaller(movieId, method, callBackMethod, argument0, argument1, argument2, argument3, argument4,
												argument5, argument6, argument7, argument8, argument9)
{
	if(callBackMethod == '' || callBackMethod == undefined) {
		callBackMethod = 'onFlashExecute';
	}
	var browser = "";
	if(isMac == true && browser != 'ns') {
		macMethodCaller(movieId, method, callBackMethod, argument0, argument1, argument2, argument3, argument4,
												argument5, argument6, argument7, argument8, argument9);
	} else {
		window.document[movieId].SetVariable("_root.JS.method", method);
		window.document[movieId].SetVariable("_root.JS.callBackMethod", callBackMethod);
		window.document[movieId].SetVariable("_root.JS.argument0", trimLineEnding(argument0));
		window.document[movieId].SetVariable("_root.JS.argument1", trimLineEnding(argument1));
		window.document[movieId].SetVariable("_root.JS.argument2", trimLineEnding(argument2));
		window.document[movieId].SetVariable("_root.JS.argument3", trimLineEnding(argument3));
		window.document[movieId].SetVariable("_root.JS.argument4", trimLineEnding(argument4));
		window.document[movieId].SetVariable("_root.JS.argument5", trimLineEnding(argument5));
		window.document[movieId].SetVariable("_root.JS.argument6", trimLineEnding(argument6));
		window.document[movieId].SetVariable("_root.JS.argument7", trimLineEnding(argument7));
		window.document[movieId].SetVariable("_root.JS.argument8", trimLineEnding(argument8));
		window.document[movieId].SetVariable("_root.JS.argument9", trimLineEnding(argument9));
		window.document[movieId].TCallFrame("_root.JS", 1);
	}
}

/**
 * Called automatically when methodCaller was invoked and no other function was defined for callBack
 * 
 * @param movieId the movieId on which the method was called
 * @param fileName the fileName of the movieClip on which the method was called
 * @param the full name of the function that was called in the movie
 * @param result the result of the flash function as string
 **/
function onFlashExecute(movieId, fileName, methodName, result) {
	/*var str = "movieId: "+movieId+",\nfileName: "+fileName+"\nmethodName: "+methodName+"\nresult: "+result;
	if(browser == 'ie' || (isMac == true && browser != 'mo')) {
		window.document.myForm.user_input.value = unescape(str);
	} else {
		window.document.myForm.user_input.value = decode_utf8(unescape(str));
	}*/
}

/**
 * Special method caller for the macintosh this only works via a gateway movie.
 * Be sure to have the gateway-movie in the same directory as your manMovie
 **/
function macMethodCaller(movieId, method, callBackMethod, argument0, argument1, argument2, argument3, argument4,
													argument5, argument6, argument7, argument8, argument9)
{	
	var divcontainer = "flash_setvariables_"+movieId+"_"+method;
	if(!document.getElementById(divcontainer)){
		var divholder = document.createElement("div");
		divholder.id = divcontainer;
		document.body.appendChild(divholder);
	}
	document.getElementById(divcontainer).innerHTML = "";
	var divinfo = "<embed src='/extras/js2swf/gateway.swf' FlashVars='lc="+movieId+
		"&method="+escape(method)+
		"&callBackMethod="+escape(callBackMethod)+
		"&argument0="+escape(argument0)+
		"&argument1="+escape(argument1)+
		"&argument2="+escape(argument2)+
		"&argument3="+escape(argument3)+
		"&argument4="+escape(argument4)+
		"&argument5="+escape(argument5)+
		"&argument6="+escape(argument6)+
		"&argument7="+escape(argument7)+
		"&argument8="+escape(argument8)+
		"&argument9="+escape(argument9)+
		"' width='0' height='0' type='application/x-shockwave-flash'></embed>";
	document.getElementById(divcontainer).innerHTML = divinfo;
}


//Called when the flash movie has initialized itself
// the name of the swf
function onFlashInit(n){
	window.status = n+" loaded and initialized!";
}



/**
 * Tries to initialize a handsahke between javascript and a given movie
 *
 * @param movieId the movieId to initialize the handshake with.
 * @param callBack (optional) the method to call when handshaking is finished
 *        if You overwrite this method be sure to clear the handShakeInterval
 * @param duration (optional) the time period for trying handshaking (default is 5000 milliseconds)
 * @param retries (optional) how many retries shoud be taken (default is 10);
 * @param retryCounter only used internally!
 **/
var handShakeInterval;
function handShake(movieId, callBack, duration, retries, retryCounter) {
	//alert("beginning handshake");
	window.clearInterval(handShakeInterval);
	retryCounter = retryCounter == undefined ? 0 : retryCounter;
	retryCounter++;
	if(retryCounter > retries) {
		onHandShake(movieId,'','this.handShake','false');
		return;
	}
	callBack = callBack == undefined ? 'onHandShake' : callBack;
	duration = duration == undefined ? 5000 : duration;
	retries = retries == undefined ? 10 : retries;
	handShakeInterval = window.setInterval("handShake('"+movieId+"','"+callBack+"',"+duration+","+retries+","+retryCounter+")",Math.round(duration/retries));
	try {
		methodCaller(movieId,'this.handShake','onHandShake');
	} catch (e) {}
	//alert("done handshake");
}

/**
 * Called automatically when handshaking has finished
 *
 * @param movieId the movieId on which handshaking was tried
 * @param fileName the fileName of the movieClip on which handshaking was tried
 * @param the function name in flash that was invoked for handshaking
 * @param the result of the handshaking as STRING: true = success, false = failure
 **/
function onHandShake(movieId, fileName, methodName, result) {
	window.clearInterval(handShakeInterval);
	alert("Result of Handshake: "+result);
}

//Sets all properties in movie/object
function setProperty(movieId, property, value){
	if(isMac == true && browser != 'ns') {
		setMacProperty(movieId, property, value);
	} else {
		window.document[movieId].SetVariable(property, value);
	}
}

//Sets properties on mac
function setMacProperty(movieId, property, value){
	var divcontainer = "flash_setvariables_"+movieId;
	if(!document.getElementById(divcontainer)){
		var divholder = document.createElement("div");
		divholder.id = divcontainer;
		document.body.appendChild(divholder);
	}
	document.getElementById(divcontainer).innerHTML = "";
	var divinfo = "<embed src='gateway.swf' FlashVars='lc="+movieId+
		"&property="+escape(property)+
		"&value="+escape(value)+
		"' width='0' height='0' type='application/x-shockwave-flash'></embed>";
	document.getElementById(divcontainer).innerHTML = divinfo;
}

//This method replaces the windows line-ending "\r\n" by "\n" (UNIX)
function trimLineEnding(text){
	var mytext = ""+text;
	var mytext = mytext.replace(/\r\n/g,"\n");
	return (mytext);
}

/*It is important to "escape" text or other variables in Flash.
Only when the Argument is "escaped", ist is possibe to transmit special characters
like "'" or linefeeds*/

function copyTextToHTML(text){
	if(browser == 'ie' || (isMac == true && browser != 'mo')) {
		window.document.myForm.user_input.value = unescape(text);
	} else {
		window.document.myForm.user_input.value = decode_utf8(unescape(text));
	}
}

//Text encoding in UTF-8
function encode_utf8(rohtext) {
	// dient der Normalisierung des Zeilenumbruchs
	rohtext = rohtext.replace(/\r\n/g,"\n");
	var utftext = "";
	for(var n=0; n<rohtext.length; n++)
		{
		// ermitteln des Unicodes des  aktuellen Zeichens
		var c=rohtext.charCodeAt(n);
		// alle Zeichen von 0-127 => 1byte
		if (c<128)
			utftext += String.fromCharCode(c);
		// alle Zeichen von 127 bis 2047 => 2byte
		else if((c>127) && (c<2048)) {
			utftext += String.fromCharCode((c>>6)|192);
			utftext += String.fromCharCode((c&63)|128);}
		// alle Zeichen von 2048 bis 66536 => 3byte
		else {
			utftext += String.fromCharCode((c>>12)|224);
			utftext += String.fromCharCode(((c>>6)&63)|128);
			utftext += String.fromCharCode((c&63)|128);}
		}
	return utftext;
}

//Text decoding in UTF-8
function decode_utf8(utftext) {
	var plaintext = ""; var i=0; var c=c1=c2=0;
	// while-Schleife, weil einige Zeichen uebersprungen werden
	while(i<utftext.length)
		{
		c = utftext.charCodeAt(i);
		if (c<128) {
			plaintext += String.fromCharCode(c);
			i++;}
		else if((c>191) && (c<224)) {
			c2 = utftext.charCodeAt(i+1);
			plaintext += String.fromCharCode(((c&31)<<6) | (c2&63));
			i+=2;}
		else {
			c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2);
			plaintext += String.fromCharCode(((c&15)<<12) | ((c2&63)<<6) | (c3&63));
			i+=3;}
		}
	return plaintext;
}
