/* version: Update November 4, 2009. ()*/
/**
This JavaScript file contains functions to install octoshape on windows by a signed applet.
It requires 2 files to be present:
	- octoinit.jar
	- octoinstall.jar
**/
function octopv_installjar(){
	var variant = (typeof octoshapeVariant == 'string')?octoshapeVariant:""; 
	var platformAdd =  octopv_appletDoMac()?"-mac":"";
	return 'http://'+octopv_baseWebPath+'/files/octosetup'+variant+platformAdd+'.jar';
}

function octopv_installcode(){
	var platformAdd =  octopv_appletDoMac()?"Mac":"";
	return 'octoshape.applets.OctoInstallApplet'+platformAdd+'.class';
}

var octopv_appletAreWorking=false;
var octopv_topObject = new Object();
octopv_topObject.installCompleted=null;
octopv_topObject.testCompleted=null; 
octopv_topObject.testCompletedCount=100; 
octopv_topObject.testAppletDiv=null; 
octopv_topObject.preloadCompleted=null; 
octopv_topObject.preloadAppletDiv=null; 
octopv_topObject.progress=null;
octopv_topObject.waitFinishedCount=0;

/** 
 * Test and preload in one.
 * Function answerFunction(boolean): if we could do applet install or not (if true also means that preloading is done)
 * 
 * Function progressFunction(String s): gets progress messages (or user error messages, or usage errors).
 * (or the id of a div). 
 * */
function octopv_appletTestAndPreload(div1,div2,answerFunction, progressFunction){
	var runNum=0;
	octopv_debug('Doing applet test.', arguments.callee);
	octopv_doAppletTest(div1,function(testInt){
		runNum++;
		octopv_debug('Applet test done: '+testInt+'. runNum: '+runNum, arguments.callee);
		if(testInt==0){
			octopv_debug('Proceeding with next step after applet test. runNum: '+runNum, arguments.callee);
			//Proceeding with next step 
			progressFunction("Initializing installation");

			octopv_doAppletPreload(div2,function(){
				octopv_debug('Preload done. ', arguments.callee);
				answerFunction(true); // all is well
			});
		}else{
			if(testInt>0){
				progressFunction("Testing system requirements");
			}else{
				octopv_debug('Should now stop applets: '+testInt+'. runNum: '+runNum, arguments.callee);
				answerFunction(false);
			}
		}
	});
}


/**
	progressFunc must take 1 argument(string).
*/
function octopv_setProgressFunction(progressFunc){
	octopv_topObject.progress=progressFunc;
}


/** if indiv is null, we write directly 
	Firefox needs two different div for the applets.  
		If an applet is remove by overwriting its parent div (with innerHTML), firefox crashes!
	onComplete must be a function taking an int (or not defined):
		-1: we could not use applet install
		 0: testing is done ok
		>0: we are testing
*/
function octopv_doAppletTest(indiv, onComplete){
	// we insert the small init applet to test if we have applet support.
	octopv_topObject.testAppletDiv=indiv; 
	octopv_topObject.testCompleted=onComplete;
	if(!octopv_appletTestSub_init()) return; // returning if there is already some loop waiting for a reply from a test applet.
	if(!octopv_canDoAppletInstall()){
		octopv_appletTestSub_stop(-1);
		return;
	}
	
	var html='';
	if(navigator.userAgent.toLowerCase().indexOf("msie") != -1){
		// browser is IE:
		octopv_debug("inserting test applet ie tag", arguments.callee);
		html += '<OBJECT ';
		html += 'NAME="octopv_testapplet" ';
		html += 'ID="octopv_testapplet" ';
	  	html += 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ';
		html += 'width="1" height="1"> ';
		html += '<PARAM NAME="code" value="'+octopv_initcode()+'" /> ';
		html += '<PARAM NAME="archive" VALUE="'+octopv_initjar()+'" />';
	  	html += '<PARAM NAME="mayscript" VALUE="true" />';
	  	html += '<PARAM NAME="callbackstring" VALUE="init" />';
	  	html += octopv_appletDebugParams(true);
		html += '</OBJECT> ';
	}else{
		// not IE:
		octopv_debug("inserting test applet non-ie tag", arguments.callee);
		html += '<applet code="'+octopv_initcode()+'" '; 
		html += 'width="1" height="1" ';
		html += 'archive="'+octopv_initjar()+'" ';
        html += 'scriptable="true" ';
        html += 'mayscript="true" ';
		html += 'callbackstring="init" ';
	  	html += octopv_appletDebugParams(false);
		html += '>';
		html += '<PARAM name="callbackstring" value="init">';	// mac os safari needs params in this way
	  	html += octopv_appletDebugParams(true);
		html += '</applet>';
	}
	octopv_debug('html len: '+html.length+' jar from: '+octopv_initjar(), arguments.callee);
	octopv_writeToDiv(indiv, html);
	octopv_appletTestSub();
}

/** if indiv is null, we write directly
 * 	Firefox needs two different div for the applets. 
		If an applet is remove by overwriting its parent div (with innerHTML), firefox crashes!
	onComplete must be a function taking no arguments
	*/
function octopv_doAppletPreload(indiv, onComplete){
	// we begin by inserting the small init applet to test if we have applet support.
	octopv_topObject.preloadAppletDiv=indiv; 
	octopv_topObject.preloadCompleted=onComplete;

	var html='';
	if(navigator.userAgent.toLowerCase().indexOf("msie") != -1){
		// browser is IE:
		octopv_debug("inserting init applet ie tag", arguments.callee);
		html += '<OBJECT NAME="octopv_initapplet"';
	  	html += 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ';
		html += 'width="1" height="1" > ';
		html += '<PARAM NAME="code" value="'+octopv_initcode()+'" /> ';
		html += '<PARAM NAME="archive" VALUE="'+octopv_initjar()+'" />';
		html += '<PARAM NAME="cache_archive_ex" VALUE="'+octopv_installjar()+';preload" />';
	  	html += '<PARAM NAME="mayscript" VALUE="true" />';
	  	html += '<PARAM NAME="callbackstring" VALUE="preload" />';
	  	html += octopv_appletDebugParams(true);
		html += '</OBJECT> ';
	}else{
		// not IE:
		octopv_debug("inserting init applet non-ie tag", arguments.callee);
		html += '<embed code="'+octopv_initcode()+'" '; 
		html += 'width="1" height="1" type="application/x-java-applet;version=1.1" ';
		html += 'pluginspage="http://java.sun.com/javase/downloads/" ';
		html += 'archive="'+octopv_initjar()+','+octopv_installjar()+'" ';
        html += 'scriptable="true" ';
        html += 'mayscript="true" ';
		html += 'callbackstring="preload" ';
	  	html += octopv_appletDebugParams(false);
		html += '/>';
	}
	octopv_debug('html len: '+html.length+' init-jar:'+octopv_initjar()+' install-jar:'+octopv_installjar(), arguments.callee);
	octopv_writeToDiv(indiv, html);
}


/** if indiv is null, we write directly
 * 	onComplete must be a function taking an int (or not defined):
	* 		  - 4: installation error ... disk?
	* 		  - 3: user denied applet security
	* 		  - 2: eula not accepted
	* 		  (- 1: could not do applet install)
	* 		    >0: all is well and finished with the install and this is the port to bind to
	*/
function octopv_doAppletInstall(indiv, onComplete, progressFunction){
	if(arguments[1] instanceof Function){
		octopv_topObject.installCompleted=onComplete;
	}
	if(progressFunction instanceof Function){
		octopv_setProgressFunction(progressFunction);
	}else if(arguments.length == 4){
		octopv_setProgressFunction(function(str){
			octopv_writeToDiv(progressFunction,str);
		});
	}

	var html='';
	if(navigator.userAgent.toLowerCase().indexOf("msie") != -1){
		// browser is IE:
		html += '<OBJECT NAME="octopv_applet"';
	  	html += 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ';
		html += 'width="1" height="1"> ';
		html += '<PARAM NAME="code" value="'+octopv_installcode()+'"> ';
		html += '<PARAM NAME="archive" VALUE="'+octopv_initjar()+','+octopv_installjar()+'">';
	  	html += '<PARAM NAME="mayscript" VALUE="true">';
	  	html += '<PARAM NAME="NAME" VALUE="'+octopv_appletDisplayName+'">';
	  	if(arguments.length == 4){
			html += '<PARAM name="'+param1+'" VALUE="'+value1+'"/>';
		}
	  	html += octopv_appletDebugParams(true);
		html += '</OBJECT> ';
		octopv_debug("inserting object install applet ie tag", arguments.callee);
	}else{
		// not IE:
		html += '<embed code="'+octopv_installcode()+'" '; 
		html += 'NAME="'+octopv_appletDisplayName+'" ';
		html += 'width="1" height="1" type="application/x-java-applet;version=1.1" ';
		html += 'pluginspage="http://java.sun.com/javase/downloads/" ';
		html += 'archive="'+octopv_initjar()+','+octopv_installjar()+'" ';
        html += 'scriptable="true" ';
        html += 'mayscript="true" ';
		html += 'callbackstring="install" ';
	  	html += octopv_appletDebugParams(false);
		html += '/>';
		octopv_debug("html len "+html.length+" install-jar: "+octopv_installjar(), arguments.callee);
	}
	octopv_writeToDiv(indiv, html);
}

/** 
 * 	might give false positive answer, but never false negative.
*/
function octopv_canDoAppletInstall(){
	var userAgent = navigator.userAgent.toLowerCase();
	function thisIs(str){ return (userAgent.indexOf(str) != -1); }
	if(thisIs("windows") || thisIs("mac os x")){
		if(!window.navigator.javaEnabled()){
			if(thisIs("windows") && thisIs("firefox")){
				octopv_debug("Java does not appear to be enabled, but we have windows+firefox, so we try anyway.", arguments.callee);
			 	return true;
			}else{
				octopv_debug("Can not do applet install since java is not enabled."+window.navigator.javaEnabled(), arguments.callee);
			 	return false;
			}
		}
		return true;
	}else{
		// not windows and not mac os x.
		octopv_debug("Can not do applet install since OS is not windows or mac os x ", arguments.callee);
		return false;
	}
}



/************************** PRIVATE FUNCTIONS ***********************************/

/** private 
 * return true if it is ok to proceed and start up a octopv_appletTestSub()
 * make the call to  octopv_appletTestSub() from the same context.
 * */
function octopv_appletTestSub_init(){
	if(	octopv_topObject.testCompletedCount<100) return false;
	octopv_topObject.testCompletedCount=20;
	return true;
}

function octopv_appletTestSub_stop(status){
	octopv_debug("Stooping loop with: "+status+" has complete-function: "+(octopv_topObject.testCompleted!=null), arguments.callee);
	if(status!=-1 && octopv_topObject.testCompleted==null){
		octopv_debug("applet test completed ok, but to late!.", arguments.callee);
	}
	octopv_topObject.testCompletedCount=-1;
	if(octopv_topObject.testCompleted !=null && arguments.length == 1){
		octopv_topObject.testCompleted(status);
		octopv_topObject.testCompleted = null;
	}
}

 
/** private */
function octopv_appletTestSub(){
	var state=-1;
	try{
		state = document.getElementById("octopv_testapplet").readyState;
	}catch(ex){}
	octopv_debug("loop left: "+octopv_topObject.testCompletedCount+" / state: "+state, arguments.callee);
	if(octopv_topObject.testCompletedCount<0) return; // we are done, no more recursion.
	
	// if count is 0 we finish.
	// if count is 6 (we have waited 3 secs) we continue to loop only if the state shows that the applet is being loaded.
	//		If state is still 0 (uninitialised) or we could not get the state (it is -1), as we cant in fx, we finish.
	if(octopv_topObject.testCompletedCount==0||(octopv_topObject.testCompletedCount==8 && state<=0)){
		octopv_debug("calling testCompleted(-1)", arguments.callee);
		// we are done, no more recursion. 
		// And we delete the callback so it will not be called from the applet callback 
		// (this could happen if the applet was very slow in starting up).
		octopv_appletTestSub_stop(-1);
	}else{
		octopv_topObject.testCompletedCount--;
		window.setTimeout("octopv_appletTestSub();",500);
	}
}

/*********************** APPLET CALLBACK FUNCTIONS ******************************/


/**
	called by install applet
*/
function octopv_appletProgress(message){
	octopv_debug("applet install progress: "+message+"", arguments.callee);
	if(octopv_topObject.progress != null){
		octopv_topObject.progress(message);
	}
}

/**
	called by install applet
	0: ok, <0 not ok. 
	result might be a string
*/
function octopv_installAppletFinishedInstall(result){
	octopv_debug("applet finished install: "+result, arguments.callee);
	if(octopv_topObject.installCompleted!=null){
		var r = parseInt(result);
		if(r>=0 && window.octopv_pluginLauncherApplet){
			window.octopv_preferencePluginLaunch_cookieSetCanUse("Applet");
		}
		octopv_topObject.installCompleted(r);
	}
}

/** called by applet */
function octopv_initAppletInited(callbackstring, javaMajor, javaMinor, javaMicro, osVersion){
	octopv_debug("applet working answer from "+callbackstring, arguments.callee);
	if(arguments.length==4){
		octopv_debug('System info: java version 1.'+javaMajor+'.'+javaMinor+'_'+javaMicro, arguments.callee);
	}
	octopv_appletAreWorking = true;
	if(callbackstring == 'init'){
		// 0 means that all is well, that is, that we can do applet install and should proceed with preload etc.
		var reportBackStatus = 0; 
		var userAgent = navigator.userAgent.toLowerCase();
		function thisIs(str){ return (userAgent.indexOf(str) != -1); }
		if(arguments.length==5 && thisIs("mac os x")){
			// the user.agent detection of os version is not perfect for mac, 
			// so we might have some pre-10.4 users to deny auto-install here.
			function hasVersion(str){ return (osVersion.indexOf(str) != -1); }
			if(hasVersion("10.0")||hasVersion("10.1")||hasVersion("10.2")||hasVersion("10.3")){
				reportBackStatus=-1; // we report that we can not do applet install
			}
		}else if(arguments.length==4 && thisIs("msie") && thisIs("windows nt 6.0")){
			// we are on vista and have ie 
			/* if java version is 1.6.0_07 or prior we can not do applet install 
			 since that java does not use vistas broker process */
			try{
				var major = parseInt(javaMajor);
				var minor = parseInt(javaMinor);
				var micro = parseInt(javaMicro);
					
				if(major < 6 || (major==6 && minor==0 && micro < 8)){
					// we are on vista and have ie and have a too old java version!
					octopv_debug("no applet install since: vista + ie + java<=1.6.0_07: "+major+"/"+minor+"/"+micro, arguments.callee);
					reportBackStatus=-1; // we report that we can not do applet install
				}
			}catch(ex){
				octopv_debug("Error parsing java version: "+ex, arguments.callee);
			}
		}
		octopv_appletTestSub_stop(reportBackStatus); // we report that all is well.
	}else if(callbackstring == 'preload'){ 
		if(octopv_topObject.preloadCompleted!=null){
			octopv_topObject.preloadCompleted();
		}
	}else{
		octopv_debug("unrecognized callback string: "+callbackstring, arguments.callee);
	}
}

function octopv_appletDoMac(){
	var userAgent = navigator.userAgent.toLowerCase();
	if(userAgent.indexOf("mac os x") == -1) return false;
	//we are on mac, now to determine if we are on at least 10.4
	if(userAgent.indexOf("safari") != -1) {
		// we know that safari 2.0 was shipped with 10.4 and that it doesent work with 10.3
		return userAgent.indexOf("safari/1") == -1;
	}
	if(userAgent.indexOf("firefox") != -1) {
		if(userAgent.indexOf("intel mac os x") != -1){
			return true;
		}
	}
	// we return true here and perform an extra test in the init-applet
	return true;
}

window.octopv_fileInitInstallerApplet=true; 


