/**
 * Librairie Javascript métadonnées
 *
 *
 * @category     lib
 * @package      kalon
 * @author       Stéphane Péron
 * @version      1.2
 *
 *
 */


var tabChamps = new Array();
tabChamps['booleen']   = new Array(/0|1/,"");
tabChamps['radio']     = new Array(/.*/,"");
tabChamps['select']    = new Array(/.*/,"");
tabChamps['string']    = new Array(/\S/,"Veuillez remplir le champ de saisie SVP.");
tabChamps['textarea']  = new Array(/\S/,"Veuillez remplir le champ de saisie SVP.");
tabChamps['email']     = new Array(/^[a-z][a-z0-9_-]*(\.[a-z0-9_-]+)*@[a-z0-9_-]+\.([a-z]{2,3})$/i,"Veuillez saisir une adresse email valide SVP.");
tabChamps['url']       = new Array(/^(https?:\/\/)?[a-z0-9]+\.([a-z0-9]+-?)+\.[a-zA-Z]{2,4}(:[0-9]+)?$/i,"Veuillez saisir une URL valide SVP.");
tabChamps['integer']    = new Array(/^\s*[+\-]?\s*\d+\s*$/,"Veuillez saisir un nombre entier SVP.");
tabChamps['float']     = new Array(/^\s*[+\-]?\s*\d+\.?\d*\s*$/,"Veuillez saisir une valeur décimale SVP");
tabChamps['date']      = new Array(validerDate,"Veuillez saisir une date valide au format jj/mm/aaaa");
tabChamps['time']      = new Array(validerTime,"Veuillez saisir une heure valide au format hh:mm:ss");

var isIE=navigator.userAgent.toLowerCase().indexOf("msie")!=-1;

function Metadonnees(objDefinitions,champ,id_conteneur)
{
	this.objDefinitions  = objDefinitions;
	this.valid       = tabChamps;
	this.bilan       = document.getElementsByName(champ)[0];
	this.baseNom     = champ;
	this.mainDiv     = document.getElementById(id_conteneur);
	this.tabTags     = new Array();
	this.tabCat      = new Array();
	this.tabGroupes  = new Array();
	
	this.objCat      = new Object();
	this.nbUnique    = 0;
	
	// recherche des définitions de métadonnées absentes
	var tabValeurs = this.bilan.value.split("&");
	var cle,cle_sp;  // cle_sp=cle sans prefixe
	for(var i in tabValeurs) {
		if(tabValeurs[i].split("=").length < 2) continue;  // contenu incomplet, ou élément vide
		cle = tabValeurs[i].split("=")[0];
		cle_sp = this.donneCleSansPrefixe(cle);
		if(this.objDefinitions[cle_sp] == undefined)
			this.objDefinitions[cle_sp] = new Array(0,0,'string_m','defaut','Indéfini,'+cle_sp,'');
	}
	
	for (var i in this.objDefinitions) {
		this.tabTags[i] = this.objDefinitions[i][4];
	}
	
	// liste des catégories
	var found;
	for(var i in this.tabTags){
		if(typeof(this.tabTags[i])!="string"){
			continue;
		}
		var cat=this.tabTags[i].split(",");
		cat=cat[0];
		found=false;
		for(var j in this.tabCat){
			if(cat==j){
				found=true;
				break;
			}
		}
		if(!found){
			this.tabCat[cat]=new Array();
		}
		this.tabCat[cat][i]=this.tabTags[i].replace(/^[^,]+,/,"").replace(","," ");
	}
	
	// liste des groupes
	var groupe;
	for(var i in this.tabTags) {
		if(this.objDefinitions[i][1]=="0") continue;
		groupe=this.tabTags[i].replace(/(^.*),[^,]+$/,"$1");
		found=false;
		for(var j in this.tabGroupes) {
			if(groupe==j) {
				found=true;
				break;
			}
		}
		if(!found) this.tabGroupes[groupe]=new Array;
		this.tabGroupes[groupe].push(i);
	}
	
	this.initialiser();
	this.charger(this.bilan.value);
	this.majValeur();
}

Metadonnees.prototype.initialiser = function()
{
	var cat;
	for(var nomCat in this.tabCat) {
		cat = new Categorie(this,nomCat);
		this.mainDiv.appendChild(cat.init());
		this.objCat[nomCat] = cat;
	}
}

Metadonnees.prototype.charger = function(valeur)
{
	if(typeof(valeur) != "string") return;

	var tabVal = valeur.split("&"),objVal = new Object(),temp;
	for (var i = 0;i<tabVal.length;i++) {
		temp = tabVal[i].split("=");
		if(temp.length < 2 || objVal[temp[0]] != undefined) continue; // ne pas écraser les valeurs déjà définies (cas d'une valeur n'utilisant pas les préfixes de clés rendant les variables uniques : si une donnée est multiple, seule la première valeur sera retenue
		objVal[temp[0]] = temp[1];
	}

	for (var cat in this.objCat) this.objCat[cat].charger(objVal);
}

Metadonnees.prototype.donneCleSansPrefixe = function(cle)
{
	if(typeof(cle)!="string")
		return cle;
	return cle.replace(/^[um]\d+__/,"");
}
Metadonnees.prototype.donnePrefixeCle = function(cle)
{
	if(typeof(cle)!="string")
		return "";
	var re = /^([um]\d+__).*$/;
	if(cle.match(re)) return cle.replace(re,"$1");
	else return "";     // offre compatibilité avec valeurs sans préfixe
}

Metadonnees.prototype.majValeur = function()
{
	var tab = new Array(),temp;
	for(var cat in this.objCat) {
		temp = this.objCat[cat].donneValeur();
		if(temp.length) tab.push(temp);
	}
	this.bilan.value = tab.join("&");
	
	///////////////  TEST A  SUPPRIMER !!!!!!!!!!!!!!!!!
	// document.getElementById("temp").innerHTML= tab.join("&");
	///////////////
}
Metadonnees.prototype.donnerBouton = function(typeBouton)
{
	var e = null,tabImg;
	var tab = tab_meta_images || undefined;
	if(tab != undefined) {
		if(tab[typeBouton] && tab[typeBouton].length && tab[typeBouton].length > 3) {
			tabImg = tab[typeBouton];
			e = creerElement("img",[["src",tabImg[0]],["width",tabImg[1]],["height",tabImg[2]],["title",tabImg[3]],["alr",tabImg[3]]]);
		}
	}
	if(!e) {
		var texte = typeBouton;
		switch(typeBouton) {
			case "Ajouter" : texte = "+";break;
			case "Supprimer" : texte = "-";break;
			case "Valider" : texte = "OK";break;
			case "Annuler" : texte = "X";break;
		}
		//e = creerElement("input",[["type","button"],["value",texte],["title",typeBouton]]);
		e = creerElement("div",[["title",typeBouton],["align","center"]]);
		e.appendChild(document.createTextNode(texte));
		e.style.padding = "3px";
		e.style.margin = "0px";
		e.style.lineHeight = "0.5em";
		e.style.color = "#000";
		e.style.backgroundColor = "#FFF";
		e.style.border = "#000 solid 1px";
		
	}
	e.style.cursor = "pointer";
	return e;
}
//////////////////////////////////////////////
//   CATEGORIES
/////////////////////////////////////////////
function Categorie(meta,nom)
{
	this.meta=meta;
	this.nomCat=nom;
	this.tabBlocs = new Array();
	this.conteneur = null;
}

Categorie.prototype.init = function()
{
	var e = creerElement("div",[["class","meta_categorie"]]);
	var e2 = creerElement("div",[["class","meta_nomcategorie"]]);
	e2.appendChild(document.createTextNode(this.nomCat));
	e.appendChild(e2);
	this.conteneur = e;
	this.objDefinitions = new Array();
	for(var cle in this.meta.objDefinitions){
		if (this.meta.objDefinitions[cle][4].replace(/^([^,]+),.*$/,"$1") != this.nomCat) continue;
		this.objDefinitions[cle] = this.meta.objDefinitions[cle];
	}
	
	var tabGroupes= new Array(),donnee,bloc,groupe,objTemp;
	for(var cle in this.objDefinitions) {
		donnee = this.objDefinitions[cle];
		if(donnee[1]==0) { // pas de regroupement
			objTemp = new Object();
			objTemp[cle] = this.objDefinitions[cle];
			bloc = new BlocData(this,this.meta,objTemp);
			this.tabBlocs.push(bloc);
			
		}
		else { // regroupement
			groupe = donnee[4].replace(/,[^,]+$/,"");
			if(tabGroupes[groupe]) continue; // le regroupement a déjà été traité			
			
			/* calculer le objDefinitions */
			objTemp = new Object();
			for (var cle2 in this.objDefinitions) {
				if(this.objDefinitions[cle2][4].replace(/,[^,]+$/,"") == groupe && this.objDefinitions[cle2][1] == 1) {
					objTemp[cle2] = this.objDefinitions[cle2];
				}
			}
			bloc = new BlocData(this,this.meta,objTemp);
			this.tabBlocs.push(bloc);
			
			tabGroupes[groupe]=1;
		}
	}
	
	for (var i = 0;i<this.tabBlocs.length;i++) {
		e.appendChild(this.tabBlocs[i].init());
	}
	
	return e;
}

Categorie.prototype.charger = function(objVal)
{
	for (var j = 0;j<this.tabBlocs.length;j++) this.tabBlocs[j].charger(objVal);
}

Categorie.prototype.donneValeur = function()
{
	var tab = new Array(),temp;
	for(var i = 0;i<this.tabBlocs.length;i++) {
		temp = this.tabBlocs[i].donneValeur();
		if(temp.length) tab.push(temp);
	}
	return tab.join("&");
}
//////////////////////////////////////////////
//   BLOCDATA
/////////////////////////////////////////////
function BlocData(objCat,objMeta,objDefinitions)
{
	this.meta=objMeta;
	this.cat=objCat;
	this.objDefinitions = objDefinitions;
	this.unique=false;
	this.regroupement=false; // en fait information redondante : si objDefinitions contient plus de 1 élément (attention, ce n'est pas un tableau, length n'est pas disponible) alors regroupement = true
	this.tabData = new Array();
	this.conteneur = null;
	this.contTitre = null;
	this.titre = null;
	this.ajouter = null;
	this.nbDef = 0;
}

BlocData.prototype.init = function()
{
	var n=0;
	for (var cle in this.objDefinitions) {
		n++;
		if(this.objDefinitions[cle][0]==1) {
			this.unique=true;
		}
	}
	
	this.regroupement = n>1;
	this.nbDef = n;
	
	for(var cle in this.objDefinitions) {
		//var tags = this.objDefinitions[cle][4];
		//this.titre = this.regroupement ?tags.replace(/,[^,]+$/,"").replace(/^.*,([^,]+)$/,"$1"):tags.replace(/^.*,([^,]+)$/,"$1");
		this.titre = this.objDefinitions[cle][4];
		if(this.regroupement) this.titre = this.titre.replace(/,[^,]+$/,"");
		this.titre = this.titre.replace(/^[^,]*,/,"").replace(/,/g," ");
	}
	
	var e = creerElement("div",[["class","meta_bloc"]]),e2;
	e2 = creerElement("div",[["class","meta_nombloc"]]);
	e2.appendChild(document.createTextNode(this.titre));
	this.contTitre = e2;
	e.appendChild(e2);
	this.conteneur = e;
	return e;
	
}

BlocData.prototype.charger = function(objVal)
{
	var cle,cle_sp,objPrefixe = new Object(),prefixe,data,dataPrefixe;
	var prefixeVideLu = false;  // pour compatibilité avec valeurs sans prefixe
	for(var cle in objVal) {
		if(this.unique && this.tabData.length > 0) break;
		cle_sp = this.meta.donneCleSansPrefixe(cle);
		prefixe = this.meta.donnePrefixeCle(cle);
		if(prefixe != "" && objPrefixe[prefixe] == 1) continue; // valeur déjà traitée
		if(prefixe == "" && prefixeVideLu) continue; // cas d'une valeur sans préfixe déjà traitée
		
		
		if(this.objDefinitions[cle_sp] != undefined) {
			var objValeurs = new Object;
			for(var cle2 in this.objDefinitions) {
				if(objVal[prefixe+cle2] != undefined) {
					objValeurs[cle2] = objVal[prefixe+cle2]
				}
			}
			if(prefixe == "") prefixeVideLu = true;
			else objPrefixe[prefixe] = 1;
			
			dataPrefixe = (this.unique?"u":"m") + this.tabData.length + "__";  // calcul du nouveau préfixe. Permet de corriger la valeur du champ s'il y a eu entre temps un changement de définitions.
			
			data = new Data(this.meta,this.cat,this,objValeurs,dataPrefixe);
			this.conteneur.appendChild(data.init());
			this.tabData.push(data);			
		}
	}
	
	if(this.tabData.length) this.tabData[this.tabData.length-1].affAjouter(true);
	
	var e = this.meta.donnerBouton("Ajouter");
	e.style.marginLeft="12px";
	var bloc = this;	
	e.onclick = function()
	{
		bloc.ajouterData();
	}
	this.ajouter = e;
	this.majInterface();
	this.contTitre.appendChild(e);
	
}
BlocData.prototype.supprimerData = function(data)
{
	// supprimer l'element HTML
	data.conteneur.parentNode.removeChild(data.conteneur);
	
	// mettre à jour la liste de Data du bloc, et supprimer l'objet javascript data
	var temp = new Array();
	for(var i = 0;i<this.tabData.length;i++) {
		if(data != this.tabData[i]) temp.push(this.tabData[i]);
	}	
	this.tabData = temp;
	data = null;
	
	// mettre à jour l'interface
	this.majInterface();
	
	// mettre à jour la valeur du champ caché métadonnées
	this.meta.majValeur();
}

BlocData.prototype.majInterface = function()
{
	if(this.tabData.length == 0 || !this.unique) this.affAjouter(true);
	else (this.affAjouter(false));
}

BlocData.prototype.donneValeur = function()
{
	var tab = new Array(),data,nData=0,temp;
	for(var i = 0;i<this.tabData.length;i++) {
		data = this.tabData[i];
		if(data.ajoutEnCours) continue;  // élément non encore validé, pas de valeur disponible, ne pas tenir compte
		data.prefixe = (this.unique?"u":"m")+nData+"__";
		temp=data.donneValeur();
		if(temp.length) tab.push(temp);
		nData++;
	}
	return tab.join("&");
}

BlocData.prototype.affAjouter = function(actif)
{
	if(!this.ajouter) return;
	this.ajouter.style.display = actif?"inline":"none";
}

BlocData.prototype.ajouterData = function()
{
	var dataPrefixe = (this.unique?"u":"m") + this.tabData.length + "__";
	var data = new Data(this.meta,this.cat,this,new Object(),dataPrefixe);
	data.ajoutEnCours = true;
	this.conteneur.appendChild(data.init());
	this.tabData.push(data);
	this.majInterface();
}
//////////////////////////////////////////////
//   DATA
/////////////////////////////////////////////
function Data(objMeta,objCat,objBloc,objValeurs,prefixe)
{
	this.meta = objMeta;
	this.cat = objCat;
	this.bloc = objBloc;
	this.objDefinitions = this.bloc.objDefinitions;
	this.objValeurs = objValeurs;
	this.prefixe = prefixe;
	
	this.unique = this.bloc.unique;
	this.regroupement = this.bloc.regroupement;
	this.conteneur = null;
	
	this.ajouter = null;
	this.supprimer = null;
	this.nbUnique = this.meta.nbUnique++;
	this.ajoutEnCours = false;
}

Data.prototype.init = function()
{
	var e = creerElement("div",[["class","meta_data"+(this.regroupement?"_r":"")]]);
	this.conteneur = e;
	if(!this.ajoutEnCours) this.majValeur();
	else this.modifier();
	return e;
}	

/* affiche la valeur en lecture, lors initialisation, ou après modification */
Data.prototype.majValeur = function()
{	
	var texte,e2,e3,e4,e5,data=this,valAffichee;
	
	// bouton supprimer
	e4 = this.meta.donnerBouton("Supprimer");
	e4.style.display = "inline";
	e4.style.marginLeft = "6px";
	e4.onclick = function()
	{
		data.bloc.supprimerData(data);
	}
	var classe = "meta_data"+(this.regroupement?"_r":"");
	var classeOver = classe+" meta_supprimer";
	e4.onmouseover = function()
	{
		data.conteneur.className = classeOver;
	}
	e4.onmouseout = function()
	{
		data.conteneur.className = classe;
	}
	this.supprimer = e4;
	if(!isIE) e4.style.cssFloat = "right";
	else e4.style.styleFloat = "right";
	this.conteneur.appendChild(e4);
	this.conteneur.className = "meta_data"+(this.regroupement?"_r":"");  // pour rétablir classe normale après modification ou ajout
	
	
	
	// données
	for(var cle in this.objDefinitions) {
		if(this.objValeurs[cle] == undefined) continue;
		e2 = creerElement("div");
		if(this.regroupement) {
			e3 = creerElement("span",[["class","meta_nomdata"]]);
			e3.appendChild(document.createTextNode(this.objDefinitions[cle][4].replace(/.*,([^,]+)$/,"$1")+" : "));
			e2.appendChild(e3);
		}
		valAffichee = this.donneValAffichee(this.objDefinitions[cle][2],this.objValeurs[cle]);
		e3 = creerElement("span",[["class","meta_valdata"]]);
		e3.appendChild(document.createTextNode(unescape(valAffichee)));
		e2.appendChild(e3);
		
		e2.ondblclick = function() {data.modifier();}
		e2.style.cursor = "default";
		this.conteneur.appendChild(e2);
	}
	
	this.conteneur.title = "Double cliquer pour modifier";
	//this.conteneur.alt = "Double cliquer pour modifier";
}

// Certaines valeurs ne peuvent pas être utilisées telles quelles en affichage : les sauts de ligne doivent êtres remplacés dans les valeurs de type textarea, certaines valeurs ne sont pas enregistrées dans le format manipulé par l'utilisateur (date : jj/mm/aaaa, mais aaaa-mm-jj en base de données)
// type : type de donnée
// valeur : la valeur en base de données
// retourne la valeur convertie (si nécessaire) à afficher
Data.prototype.donneValAffichee = function (type,valeur)
{
	var valAff=valeur;
	switch(type) {
		case 'textarea':valAff=valeur.replace(/§/g," ").replace(/U\+00A7/g,"§");
						break;
		case 'date':if(valeur) {
						var tab=valeur.split("-");
						if(tab.length==3) {
							tab.reverse();
							valAff=tab.join("/");
						}
					}
					break;
		default:break;
	}
	return valAff;
}

Data.prototype.donneValeur = function()
{
	var temp = new Array();
	for(var cle in this.objValeurs) temp.push(this.prefixe+cle+"="+this.objValeurs[cle]);
	return temp.join("&");
}

Data.prototype.affAjouter = function(actif)
{
	if(!this.ajouter) return;
	this.ajouter.style.display = actif?"inline":"none";
}

Data.prototype.modifier = function()
{
	var data = this,contBoutons,valeur;
	viderElement(this.conteneur);
	
	contBoutons =  creerElement("div",[["class","meta_boutons"]]);	var b1 = this.meta.donnerBouton("Valider");
	b1.style.display = "inline";
	b1.onclick = function ()
	{
		data.validerSaisie();
	}
	b1.onmouseover = function()
	{
		data.conteneur.className = classeOver2;
	}
	b1.onmouseout = function()
	{
		data.conteneur.className = classe;
	}
	contBoutons.appendChild(b1);		
	
	var b2 = this.meta.donnerBouton("Annuler");
	b2.style.display = "inline";
	b2.style.marginLeft = "10px";
	b2.onclick = function ()
	{
		data.annulerSaisie();
	}
	b2.onmouseover = function()
	{
		data.conteneur.className = classeOver;
	}
	b2.onmouseout = function()
	{
		data.conteneur.className = classe;
	}
	contBoutons.appendChild(b2);
	this.conteneur.appendChild(contBoutons);
	
	if(!this.regroupement) {
		for(var cle in this.objDefinitions) {
			var e = creerElement("div");
			e.style.display = "inline";
			valeur = this.objValeurs[cle];
			if(valeur === undefined) valeur = "";
			this.ajouterSaisie(this,cle,this.objDefinitions[cle],unescape(valeur),e);
			this.conteneur.appendChild(e);
			break;
		}
		contBoutons = this.conteneur;
	}
	else {
		var tableau = document.createElement("table",[["width","100%"]]),ligne,cellule,titre,temp;
		var body = document.createElement("tbody");
		tableau.cellpadding = "3";
		tableau.cellspacing = "0";
		
		for(var cle in this.objDefinitions) {
			titre = this.objDefinitions[cle][4].replace(/.*,([^,]+)$/,"$1");
			ligne = document.createElement("tr");
			cellule = creerElement("td");
			temp = creerElement("div",[["class","meta_nomdata"]]);
			temp.appendChild(document.createTextNode(titre))
			cellule.appendChild(temp);
			
			ligne.appendChild(cellule);
			cellule = creerElement("td");
			temp = creerElement("div",[["class","meta_valdata"]]);
			valeur = this.objValeurs[cle];
			if(valeur === undefined) valeur = "";
			this.ajouterSaisie(this,cle,this.objDefinitions[cle],unescape(valeur),temp);
			cellule.appendChild(temp);
			ligne.appendChild(cellule);
			body.appendChild(ligne);
		}	
		
		tableau.appendChild(body);
		this.conteneur.appendChild(tableau);
	}
	
	var classe = "meta_data"+(this.regroupement?"_r":"");
	var classeOver = classe+" meta_"+(this.ajoutEnCours?"supprimer":"annuler");
	var classeOver2 = classe+" meta_valider";
}

Data.prototype.validerSaisie=function()
{
	var def,type,critereValidation,champ,valeur;
	var objNewValeurs = new Object();
	
	for(var cle in this.objDefinitions) {
		def = this.objDefinitions[cle];
		type = def[2].replace(/^([^_]+)_.*$/,"$1");  // pour les types de données qui contiennent infos sup, tels que string_s, string_m, etc.
		
		valeur = this.lireSaisie(cle);
		objNewValeurs[cle] = this.echapperSaisie(valeur);
		
		if(type == "booleen") continue;
		
		critereValidation = tabChamps[type][0];
		if(critereValidation == undefined) continue;		// si pas de format défini, ça passe		
		
		var resultat = null;
		var c = critereValidation.constructor;
		if(!c) continue;
		
		if(valeur != null) {
			if(c.toString().toLowerCase().indexOf("function regexp()") != -1) {   // un motif d'expression reguliere 
				resultat = valeur.match(critereValidation);
			}
			else resultat = critereValidation.call(this,valeur);
		}
	
		var message = tabChamps[type][1];
		if (valeur == null || resultat == null) {
			alert(def[4].replace(/,/g,", ") + " : " + message);
			return false;
		}	
	}
	
	this.objValeurs = objNewValeurs;
	viderElement(this.conteneur);
	this.ajoutEnCours = false;
	this.majValeur();
	this.bloc.majInterface();
	this.meta.majValeur();
}
Data.prototype.annulerSaisie=function()
{
	if(this.ajoutEnCours) {
		this.bloc.supprimerData(this);
		return;
	}
	viderElement(this.conteneur);
	this.majValeur();
	this.bloc.majInterface();
	this.meta.majValeur();
}

Data.prototype.lireSaisie=function(cle)
{
	if(!this.objDefinitions[cle]) return null;
	var def = this.objDefinitions[cle], baseNom = this.donneBaseNom(cle);
	var type = def[2].split("_")[0],valeur = null;
	
	switch(type) {
		case 'radio':var i=0,radio;
			while(1) {
				radio = document.getElementById(baseNom+"_"+i);
				if(!radio) break;
				if(radio.checked) {
					valeur = radio.value;
					break;
				}
				i++;
			}
			break;
				case 'select':var sel=document.getElementById(baseNom);
			if(!sel || sel.options.selectedIndex<0) break;
			valeur=sel.options[sel.options.selectedIndex].value;
		break;
		case 'booleen':var cb=document.getElementById(baseNom);
			if(!cb) break;
			var options = def[5];
			if(!options) break;
			valeur = options.split(",")[cb.checked?1:0];
		break;
		case 'textarea':var txt=document.getElementById(baseNom);
			if(!txt) break;
			valeur = txt.value.replace(/§/g,"U+00A7");
			valeur = valeur.replace(/\r?\n/g,"§");
		break;
		case 'date':var txt=document.getElementById(baseNom);
			if(!txt) break;
			if(txt.value) {
				var tab = txt.value.replace(/\s+/g,"").replace(/\D+/g,"/").split("/");
				if(tab.length>2) {
					if(tab[0].length<2) tab[0]="00".substr(0,2-tab[0].length)+tab[0];
					if(tab[1].length<2) tab[1]="00".substr(0,2-tab[1].length)+tab[1];
					//if(tab[2].length<4) tab[2]="2000".substr(0,4-tab[2].length)+tab[2];
					var annee=Number(tab[2]);
					if(!isNaN(annee)) {
						if(annee>=0 && annee<21) annee+=2000;
						else if(annee<100) annee+=1900;
						tab[2]=annee;
					}
					txt.value = tab[0]+"/"+tab[1]+"/"+tab[2];
					if(tab.length>3) tab = tab.splice(0,3);
					tab.reverse();
					valeur = tab.join("-");
				}
			}
		break;
		case 'time':var txt=document.getElementById(baseNom);
			if(!txt) break;
			if(txt.value) {
				var val = txt.value.replace(/\s+/g,"").replace(/\D+/g,":");
				var tab = val.split(":");
				if(tab.length>3) tab = tab.slice(0,3);
				for(var i=0;i<tab.length;i++) if(tab[i].length < 2) tab[i] = "00".substr(0,2-tab[i].length)+tab[i];
				valeur = tab.join(":");
				txt.value = valeur;
			}
		break;
		default:var txt=document.getElementById(baseNom);
			if(!txt) break;
			valeur = txt.value;
	}
	return valeur;
}

Data.prototype.donneBaseNom = function(cle)
{
	return "saisie_"+this.nbUnique+"_"+cle;
}

// echappe les caractères "&" et "=" dans l'argument
Data.prototype.echapperSaisie = function(texte)
{
	if (typeof(texte) != 'string') return texte;
	texte = texte.replace(/&/g,"%26").replace(/=/g,"%3D");
	return texte;
}

Data.prototype.ajouterSaisie = function(data,cle,definition,valeur,conteneur)
{
	var options = definition[5];
	var type = definition[2];
	var tabDetailType = type.split("_");
	type=tabDetailType[0];
	var tailleTxt=25;
	var baseNom = this.donneBaseNom(cle);
	if(tabDetailType.length>1) {
		switch(tabDetailType[1]) {
			case "s":tailleTxt="15";break;
			case "m":tailleTxt="25";break;
			case "l":tailleTxt="35";break;
		}
	}
	switch(type){
		case 'radio':var listeValeurs = options.split(",");
			for(var i in listeValeurs) {
				var label = document.createElement("span");
				label.appendChild(document.createTextNode(listeValeurs[i]));
				var radio = creerElement("input",[["type","radio"],["name",baseNom],["id",baseNom+"_"+i],["value",listeValeurs[i]]]);
				conteneur.appendChild(radio);
				if(valeur == listeValeurs[i]) {
					radio.setAttribute("checked",true);
					radio.setAttribute("defaultChecked",true);
				}
				radio=null;
				conteneur.appendChild(label);
			}
		break;
		case 'select':var listeValeurs = options.split(",");
			var tabValeurs=Array();
			for(var i in listeValeurs) tabValeurs[listeValeurs[i]] = listeValeurs[i];
			//var sel = creerElement("select",[["id",baseNom]]);
			var sel = creerElement("select",[["id",baseNom],["style","width:200px;"]]);
			ediSelect(sel,tabValeurs,valeur);
			conteneur.appendChild(sel);
			sel=null;
		break;
		case 'booleen':var cb=creerElement("input",[["type","checkbox"],["id",baseNom]]);			
			var val=valeur;
			conteneur.appendChild(cb);
			if(valeur == options.split(",")[1]) {
				cb.setAttribute("checked",true);
				cb.setAttribute("defaultChecked",true);
			}
			cb=null;
		break;
		case 'textarea':if(valeur) {
				valeur=valeur.replace(/'/g,"\'");
				valeur=valeur.replace(/§/g,"\r");
				valeur=valeur.replace(/U\+00A7/g,"§");
			}
			else valeur="";
			var txt = creerElement("textarea",[["id",baseNom],["cols",30],["rows",8]]);
			txt.appendChild(document.createTextNode(valeur));
			conteneur.appendChild(txt);
			txt=null;
		break;
		case 'date':if(valeur) {
				var tab=valeur.split("-");
				if(tab.length==3) {
					tab.reverse();
					valeur=tab.join("/");
				}
			}
			var text = creerElement("input",[["type","text"],["id",baseNom],["value",valeur],["size",10]]);
			conteneur.appendChild(text);
			text=null;
		break;
		case 'time':
			var text = creerElement("input",[["type","text"],["id",baseNom],["value",valeur],["size",8]]);
			conteneur.appendChild(text);
			text=null;
		break;
		default:if(valeur) valeur = valeur.replace(/'/g,"\'");
			else valeur="";
			var text = creerElement("input",[["type","text"],["id",baseNom],["value",valeur],["size",tailleTxt]]);
			conteneur.appendChild(text);
			text=null;
		break;
	}
}
////////////////////////////////////////////////////////////////////////////
/// FONCTIONS GÉNÉRIQUES, à extraire dans un fichier séparé
////////////////////////////////////////////////////////////////////////////
/**
 * Librairie Javascript, fonctions diverses
 *
 *
 * @category     lib
 * @package      kalon
 * @author       Stéphane Péron
 * @version      1.0
 *
 *
 *
 */



/**
 * Crée un élément HTML
 *
 * @param string balise   type d'élément à créer (nom de la balise)
 * @param array  attr     attributs et valeurs, sous forme d'un tableau de tableaux [attribut,valeur]
 * @return null|object    null ou élément HTML créé
 *
 */
function creerElement(balise,attr)
{
	balise=balise.toLowerCase();
	var element=null;
	var attributs=attr || null;
	
	if(navigator.userAgent.toLowerCase().indexOf("msie")!=-1 && balise=="input") {
		var code="<"+balise;
		for(var i in attributs) {
			try{
				code+=" "+attributs[i][0]+"='"+attributs[i][1].replace("'","\'")+"'";
			}
			catch(e){
				//debug("creerElement, IExplorer, balise="+balise+" ; attr="+attr.join(";"));//
			}
		}
		code+=" />";
		element=document.createElement(code);
		return element;
	}
	else element=document.createElement(balise);
	if(!element) return null;
	
	if(attributs==null) return element;
	
	var tabAttributs=new Object();
	if(typeof(attributs)=="string") {
		var temp=attributs.split(" ");
		var attribut;
		for(var i in temp) {
			attribut=temp[i].split("=");
			if(attribut.length<2 || attribut[0].length<1) continue;
			tabAttributs[attribut[0]]=attribut[1];
		}
	}
	else tabAttributs=attributs;
	
	for(var i in tabAttributs) {
		try{
			if(isIE && tabAttributs[i][0] == "class") tabAttributs[i][0] = "className";
			element.setAttribute(tabAttributs[i][0],tabAttributs[i][1]);
		}
		catch(e){
				//debug("creerElement, setAttritbute, balise="+balise+" ; attr="+attr.join(";"));//
		}
	}
	
	return element;
}

/**
 *
 */
function viderElement(e)
{
	if(!e.childNodes) return;	
	for(var i = e.childNodes.length-1;i >= 0;i--) e.removeChild(e.childNodes[i]);
}

/**
 * Réinitialise un champ de formulaire select (toutes les options sont supprimées)
 *
 * @param  HTMLElement select       élément HTML select à traiter
 * @param  array       tabValues    tableau indicé des options du select
 * @param  string      selection    valeur de l'option à sélectionner
 * @return integer                  indice de l'option sélectionnée
 *
 */
function ediSelect (select,tabValues,selection)
{
	viderSelect(select);
	var indice = 0;
	var i = 0;
	for (var propriete in tabValues) {
		select[i] = new Option(tabValues[propriete],propriete);
		if (tabValues[propriete] == selection || propriete == selection) indice = i;
		i++;
	}
	select.selectedIndex = indice;
	return indice;
}

/**
 * Supprime les options d'un select
 *
 * @param HTMLElement     élément HTML select à traiter
 *
 */
function viderSelect(select) {
	if(select.options) {
		for (var i=select.options.length; i>0; i--) {
			select.options[i-1] = null;
		}
	}
}

function validerDate(valeur)
{
	if(typeof(valeur)!="string") return null;
	var tab=valeur.split("-");
	if(tab.length!=3) return null;
	
	var jour=Number(tab[2]);
	var mois=Number(tab[1]);
	var annee=Number(tab[0]);
	
	if( isNaN(jour) || isNaN(mois) || isNaN(annee)) return  null;	
	
	// années bissextiles
	var tabMaxJour=new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
	if(annee%4==0)
	{
		if(annee%100!=0)
			tabMaxJour[2]=29;
		else if(annee%400==0)
			tabMaxJour[2]=29;
	}
	
	//controle validite
	if(mois<1||mois>12) return null;	
	if(jour<1||jour>tabMaxJour[mois]) return null;
	
	return true;
}

function validerTime(time)
{
	if(typeof(time)!="string") return null;
	var tab=time.split(":");
	if(tab.length<2) return null;
	
	var heure=Number(tab[0]);
	var minute=Number(tab[1]);
	var seconde=tab.length>2?Number(tab[2]):0;
	
	if(isNaN(heure) || isNaN(minute) || isNaN(seconde)) return null;
	if(heure<0 || heure>23 || minute<0 || minute>59 || seconde<0 || seconde>59) return null;
	return true;
}

// debuggage// debuggage
function init_debug(element)
{
	var conteneur = element || document.getElementsByTagName("body")[0];
	var e = creerElement("div",[["id","div_debug"],["style","background: #ffe; border: 2px solid #fff; padding: 4px;margin:10px;height:250px;overflow:scroll;font-family:monospace;"]]);
	if(conteneur.appendChild) {
		conteneur.appendChild(e);
		document._debug=true;
	}
	else alert("Impossible d'initialiser le debuggage, conteneur non valide");
}
function debug(txt)
{
	var e=document.getElementById("div_debug");
	if(!e) return;
	e.appendChild(document.createTextNode(txt));
	e.appendChild(document.createElement("br"));
}
