//////////////////////////////////////////////////////////////////////////////////////////
//
//	Fichier		: cookie.js
//      Voir application dans identite.js
//	Description	: Bibliothèque JavaScript de gestion de cookies
//
//
//
//	Mise en oeuvre	:
//
//	Un cookie est une variable stockée sur le client dans le cadre d'un dialogue via
//	un navigateur Web.
//	Un cookie est caractérisé par un nom, une valeur, une date d'expiration, un 
//	domaine et un chemin de validité. Un cookie possède également un paramètre 
//	"secure" qui n'est pas géré par cette bibliothèque.
//
//	Pour un domaine donné (un nom de serveur en général), un navigateur ne peut 
//	déposer qu'au maximum 20 cookies sur le poste client. 
//
//	Comme un cookie ne possède qu'une seule valeur, cette bibliothèque propose une
//	API permettant de stocker plusieurs couples nom/valeur dans un meme cookie. Dans 
//	la suite de ce programme, ce format de stockage sera appelé "paquet", "pack" ou 
//	donnée "empaquetée" et il a la forme suivante (prop = propriété, val = valeur):
//			nomProp1=valProp1&nomProp2=valProp2&nomProp3=valProp3 ...
//
//
//	Dernière mise à jour : 28/02/2000
//
//
//	Historique des mises à jour :
//      28/02/2000 : adaptation à a-et-a.com
//
//////////////////////////////////////////////////////////////////////////////////////////


 // Délai d'expiration par défaut (1 an, exprimé en jours) pour les prochains cookies
 // créés - Number
var EXPIRE_DELAY = 365; 
var PATH         = null; // chemin associé par défaut aux prochains cookies créés - String
var DOMAIN       = null; // domaine associé par défaut aux prochains cookies créés -String


// ---------------------------------------------------------------------------------------
// Nom		: setCookie(name, value, [expireDelay])
// Description	: Positionne un cookie.
//		  - Le nom et la valeur peuvent contenir des caractères spéciaux.
//		  - Le chemin et le domaine de validité sont ceux positionnés par les 
//		    fonctions setCookiePath() et setCookieDomain()
// Entrées	: name        - String - nom du cookie
//		  value       - String - valeur du cookie
//		  expireDelay - Number [optionnel] - délai d'expiration du cookie exprimé
//			 en jours (1 an par défaut)
function setCookie(name, value) {
	var argv = setCookie.arguments;	// liste des arguments de la fonction
	var argc = argv.length;		// nombre d'arguments de la fonction
	// si le délai d'expiration n'est pas indiqué alors prendre le délai par défaut
	var expireDelay = (argc > 2) ? argv[2] : EXPIRE_DELAY;
	// convertir les jours en millisecondes 
	expireDelay = parseInt(expireDelay) * 24 * 60 * 60 * 1000; 
	var expireDate = new Date();	    // prendre la date du jour
	// ajouter le délai d'expiration
	expireDate.setTime(expireDate.getTime() + expireDelay);
	document.cookie = escape(name) + "=" + escape(value) +
		"; expires=" + expireDate.toGMTString() +
		((PATH == null) ? "" : ("; path=" + PATH)) +
		((DOMAIN == null) ? "" : ("; domain=" + DOMAIN));
}


// ---------------------------------------------------------------------------------------
// Nom		: getCookie(name)
// Description	: Renvoie la valeur d'un cookie ou null si le cookie est inexistant
// Entrée	: name - String - nom du cookie dont on veut connaitre la valeur
// Retour	: String - la valeur du paramètre ou null si le cookie est inexistant
function getCookie(name) {
	var result = null; 	// valeur de retour de la fonction
	// ajouter les sentinelles " " et ";" respectivement en début et fin de chaine 
	// afin que tous les couples "nomParam=valeurParam" soient encadrés par un " " et
	// un ";"
	var cookies = " " + document.cookie + ";"; 	
	var name = " " + escape(name) + "="; // un nom de cookie est toujours suivi de "="
	// recherche la position de début du cookie
	var startOfCookie = cookies.indexOf(name); 
	var endOfCookie;
	if (startOfCookie != -1) { // si le début a été trouvé
		startOfCookie += name.length;	// "sauter" le nom du cookie
		// repérer la fin du cookie
		endOfCookie = cookies.indexOf(";", startOfCookie);
		// extraire la valeur du cookie
		result = unescape(cookies.substring(startOfCookie, endOfCookie)); 
	}
	return result;
}


// ---------------------------------------------------------------------------------------
// Nom		: deleteCookie(name)
// Description	: Supprime un cookie
// Entrée	: name - String - nom du cookie à supprimer
// 	Ne pas oublier, avant suppression, de positionner si nécessaire le domaine et le
//	chemin du cookie à supprimer avec les fonctions setCookieDomain() et 
//	setCookiePath()  
function deleteCookie(name) {
	// supprimer un cookie, c'est lui donner une date d'expiration dans le passé
	// par exemple ici, 3 jours avant
	setCookie(name, "", -3);
}


// ---------------------------------------------------------------------------------------
// Nom		: setCookiePath([path])
// Description	: Positionne le chemin associé aux prochains cookies qui seront créés par
//		  les fonctions setCookie() et setCookieFromObject() (par défaut, le 
//		  chemin de la page courante)
// Entrée	: path - String [optionnel] - chemin associé aux prochains cookies qui 
//			seront créés par les fonctions setCookie() et
//			setCookieFromObject(), par défaut : le chemin de la page courante
function setCookiePath() {
	var argv = setCookiePath.arguments;	// liste des arguments de la fonction
	var argc = argv.length;			// nombre d'arguments de la fonction
	PATH = (argc > 0) ? argv[0] : null;
}


// ---------------------------------------------------------------------------------------
// Nom		: getCookiePath()
// Description	: Renvoie le chemin associé aux prochains cookies qui seront créés par
//		  les fonctions setCookie() et setCookieFromObject()
// Retour	: String - le chemin associé aux prochains cookies qui seront créés par
//			les fonctions setCookie() et setCookieFromObject()
function getCookiePath() {
	// si PATH est null alors retourner le chemin de la page courante 
	// sinon retourner PATH courant
	return ( (PATH == null) ? document.location.pathname : PATH );
}


// ---------------------------------------------------------------------------------------
// Nom		: setCookieDomain([domain])
// Description	: Positionne le domaine associé aux prochains cookies qui seront créés par
//		  les fonctions setCookie() et setCookieFromObject() (par défaut, le 
//		  domaine de la page courante)
// Entrée	: domain - String [optionnel] - domaine associé aux prochains cookies qui
//			seront créés par les fonctions setCookie() et 
//			setCookieFromObject(), par défaut : le domaine de la page courante
function setCookieDomain() {
	var argv = setCookieDomain.arguments;	// liste des arguments de la fonction
	var argc = argv.length;			// nombre d'arguments de la fonction
	DOMAIN = (argc > 0) ? argv[0] : null;
}


// ---------------------------------------------------------------------------------------
// Nom		: getCookieDomain()
// Description	: Renvoie le domaine associé aux prochains cookies qui seront créés par
//		  les fonctions setCookie() et setCookieFromObject()
// Retour	: String - le domaine associé aux prochains cookies qui seront créés par
//		  les fonctions setCookie() et setCookieFromObject()
function getCookieDomain() {
	// si DOMAIN est null alors retourner le domaine de la page courante (y compris
	// le numéro de port), sinon retourner le DOMAIN courant
	return ( (DOMAIN == null) ? document.location.host : DOMAIN );
}


// ---------------------------------------------------------------------------------------
// Nom         : setCookieFromObject(anObject, [expireDelay])
// Description : Positionne un cookie contenant les propriétés de l'objet passé en 
//		 paramètre.
//		 - Le nom du cookie est celui de la classe de l'objet
//		 - Les propriétés sont stockées dans le format suivant :
//		   	nomProp1=valProp1&nomProp2=valProp2 ...
//		 - Le chemin et le domaine de validité sont ceux positionnés par les 
//		   fonctions setCookiePath() et setCookieDomain()
// Entrées     : anObject    - Object - l'objet à stocker dans le cookie
//		 expireDelay - Number [optionnel] - délai d'expiration du cookie exprimé
//			 en jours (1 an par défaut)
function setCookieFromObject(anObject) {
	// fabriquer le "paquet" des propriétés, à stocker dans le cookie
	var cookieVal = packToString(anObject); 

	// Gérer le paramètre optionnel expireDelay
	var argv = setCookieFromObject.arguments;// liste des arguments de la fonction
	var argc = argv.length;			  // nombre d'arguments de la fonction
	if (argc > 1)	// délai spécifié
		setCookie(anObject.constructor.name, cookieVal, argv[1]);
//		setCookie(anObject.name, cookieVal, argv[1]);	
	else		// délai par défaut
		setCookie(anObject.constructor.name, cookieVal);
//		setCookie(anObject.name, cookieVal);
// alert(anObject.name);
// alert(anObject.constructor.name);
}


// ---------------------------------------------------------------------------------------
// Nom		: getCookieToObject(name)
// Description	: Renvoie un objet dont les propriétés correspondent au contenu
//		  du cookie dont le nom est spécifié. La classe de l'objet est <name>
// Entrée	: name - String - nom du cookie, qui est aussi le nom de la classe à 
//			instancier
// Retour	: Object - un objet de la classe <name>
//		  ou null si le cookie <name> est inexistant ou si <name> n'est pas un 
//		  nom de classe existante
//		  - S'il existe, le constructeur <name> sera exécuté. Ensuite, ses 
//		    propriétés seront positionnées aux valeurs trouvées dans la chaine 
//		    le cookie nommé <name>
function getCookieToObject(name) {
	return unpackToObject(getCookie(name), name);
}


// ---------------------------------------------------------------------------------------
// Nom         : unpackToArray(pack)
// Description : Décode un cookie "empaqueté" dans un tableau associatif
// Entrée      : pack - String - la chaine de caractères contenant les données 
//			"empaquetées" au format suivant :
//		   		nomProp1=valProp1&nomProp2=valProp2 ...
// Retour      : Array - un tableau associatif dont la clé est un nom de propriété
function unpackToArray(pack) {
	var result = new Array();
	var props = pack.split("&"); // Découper la chaine selon les "&"
	for (var propCount=0; propCount < props.length; propCount++) { 
		// pour chaque propriété
		// séparer le nom de la valeur par le "="
		var currentProp = props[propCount].split("=");
		// faire result[nomPropriete] = valeurPropriete
		result[unescape(currentProp[0])] = unescape(currentProp[1]); 
	}
	return result;
}


// ---------------------------------------------------------------------------------------
// Nom		: unpackToObject(pack, className)
// Description	: Renvoie un objet de la classe spécifiée à partir du "paquet" donné
// Entrée	: pack      - String - "paquet" contenant les données à utiliser pour les
//			propriétés de l'objet à construire. Le format est :
//				nomProp1=nomVal1&nomProp2=nomVal2 ...
//		  className - String - nom de la classe à laquelle l'objet à retourner 
//			appartient
// Retour	: Object - un objet de la classe <className>
//		  ou null si pack est null ou si <className> n'est pas un nom de classe 
//		  existante
//		  - S'il existe, le constructeur <name> sera exécuté. Ensuite, ses 
//		    propriétés seront positionnées aux valeurs trouvées dans la chaine 
//		    <pack>
function unpackToObject(pack, className) {
	// si pack est null ou si <className> n'est pas un nom de classe existante
	if ( (pack == null) || (eval("typeof(" + className + ")") != "function") )
		return null;

	// Instancier un objet de la classe <className>
	eval("var result = new " + className + "();");	
	// récupérer le tableau associatif contenant les propriétés
	var properties = unpackToArray(pack);	
	for (var prop in properties) {	// pour chaque propriété du cookie "empaqueté"
		// Positionner la valeur de la propriété de l'objet
		result[prop] = properties[prop];
	}
	return result;
}


// ---------------------------------------------------------------------------------------
// Nom		: packToString(anObjectOrArray)
// Description	: Renvoie une chaine "empaquetée" contenant les propriétés d'un objet ou
//		  d'un tableau donné
// Entrée	: anObjectOrArray - Object/Array - Objet ou tableau associatif contenant 
//			les propriétés à empaqueter
// Retour	: String - propriétés "empaquetées" de l'objet ou tableau donné, au format
//		   	nomProp1=valProp1&nomProp2=valProp2 ...
function packToString(anObjectOrArray) {
	var result = "";
	var objectProps;
	if (anObjectOrArray.constructor.name == "Array") {  // l'argument est un tableau
		objectProps = anObjectOrArray;
	} else { // l'argument est un objet
		// Récupérer le tableau des propriétés
		objectProps = getObjectProperties(anObjectOrArray); 
	}
	for (var prop in objectProps) {	// pour chaque propriété
		// ajouter nomProp=valProp& en échappant le nom et la valeur de la 
		// propriété pour éviter une confusion avec les délimiteurs "=" et "&"
		result += escape(prop) + "=" + escape(objectProps[prop]) + "&"; 
	}
	return (result.substring(0, result.length-1)); // Enlever le dernier "&" en trop 
}


// ---------------------------------------------------------------------------------------
// Nom		: getObjectProperties(anObject)
// Description	: Retourne un tableau associatif contenant les propriétés (pas les 
//		  méthodes) de l'objet spécifié
// Entrée	: anObject - Object - objet dont on veut connaitre les propriétés
// Retour	: Array - un tableau associatif dont les clés sont les noms des propriétés
function getObjectProperties(anObject) {
	var result = new Array();
	var count = 0;

	for (var prop in anObject) { // pour chaque propriété
		// ne pas prendre les méthodes
		if ( typeof(anObject[prop]) != "function" ) {
			result[prop] = anObject[prop];
			count++;
		}
	}

	return result;
}


// ---------------------------------------------------------------------------------------
// Nom		: joinHashArray(array, [separator])
// Description	: Retourne une chaine de caractères contenant les éléments de <array>
//		  séparés par <separator>. Cette fonction remplace la fonction join(),
//		  de la classe Array, qui ne fonctionne pas sur les tableaux associatifs.
// Entrées	: array     - Array - tableau associatif
//		  separator - String - séparateur des éléments, par défaut : ","
// Retour	: String - une chaine de caractères contenant les éléments de <array>
//		  séparés par <separator>
function joinHashArray(array) {
	var result = "";
	var argv = joinHashArray.arguments;
	var argc = argv.length;
	var separator = ( (argc > 1) ? argv[1] : "," );

	for (var item in array) {
		result += item + separator + array[item] + separator;
	}

	// Enlever le dernier <separator> en trop
	return ( result.substring(0, result.length-separator.length) );
}


//
//////////////////////////////////////////////////////////////////////////////////////////
// fin du fichier cookie.js
//////////////////////////////////////////////////////////////////////////////////////////
