//	install type
var KRInstallType = {Null:-1, A1:1, A2:2, B1:3, B2:4, C1:5}
//	available install method
var KRInstallMethod = {Null:-1, ActiveX:1, ManualAndDitect:2, Manual:3}

var krinsobj 					= new KRInsObj();
var os								= krinsobj.getOS();
var browser						= krinsobj.getBrowser();
var install_type 			= KRInstallType.Null;
var install_method		= KRInstallMethod.Null;
var license_server 		= "";
var success_url				= "";
var error_url					= "";
var redirect_time     = 0;
var activex_codebase	= "krins.cab#Version=1,0,0,21";
var keyringlib_name		= "";
var eula_agreement		= false;
var debug_enable			= false;
//	DOM element name
var elm_msg1					= "";
var elm_msg2					= "";
var elm_activex				= "";
var elm_nsplugin			= "";
var elm_debug					=	"";

//	print message
function print(msg, element_name) {
	if(!msg) {msg = "";}
	if(!element_name) {element_name = elm_msg1;}
	if(element_name) {
		$(element_name).innerHTML += msg;
	} else {
		document.write(msg);
	}
}
	
//	print debug message
function printdbg(msg) {
	if(debug_enable) {print(msg + "<br>", $(elm_debug));}
}

//	redirect page
//	time: wait second.
function redirect(url, time) {
	if(url.length > 0) {
		if(time >= 0) {   
			print(time + MSG_REDIRECT1 + "<br>");
			print("<p class='bt_box'><a href=" + url + ">" + MSG_REDIRECT2 + "</a></p>");
			setTimeout(function() {location.href=url}, time * 1000);
		} else {
			print("<p class='bt_box'><a href=" + url + ">" + MSG_CLICK_HERE + "</a></p>");
		}
	} else {
		print("<h2>" + MSG_CLOSE_WINDOW + "</h2>");
	}
}
	
//	success
function success() {
	print("<br>");
	print("<h2 class='complete'>" + MSG_COMPLETE + "</h2>");
	redirect(success_url, redirect_time);
}
	
//	error
//	msg:	error message
function error(msg) {
	print("<br>");
	print(msg == "[Cancel]" ? "<h2>" + MSG_CANCEL + "</h2>" : "<h2>" + MSG_ERROR_OCCURED + msg + "</h2>");
	redirect(error_url, 10);
}
	
// 	error(no supported OS)
function errorNoSupportedOS() {
	print("<br>");
	print("<h4>" + MSG_NO_SUPPORT_OS + "</h4>");
	redirect(error_url, 10);
}

// 	error(no supported Browser)
function errorNoSupportedBrowser() {
	print("<br>");
	print("<h4>" + MSG_NO_SUPPORT_BROWSER + "</h4>");
	redirect(error_url, 10);
}
	
//	check parameter
function checkParams() {
	//	invalid parameter
	if(license_server.length <= 0) {throw new Error("parameter \"license_server\" not specified.");}
	if(install_type == KRInstallType.Null) {throw new Error("parameter \"install_type\" not specified.");}
	//	*not supported yet
	if(install_type == KRInstallType.B2) {throw new Error("\"install_type\" B2 not supported.");}
}

//	check OS supported
//	return: true, false
function checkOS() {
	//	old windows(9x)
	if(os == "Windows" && krinsobj.isOldWindows()) {return false;}
	//	check
	switch(install_type) {
	case KRInstallType.A1:
		if(os == "Windows") {return true;}
		break;
	case KRInstallType.A2:	
		if(os == "Windows" || os == "Mac") {return true;}
		break;
	case KRInstallType.B1: 
		if(os == "Windows") {return true;}
		break;
	case KRInstallType.B2:	
		if(os == "Windows") {return true;}
		break;
	case KRInstallType.C1:	
		if(os == "Windows" || os == "Mac") {return true;}
		break;
	default: throw new Error("invalid install_type: " + install_type);
	}
	return false;
}
	
//	check Browser supported
//	return: true, false
function checkBrowser() {
	//	windows
	if(os == "Windows") {
		switch(browser) {
		case "IE":
		case "Firefox":
		//case "Chrome":
			return true;
		}
	} 
	//	mac
	else if(os == "Mac") {
		switch(browser) {
		case "Safari":
		case "Firefox":
			return true;
		}
	}
	return false;
}
	
//	get available install method
//	return: KRInstallMethod
function getAvailableInstallMethod() {
	//	windows
	if(os == "Windows") {
		switch(browser) {
		case "IE":	
			return KRInstallMethod.ActiveX;
		case "Firefox":
		case "Safari":
		case "Chrome":
			return KRInstallMethod.ManualAndDitect;
		}
	}
	//	mac
	else if(os == "Mac") {
		switch(browser) {
		case "Firefox":
		case "Safari":
			return KRInstallMethod.ManualAndDitect;
		}
	}
	return KRInstallMethod.Manual;
}

//  get element value from xml
function getElementValue(xml, element_name) {
  var begin, end;
  begin = xml.indexOf("<" + element_name + ">");
  if(begin == -1) {return "";}
  end = xml.indexOf("</" + element_name + ">");
  if(end == -1) {return "";}
  begin += element_name.length + 2;
  return xml.substr(begin, end - begin);
}

////////////////////////////////////////////////////////////////////////////
//	install by ActiveX
function installActiveX() {

	//	array for functions
	var func_array = new Array();

	//  install application
	function install() {
		//  installer command-line option
		var install_option = "/silent";
		// 	change command-line option for create new process(C1 only)
		if(install_type == KRInstallType.C1 && success_url.length > 0) {
			install_option += " /new_ie " + success_url;
			success_url = "";
		}
		if(!eula_agreement) {
			eula_agreement = true;
			var script_install = "try{krinsobj.installApp('" + install_option + "');} catch(e){$(elm_msg2).innerHTML = ''; error(e.message);}";
			var script_cancel = "try{throw new Error('[Cancel]');} catch(e){$(elm_msg2).innerHTML = ''; error(e.message);}";
			print("<h4 class='notice'><span class='color_red'>" + MSG_APP_NOT_INSTALLED_LATEST + "</span><br />" + MSG_PLEASE_INSTALL + "</h4>", elm_msg2);
			print("<div class='eula'>", elm_msg2);
			print("<textarea readonly>" + MSG_GET_URLA + "</textarea><br>", elm_msg2);
			print("<input type=\"button\" value=\"" + MSG_INSTALL_AGREE + "\" onClick=\"" + script_install + "\">", elm_msg2);
			print("<input type=\"button\" value=\"" + MSG_INSTALL_NON_AGREE + "\" onClick=\"" + script_cancel + "\"><br>", elm_msg2);
			print("</div>", elm_msg2);
		} 
		else {
			krinsobj.installApp(install_option);
		}
	}

	//  check application
	function checkInstall(app_internal_name, app_display_name)
	{
		//  install ok
		function installOK() {
			$(elm_msg2).innerHTML = "";
			print("<p class='color_pk check'>" + MSG_APP_INSTALLED + "</p>");
			func_array.shift()();
		}
			
		try {
			krinsobj.writeActiveX(activex_codebase, "activex", {onSuccess:installOK});
			krinsobj.setLicenseServer(license_server);
			print("<h3>" + app_display_name + "</h3>");
			krinsobj.setAppName(app_internal_name);
			var check_app_version = krinsobj.checkAppVersion();
			if(krinsobj.getInstalledVer() != "0.0") {
				print("<p class='color_pk check'>" + MSG_INSTALLED_VERSION + krinsobj.getInstalledVer() + "</p>");
			}
			print(" <p class='check_ng'>" + MSG_LATEST_VERSION + krinsobj.getLatestVer() + "</p>");
			if(check_app_version) {
				installOK();
			} else {
				install();
			}
		} 
		catch(e) {
			error(e.message);
		}
	}

	//  check and instal ActiveX
	function checkActiveX() {
		// 	install ok
		function checkOK() {
			$(elm_msg2).innerHTML = "";
			print("<p class='color_pk check'>" + MSG_APP_INSTALLED + "</p>");
			func_array.shift()();
		}
		//  check and install
		print("<h3>" + MSG_PRODUCT_NAME_ACTIVEX + "</h3>");
    krinsobj.writeActiveX(activex_codebase, elm_activex);
		if(krinsobj.isActivexAvailable()) {
			checkOK();
		} else {
			print("<h4>" + MSG_REQUIRE_ACTIVEX_INSTALL + "</h4>", elm_msg2);
			print(MSG_GET_ACTIVEX, elm_msg2);
			//  wait until installation complete
			var timer_id = setInterval(function() {
				if(krinsobj.isActivexAvailable()) {
					clearInterval(timer_id);
					checkOK();
				}
			}, 1000);
		}
	}
	
	//	regist install function	and start
	function beginInstall()
	{
		//	function for application install
		var krpdf_func = function() {checkInstall("KRMDecryptor", MSG_PRODUCT_NAME_KRPDF);}
		var krlib_func = function() {checkInstall(keyringlib_name, MSG_PRODUCT_NAME_KRLIB);}
		var krfla_func = function() {checkInstall("KeyringFlashDecryptorIE", MSG_PRODUCT_NAME_KRFLA);}
		//	regist functions
		func_array.push(function() {checkActiveX();});
		switch(install_type) {
		case KRInstallType.A1:	
			func_array.push(krpdf_func);
			break;
		case KRInstallType.A2:	
			func_array.push(krfla_func);
			break;
		case KRInstallType.B1:
			func_array.push(krpdf_func);
			func_array.push(krlib_func);
			break;
		case KRInstallType.B2:
			func_array.push(krfla_func);
			func_array.push(krlib_func);
			break;
		case KRInstallType.C1:
			func_array.push(krfla_func);
			break;
		default: throw new Error("invalid install_type: " + install_type);
		}
		func_array.push(function() {success();});
		//	start
		func_array.shift()();
	}

	beginInstall();
}
	
////////////////////////////////////////////////////////////////////////////
//	install by Manual
function installManual(ditection_enabe) {
	
	var KRObjStatus = {Null:-1, Initialized:1, NotInstalled:2, OldInstalled:3, Installed:4}
	var app_objects = new Array();	
	var obj_krpdf = {display_name:MSG_PRODUCT_NAME_KRPDF, id_msg:"msg_krpdf", status:KRObjStatus.Null};
	var obj_krlib = {display_name:MSG_PRODUCT_NAME_KRLIB, id_msg:"msg_krlib", status:KRObjStatus.Null};
	var obj_krfla = {display_name:MSG_PRODUCT_NAME_KRFLA, id_msg:"msg_krfla", status:KRObjStatus.Null};
	
	//	initialize application objects on Windows
	function initOnWindows() {
		switch(install_type) {
		case KRInstallType.A1:	
      obj_krpdf.name = "KRMDecryptor-Vista";
			obj_krpdf.check_func = function() {return krinsobj.getKeyringPdfClientVersion("npkrplugin");};
			app_objects.push(obj_krpdf);
			break;
		case KRInstallType.A2:
      obj_krfla.name = "KeyringFlashDecryptorIE";
			obj_krfla.check_func = function() {return krinsobj.getKeyringFlashClientVersion("npkrplugin", "IE");};
			app_objects.push(obj_krfla);
			break;
		case KRInstallType.B1:
      obj_krpdf.name = "KRMDecryptor-Vista";
			obj_krpdf.check_func = function() {return krinsobj.getKeyringPdfClientVersion("npkrplugin");};
			app_objects.push(obj_krpdf);
      obj_krlib.name = keyringlib_name;
			obj_krlib.check_func = function() {return krinsobj.getKeyringLibraryVersion("npkrplugin");};
			app_objects.push(obj_krlib);			
			break;
		case KRInstallType.B2:
      obj_krfla.name = "KeyringFlashDecryptorIE";
			obj_krfla.check_func = function() {return krinsobj.getKeyringFlashClientVersion("npkrplugin", "IE");};
			app_objects.push(obj_krfla);
      obj_krlib.name = keyringlib_name;
			obj_krlib.check_func = function() {return krinsobj.getKeyringLibraryVersion("npkrplugin");};
			app_objects.push(obj_krlib);			
			break;
		case KRInstallType.C1:
			switch(browser) {
			case "IE":	//	never happen.
        obj_krfla.name = "KeyringFlashDecryptorIE";
				break;
			case "Firefox":
			case "Safari":
			case "Chrome":
        obj_krfla.name = "KeyringFlashDecryptorFirefox";
				break;
			default: throw new Error("browser: " + browser + " is not supported.");
			}
			obj_krfla.check_func = function() {return krinsobj.getKeyringFlashClientVersion("npkrplugin");};
			app_objects.push(obj_krfla);
			break;
		default: throw new Error("invalid install_type: " + install_type);
		}
	}
	
	//	initialize application objects on Mac
	function initOnMac() {
		switch(install_type) {
    case KRInstallType.A2:
      obj_krfla.name = "KeyringFlashDecryptorForMac";
			obj_krfla.check_func = function() {return krinsobj.getKeyringFlashClientVersion("npkrplugin");};
			app_objects.push(obj_krfla);
      break;
		case KRInstallType.C1:
			switch(browser) {
			case "Firefox":
			case "Safari":
				obj_krfla.name = "KeyringFlashDecryptorForMac";
				break;
			default: throw new Error("browser: " + browser + " is not supported.");
			}
			obj_krfla.check_func = function() {return krinsobj.getKeyringFlashClientVersion("npkrplugin");};
			app_objects.push(obj_krfla);
			break;
		default: throw new Error("invalid install_type: " + install_type);
		}
	}
	
	//	initialize application objects
	function init() {
		if(os == "Windows") {
			initOnWindows();
		}
		else if(os == "Mac") {
			initOnMac();
		}
		else {
			throw new Error("invalid os: " + os);
		}
    getVersionInfo();
	}
  
  //  get version info
  function getVersionInfo() {
    app_objects.each(function(obj) {
      var param = license_server + "/license/GetVersion?Program=" + obj.name;
      var url = "redirect.php?url=" + encodeURIComponent(param);
      new Ajax.Request(url, {method: 'get', 
          onComplete: function(request) {
            var xml = request.responseText;
            printdbg("GetVersion: " + xml);
            var status      = getElementValue(xml, "Status");
            var status_desc = getElementValue(xml, "StatusDescription");
            if(status != "8000") {
              error(xml.length > 0 ? xml : "GetVersion failed.");
              return;
            }
            obj.latest_ver    = getElementValue(xml, "MajorVersion") + "." +  getElementValue(xml, "MinorVersion");
            obj.download_url  = getElementValue(xml, "DownloadURL");
            obj.refer_url     = getElementValue(xml, "ReferURL");
            obj.force_update  = getElementValue(xml, "ForceUpdate");
            obj.status = KRObjStatus.Initialized;
          }, 
          onException: function(request, e) {error(e.message);}
        });
    });
  }
  
  //  check all application object initialized
  function checkInitializeComplete() {
    var ret = true;
    app_objects.each(function(obj) {
      if(obj.status != KRObjStatus.Initialized) {ret = false;}
    });
    return ret;
  }
	
	//	get html for application status table 
	//	return: html strings
	function getAppStatusTableHtml() {
		//	html for applications
		var html = "<table border='0' class='manual_ver'>";
		app_objects.each(function(obj) {
			html += "<tr><th>" + obj.display_name + "</th><td id='" +  obj.id_msg + "'> - </td>" + 
        "<td>(" + MSG_LATEST_VERSION + obj.latest_ver + ")</td></tr>";
		});
		html += "</table>";
		return html;
	}
	
	//	get html for application download button
	//	return: html strings
	function getDownloadButtonHtml() {
		//	html for applications
		var html = "";
		app_objects.each(function(obj) {
			if(obj.status != KRObjStatus.Installed) {
				html += "<input type=\"button\" value=\"" + obj.display_name + "\" onClick=\"javascript:location.href='" + obj.download_url + "';\">";
			}
		});
		return html;
	}
	
	//	check application install status
	//	return: true, false
	function checkInstallStatus() {
		var complete = true;
		//  reload plugins
		navigator.plugins.refresh(false); 
		//	get installed version and update status table
		app_objects.each(function(obj) {
			if(obj.status != KRObjStatus.Installed) {
				var version = obj.check_func();
        if(version) {
          $(obj.id_msg).innerHTML = version;
          obj.status = krinsobj.compareVersion(version, obj.latest_ver) >= 0 ? KRObjStatus.Installed : KRObjStatus.OldInstalled;
        } 
        else {
          $(obj.id_msg).innerHTML = MSG_APP_NOT_INSTALLED;
          obj.status =  KRObjStatus.NotInstalled;
        }
				if(obj.status != KRObjStatus.Installed) {complete = false;}
			}
		});	
		return complete;
	}
 
 	//	begin install manual with ditection
	function beginInstallManualWithDitection()
	{
		print("<h3>" + MSG_CHECK_INSTALLED_CLIENT + "</h3>");
		print(getAppStatusTableHtml());

		//  wait installation complete
		var timer_id = setInterval(function() {
			if(checkInstallStatus()) {
				clearInterval(timer_id);
				$(elm_msg2).innerHTML = "";
				navigator.plugins.refresh(false);
				success();
			} 
			else {
				create_download_button = true;
				$(elm_msg2).innerHTML = "";
				print("<h4>" + MSG_APP_NOT_INSTALLED_LATEST + "<br />" + MSG_PLEASE_DOWNLOAD_AND_INSTALL + "</h4>", elm_msg2);
				print(getDownloadButtonHtml(), elm_msg2);
			}
		}, 1000);
	}
	
 	//	begin install manual
	function beginInstallManual() {
		print("<h3>" + MSG_CHECK_INSTALLED_CLIENT + "</h3>");
		print("<h4>" + MSG_CLIENT_DITECTION_NOT_SUPPORTED + "<br />" +
			MSG_PLEASE_DOWNLOAD_AND_INSTALL2 + "</h4><br />");
		print(getDownloadButtonHtml());

		if(success_url.length > 0) {
			print("<p class='bt_box'><a href=" + success_url + ">" + MSG_END_MANUAL_INSTALL1 + "</a></p>");
		} else {
			print("<p>" + MSG_END_MANUAL_INSTALL2 + "</p>");
		}
	}
	
	init();
  //  wait initialization
  var timer_id = setInterval(function() {
    if(checkInitializeComplete()) {    
      //  start manual install
      clearInterval(timer_id);
      app_objects.each(function(obj) {printdbg(Object.toJSON(obj));});
      ditection_enabe ? beginInstallManualWithDitection() : beginInstallManual();
    }
  }, 1000);
}

//	main
function process() {
	printdbg("OS = " + os);
	printdbg("Browser = " + browser);	
	printdbg("InstallType = " + install_type);	
	printdbg("LicenseServer = " + license_server);	
	printdbg("RedirectTime = " + redirect_time);	
	printdbg("SuccessURL = " + success_url);	
	printdbg("ErrorURL = " + error_url);	
  printdbg("LibraryName = " + keyringlib_name);
  printdbg("navigator.appName = " + navigator.appName);
  printdbg("navigator.userAgent = " + navigator.userAgent);
  printdbg("navigator.platform = " + navigator.platform);
	//	check parameter
	checkParams();
	//	check os
	if(!checkOS()) {
		errorNoSupportedOS();
		return;
	}
	//	check browser
	if(install_type == KRInstallType.C1 && !checkBrowser()) {
		errorNoSupportedBrowser();
		return;
	}	
	//	check install method
	install_method = getAvailableInstallMethod();
	printdbg("InstallMethod = " + install_method);	
	//	install
	switch(install_method) {
	case KRInstallMethod.ActiveX:					installActiveX(); break;
	case KRInstallMethod.ManualAndDitect:	installManual(true); break;
	case KRInstallMethod.Manual:						installManual(false); break;
	default: throw new Error("invalid install method: " + install_method);
	}
}
