/***************************************************
 * Variables JavaScript utilisees par les methodes.
 ***************************************************/

/* Identifiant de l'applet */
var cpsAppletId = "cpsApplet";

/* Identifiant de l'input correspondant au code PIN */
var cpsAppletCodePinHtmlId = "codePinFieldHtmlId";

/* Identifiant du boutton submit declenchant l'action sur l'applet */
var cpsAppletOkButtonHtmlId = "okButtonHtmlId";

/* Identifiant de l'image CPS/NO CPS */
var cpsAppletBitmapHtmlId = "bitmapHtmlId";
var cpsAppletBitmapSrc = images_path + "module/inscription/cartecps.gif";
var cpsAppletBitmapDisabledSrc = images_path + "module/inscription/cartecpsdisabled.gif";

/* Identifiant du div d'erreur */
var cpsAppletErrorDivHtmlId = "errorDivHtmlId";

/* Identifiant du div d'information */
var cpsAppletInfoDivHtmlId = "infoDivHtmlId";

/* Identifiant de l'input des donnees a signer */
var cpsAppletDataToSignHtmlId = "dataToSignHtmlId";

/* Identifiant de l'input des donnees signees */
var cpsAppletSignedDataHtmlId = "signedDataHtmlId";

/* Identifiant de l'input du certificat de signature */
var cpsAppletSignCertHtmlId = "signCertHtmlId";

/***************************************************
 * Array -> String
 ***************************************************/
function arrayToString(tmpArray) {
	if (!tmpArray) {
		return null;
	}
	var strArray;
	var first = true;
	for(var nb = 0 ; nb < tmpArray.length ; nb++){
		if(first){
			strArray = tmpArray[nb];
		}
		else{
			strArray += ',' + tmpArray[nb];
		}

		first = false;
	}
	return strArray;
}

/***************************************************
 * String -> Array
 ***************************************************/
function stringToArray(strArray) {
	if (!strArray) {
		return null;
	}
	var retArray = new Array();
	retArray = strArray.split(',');
	return retArray;
}

/* Fonctions de communication Javascript->JAVA */

/***************************************************
 * Crypte le digest avec le certificat de signature.
 * @param codePin le codePin
 * @param digest le digest
 * @param cpsInfoKeys les keys des valeurs a retourner avec la signature [key1, key2]
 * @return le digest crypte ou un tableau contenant [digest, value1, value2]
 ***************************************************/
function cpsSign(codePin, digest, cpsInfoKeys) {
	alertCpsError('');
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try {
			if (cpsInfoKeys) {
				var s = applet.signWithTabInfo(codePin, digest, arrayToString(cpsInfoKeys));
				return stringToArray(s);
			}
			return applet.sign(codePin, digest);
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
		}
	}
	return null;
}

/***************************************************
 * Crypte le digest avec le certificat d'authentification.
 * @param codePin le codePin
 * @param authChallenge le challenge
 * @param cpsInfoKeys les keys des valeurs a retourner avec la signature [key1, key2]
 * @return le authChallenge crypte ou un tableau contenant [hash, value1, value2]
 ***************************************************/
function cpsAuthentify(codePin, authChallenge, cpsInfoKeys) {
	alertCpsError('');
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try {
			if (cpsInfoKeys) {
				var s = applet.authentifyWithTabInfo(codePin, authChallenge, arrayToString(cpsInfoKeys));
				return stringToArray(s);
			}
			return applet.authentify(codePin, authChallenge);
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
		}
	}
	return null;
}

/***************************************************
 * @param key : 'cpsIdNat', 'cpsAdeli', 'cpsNumcard', 'cpsLastname', 'cpsFirstname', 'cpsAuthX509', 'cpsSigX509', 'cpsCivilite', 'cpsProfession', 'osName';
 * Retourne les informations de la carte CPS.
 ***************************************************/
function cpsGetCpsInfo(key) {
	alertCpsError('');
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try {
			return applet.getCpsInfo(key);
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
		}
	}
	return null;
}

/***************************************************
 * @param tmpArray : un tableau de cles parmi : 'cpsIdNat', 'cpsAdeli', 'cpsNumcard', 'cpsLastname', 'cpsFirstname', 'cpsAuthX509', 'cpsSigX509', 'cpsCivilite', 'cpsProfession', 'osName';
 * Retourne un tableau des donnees de la carte CPS pour les cles choisies.
 ***************************************************/
function cpsGetCpsTabInfo(tmpArray) {
	alertCpsError('');
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try {
			var str = applet.getCpsTabInfo(arrayToString(tmpArray));
			return stringToArray(str);
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
		}
	}
	return null;
}

/***************************************************
 * Retourne le message d'erreur courrante. Avec la
 * methode par defaut de gestion des erreurs.
 ***************************************************/
function cpsGetCurrentError() {
	var div = document.getElementById(cpsAppletErrorDivHtmlId);
	if (div) {
		var message = div.innerHTML;
		return message;
	}
	return null;
}

/***************************************************
 * Indique si le code PIN de la carte est verifie.
 ***************************************************/
function cpsIsCodePinVerified() {
	alertCpsError('');
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try  {
			return applet.isCodePinVerified();
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
			return false;
		}
	}
	return false;
}

/***************************************************
 * Lance la methode d'authentification.
 ***************************************************/
function cpsActionValidation() {
	alertCpsError('');
	var input = document.getElementById(cpsAppletCodePinHtmlId);
	var codePin;
	if (input) {
		codePin = input.value;
		input.value = "";
	}
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try {
			applet.actionValidation(codePin);
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
		}
	}
}

/***************************************************
 * Lance la methode de signature de donnees.
 ***************************************************/
function cpsActionSignature() {
	alertCpsError('');
	var input = document.getElementById(cpsAppletCodePinHtmlId);
	var codePin;
	var condensat;
	if (input) {
		codePin = input.value;
		input.value = "";
	}
	var condensatInput = document.getElementById(cpsAppletDataToSignHtmlId);
	if (condensatInput) {
		condensat = condensatInput.value;
	}
	var applet = document.getElementById(cpsAppletId);
	if (applet) {
		try {
			return applet.actionSignature(codePin, condensat);
		} catch(ex) {
			// La carte a appele la gestion des erreurs alertCpsError();
			//throw ex;
			return false;
		}
	}
	return false;
}


/* Fonctions de communication JAVA->Javascript */

/***************************************************
 * Desactive le focus sur l'applet en le donnant a
 * un autre element.
 ***************************************************/
function disableCpsFocus() {
	// A surcharger par une methode du même nom
	var input = document.getElementById(cpsAppletCodePinHtmlId);
	if (input && input.disabled != "true" && input.readonly != "true") {
		try {
			input.focus();
		} catch (ex) {}
	}
}

/***************************************************
 * Dispatche les donnees signees et le certificat de
 * signature sur la page Web.
 ***************************************************/
function dispatchCpsSignature(signature, signatureCert) {
	var signatureInput = document.getElementById(cpsAppletSignedDataHtmlId);
	if (signatureInput) {
		signatureInput.value = signature;
	}
	var signatureCertInput = document.getElementById(cpsAppletSignCertHtmlId);
	if (signatureCertInput) {
		signatureCertInput.value = signatureCert;
	}
}

/***************************************************
 * Active les elements HTML de la page Web pour
 * utiliser l'applet CPS.
 ***************************************************/
function enableCps() {
  	var button = document.getElementById(cpsAppletOkButtonHtmlId);
  	if (button) {
  		button.disabled = null;
  	}
  	var img = document.getElementById(cpsAppletBitmapHtmlId);
  	if (img) {
  		img.src = cpsAppletBitmapSrc;
  	}
  	return 0;
}

/***************************************************
 * Desactive les elements HTML de la page Web en cas
 * d'erreur de chargement de l'applet CPS.
 ***************************************************/
function disableCps() {
	var button = document.getElementById(cpsAppletOkButtonHtmlId);
	if (button) {
	  	button.disabled = "true";
	}
  	var img = document.getElementById(cpsAppletBitmapHtmlId);
  	if (img) {
  		img.src = cpsAppletBitmapDisabledSrc;
  	}
  	return 0;
}

/***************************************************
 * Desactive le code PIN de la page Web en cas
 * d'erreur de chargement de l'applet CPS.
 ***************************************************/
function lockCpsCodePin() {
	var input = document.getElementById(cpsAppletCodePinHtmlId);
	if (input) {
		input.disabled = "true";
		input.readonly = "true";
  		input.style.backgroundColor = "#CCCCCC";
	}
	return 0;
}

/***************************************************
 * Active le code PIN de la page Web pour utiliser
 * l'applet CPS.
 ***************************************************/
function unlockCpsCodePin() {
	var input = document.getElementById(cpsAppletCodePinHtmlId);
	if (input) {
		input.disabled = null;
		input.readonly = null;
		input.value = "";
		input.style.backgroundColor = "#FFFFFF";
	}
	return 0;
}

/***************************************************
 * Dispatche les erreurs de l'applet CPS sur la page
 * Web.
 ***************************************************/
function alertCpsError(message) {
	afficheMessage(message);
}

/***************************************************
 * Indique que la carte vient d'être retirer du lecteur.
 ***************************************************/
function cpsRemoveFromReader() {
	// nothing
}

/***************************************************
 * Indique que la carte vient d'être introduite dans le lecteur.
 ***************************************************/
function cpsIntroduceInReader() {
	// nothing
}

/***************************************************
 * Dispatche les informations de l'applet CPS sur la page
 * Web.
 ***************************************************/
function alertCpsInfo(message) {
	afficheMessage(message,'interrogation','Information');
}

/***************************************************
 * A surcharger... Indique que l'applet est en train de s'initialiser, est finie de s'initialiser, est en erreur
 ***************************************************/
function cpsInitializationWaiting() {
	alertCpsInfo('Initialisation de la carte CPS en cours...');
}

function cpsInitializationFinished() {
	alertCpsInfo('');
	if(document.getElementById('overlay')) {
		hideMe('overlay');
	}
}

/***************************************************
 * A surcharger... Indique que l'applet est en train de faire une action, a termine une action, est en erreur
 ***************************************************/
function cpsActionWaiting () {
	alertCpsInfo('Lecture de la carte CPS en cours...');
}

function cpsActionFinished () {
	alertCpsInfo('');
	if(document.getElementById('overlay')) {
		hideMe('overlay');
	}
}

/***************************************************
 * Retourne le code de l'applet CPS.
 *
 * @param code la classe de l'applet
 * @param codeBase le chemin des jars (generalement: 'jars').
 * @param height la hauteur de l'applet (generalement: 0)
 * @param width la largeur de l'applet (generalement: 0)
 * @param cpsMode le mode de l'applet ('00', 'debug')
 * @param urlConnect l'URL où sera poster les informations de connexion
 * @param urlRedirect l'URL de redirection apres le poste des informations de connexion
 * @param authChallenge le defi d'authentification a chiffrer par l'applet (Base64)
 * @param codePinDuration la duree de validite du code PIN en ms
 * @param checkCardInPeriod l'intervalle de temps entre la verification de presence de la carte en ms
 * @param jsMethodsHash Hash des methodes JavaScript afin de pouvoir modifier le nom des methodes JS appelees par l'applet
 * 			Ex : {cpsRemoveFromReader: 'cpsRemoveFromReader', cpsActionWaiting: 'cpsActionWaiting', ...}
 * 			Les methodes possibles : disableCps, enableCps, lockCpsCodePin, unlockCpsCodePin, alertCpsError, dispatchCpsSignature, cpsInitializationWaiting, cpsInitializationFinished, cpsActionWaiting, cpsActionFinished, cpsRemoveFromReader
 *
 * Les informations postees par l'applet sur l'URL urlConnect sont :
 *
 * cpsAuthChallenge le defi d'authentification (Base64)
 * cpsAuthResponse la reponse d'authentification (Base64) a verifier avec le certificat de la personne (de l'annuaire)
 * cpsAuthX509 le certificat de la personne (Base64)
 * cpsSigX509 le certificat de la personne (Base64)
 * cpsProfession le code profession
 * cpsAdeli le numero d'identifiant national (ApsIdNat)
 * cpsNumcard le numero de la carte
 * cpsLastname le nom
 * cpsFirstname le prenom
 * cpsError 'true' si erreur
 * cpsErrorCode le code d'erreur
 * cpsErrorMessage le message correspondant au code d'erreur
 ***************************************************/
function getApplet(code, codeBase, height, width, cpsMode, urlConnect, urlRedirect, authChallenge, codePinDuration, checkCardInPeriod, jsMethodsHash) {
    /* Configuration de l'applet */
	var cpsAppletCode = code;
	var cpsAppletCodebase = codeBase;
	if (!cpsAppletCodebase) {
		codeBase = "jars";
	}
	var cpsAppletArchive = "cps-all.jar, commons-codec-1.3.jar, iaikPkcs11Wrapper.jar";
	var cpsAppletMayscript = "true";
	var cpsAppletWidth = width;
	var cpsAppletHeight = height;
	var cpsAppletParamMode = cpsMode;
	if (!cpsAppletParamMode) {
		cpsAppletParamMode = "00";
	}
	var cpsAppletParamUrlConnect = urlConnect;
	if (!cpsAppletParamUrlConnect) {
		cpsAppletParamUrlConnect = "";
	}
	var cpsAppletParamUrlRedirect = urlRedirect;
	if (!cpsAppletParamUrlRedirect) {
		cpsAppletParamUrlRedirect = "";
	}
	var cpsAppletParamAuthChallenge = authChallenge;
	if (!cpsAppletParamAuthChallenge) {
		cpsAppletParamAuthChallenge = "";
	}
	var cpsCodePinDuration = codePinDuration;
	if (!cpsCodePinDuration) {
		cpsCodePinDuration = "";
	}
	var cpsCheckCardInPeriod = checkCardInPeriod;
	if (!cpsCheckCardInPeriod) {
		cpsCheckCardInPeriod = "";
	}
	var appletNotSupported = "No Java 2 SDK, Standard Edition v 1.6.0 support for APPLET!!";

	/* Affichage de l'applet en fonction du navigateur */
	var _info = navigator.userAgent;
    var _ns = false;
    var _ie = (_info.indexOf("MSIE") > 0 && _info.indexOf("Win") > 0 && _info.indexOf("Windows 3.1") < 0);

    var appletCpsHtml;
    if (_ie == true) {
    	var jsMethodsMapping = '';
    	if (jsMethodsHash) {
	    	for (var key in jsMethodsHash) {
	    		var value = jsMethodsHash[key];
	    		jsMethodsMapping += '<param name="' + key + '" value="' + value + '"/>';
	    	}
    	}
    	appletCpsHtml = ''
	    + '<object id="' + cpsAppletId + '" width="' + cpsAppletWidth + '" height="' + cpsAppletHeight + '" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" codebase="https://java.sun.com/update/1.6.0/jinstall-6-windows-i586.cab#Version=1,6,0,0">'
	    	+ '<param name="name" value="' + cpsAppletId + '"/>'
			+ '<param name="java_type" value="application/x-java-applet;jpi-version=1.6.0"/>'
			+ '<param name="java_code" value="' + cpsAppletCode + '"/>'
			+ '<param name="java_codebase" value="' + cpsAppletCodebase + '"/>'
			+ '<param name="java_archive" value="' + cpsAppletArchive + '"/>'
			+ '<param name="scriptable" value="' + cpsAppletMayscript + '"/>'
			+ '<param name="mayscript" value="' + cpsAppletMayscript + '"/>'
			+ '<param name="mode" value="' + cpsAppletParamMode + '"/>'
			+ '<param name="urlConnect" value="' + cpsAppletParamUrlConnect + '"/>'
			+ '<param name="urlRedirect" value="' + cpsAppletParamUrlRedirect  + '"/>'
			+ '<param name="authChallenge" value="' + cpsAppletParamAuthChallenge + '"/>'
			+ '<param name="codePinDuration" value="' + cpsCodePinDuration + '"/>'
			+ '<param name="checkCardInPeriod" value="' + cpsCheckCardInPeriod + '"/>'
			+ jsMethodsMapping
			+ appletNotSupported
		 + '</object>';
 	} else if (_ns == true) {
 		var jsMethodsMapping = '';
 		if (jsMethodsHash) {
	    	for (var key in jsMethodsHash) {
	    		var value = jsMethodsHash[key];
	    		jsMethodsMapping += ' ' + key + '="' + value + '"';
	    	}
 		}
    	 appletCpsHtml = ''
    	 + '<embed id="' + cpsAppletId + '" width="' + cpsAppletWidth + '" height="' + cpsAppletHeight + '" '
			 + 'name="' + cpsAppletId + '"'
			 + 'pluginspage="https://java.sun.com/javase/downloads/ea.jsp"'
			 + 'type="application/x-java-applet;jpi-version=1.6.0"'
			 + 'code="' + cpsAppletCode + '"'
			 + 'codebase="' + cpsAppletCodebase + '"'
			 + 'archive="' + cpsAppletArchive + '"'
			 + 'mayscript="' + cpsAppletMayscript + '"'
			 + 'scriptable="' + cpsAppletMayscript + '"'
			 + 'mode="' + cpsAppletParamMode + '"'
			 + 'urlConnect="' + cpsAppletParamUrlConnect + '"'
			 + 'urlRedirect="' + cpsAppletParamUrlRedirect  + '"'
			 + 'authChallenge="' + cpsAppletParamAuthChallenge + '"'
			 + 'codePinDuration="' + cpsCodePinDuration + '"'
			 + 'checkCardInPeriod="' + cpsCheckCardInPeriod + '"'
			 + jsMethodsMapping
			 + '<noembed>'
			 + appletNotSupported
			 + '</noembed>'
		 + '</embed>';
	} else {
		var jsMethodsMapping = '';
		if (jsMethodsHash) {
	    	for (var key in jsMethodsHash) {
	    		var value = jsMethodsHash[key];
	    		jsMethodsMapping += '<param name="' + key + '" value="' + value + '"/>';
	    	}
		}
    	appletCpsHtml = ''
	    + '<applet id="' + cpsAppletId + '" name="' + cpsAppletId + '" width="' + cpsAppletWidth + '" height="' + cpsAppletHeight + '" '
			+ 'mayscript="' + cpsAppletMayscript + '" scriptable="' + cpsAppletMayscript + '"'
			+ 'code="' + cpsAppletCode + '" codebase="' + cpsAppletCodebase + '" archive="' + cpsAppletArchive + '">'
			+ '<param name="mode" value="' + cpsAppletParamMode + '"/>'
			+ '<param name="urlConnect" value="' + cpsAppletParamUrlConnect + '"/>'
			+ '<param name="urlRedirect" value="' + cpsAppletParamUrlRedirect  + '"/>'
			+ '<param name="authChallenge" value="' + cpsAppletParamAuthChallenge + '"/>'
			+ '<param name="codePinDuration" value="' + cpsCodePinDuration + '"/>'
			+ '<param name="checkCardInPeriod" value="' + cpsCheckCardInPeriod + '"/>'
			+ jsMethodsMapping
			+ appletNotSupported
		+ '</applet>';
    }
	return appletCpsHtml;
}

/***************************************************
 * Retourne le code de l'applet de Test.
 ***************************************************/
function getAppletTest(codeBase) {
	return getApplet('com.sqli.cps.applet.AppletTest.class', codeBase, '0', '0', '60000', '1000');
}

/***************************************************
 * Ecrit le code de l'applet de Test sur le
 * document.
 ***************************************************/
function writeAppletTest(codeBase) {
	/**
	 * On ecrit le code HTML de l'applet.
	 */
	var appletHtml = getAppletTest(codeBase);
	document.writeln(appletHtml);
}

/***************************************************
 * Retourne le code de l'applet CPS.
 ***************************************************/
function getAppletCps(codeBase, cpsMode, urlConnect, urlRedirect, authChallenge, codePinDuration, checkCardInPeriod, jsMethodsHash) {
	return getApplet('com.sqli.cps.applet.AppletCps.class', codeBase, '0', '0', cpsMode, urlConnect, urlRedirect, authChallenge, codePinDuration, checkCardInPeriod, jsMethodsHash);
}

/***************************************************
 * Ecrit le code de l'applet CPS sur le document.
 ***************************************************/
function writeAppletCps(codeBase, cpsMode, urlConnect, urlRedirect, authChallenge, codePinDuration, checkCardInPeriod, jsMethodsHash) {
   	/**
	 * Appel de la fonction disableCps() pour desactiver l'applet par defaut.
	 * C'est l'applet qui active les elements HTML.
	 */
	disableCps();
	lockCpsCodePin();
	cpsInitializationWaiting();

	/**
	 * On ecrit le code HTML de l'applet.
	 */
	var appletCpsHtml = getAppletCps(codeBase, cpsMode, urlConnect, urlRedirect, authChallenge, codePinDuration, checkCardInPeriod, jsMethodsHash);
	document.writeln(appletCpsHtml);
}

