/*--------------------------------------------------------------------------*/
/*  EC JavaScript framework, version 1.0.4
 * (c) Eric Cinget - C.D.I. Logiciels - 2007/2010
/*--------------------------------------------------------------------------*/

//var ec = {};  
var ec = Class.create();

ec.debug = {  /** ec.debug : espace de nom pour les fonctions de débuggage **/

    create : function(iTop, iLeft, iCols, iRows) {  /** ec.debug.create : création du 'textarea' d'affichage **/
	    if(!$('ECTXTDEBUG')) {
		    var oDebug = $(document.createElement('textarea'));	 
		    iTop = isEmpty(iTop) ? '520px' : (iTop.indexOf('px')!=-1 ? iTop : iTop + 'px');  
	        iLeft = isEmpty(iLeft) ? '10px' : (iLeft.indexOf('px')!=-1 ? iLeft : iLeft + 'px');  
	        iCols = isEmpty(iCols) ? '130' : iCols;  
	        iRows = isEmpty(iRows) ? '15' : iRows; 
			
			oDebug.setStyle({top: iTop, left: iLeft, position: 'absolute', zIndex: '1000'}); 
			oDebug.setAttribute('id', 'ECTXTDEBUG');
			oDebug.setAttribute('name', 'ECTXTDEBUG');
			oDebug.setAttribute('cols', iCols);
			oDebug.setAttribute('rows', iRows); 
			document.body.appendChild(oDebug); 
		}	
		return $('ECTXTDEBUG');
	},  /** fin : ec.debug.create **/
		
	print : function(s) {  /** ec.debug.print :	écriture d'une ligne **/
		var oDebug = ec.debug.create(); 
		
		s = oDebug.value + s;
		oDebug.value = s;
	},  /** fin : ec.debug.print **/
	
	print2 : function(s, iTop, iLeft, iCols, iRows) {  /** ec.debug.print :	écriture d'une ligne **/
		var oDebug = ec.debug.create(iTop, iLeft, iCols, iRows); 
		
		s = oDebug.value + s;
		oDebug.value = s;
	},  /** fin : ec.debug.print **/	  
	
	time : function(s) {  /** ec.debug.time :	écriture du nombre de millième de seconde **/
		var oDebug = ec.debug.create(); 
		var dtNow = new Date();
		
		s = oDebug.value + dtNow.getTime() + s;
		oDebug.value = s;
	}  /** fin : ec.debug.time **/
};  /** fin : ec.debug **/ 

ec.base = {	/** ec.base : espace de nom pour les fonctions de bases **/

    proprietes : function(oCible, tP) {  /** ec.base.proprietes : affecte les propriétés du tableau à l'object **/	
	    var oCible = $(oCible)							   
		for (var name in tP) {
		    oCible[name] = tP[name];
	    }		   
	},  /** fin : ec.base.proprietes **/  
	
	setProperty : function(oCible, tP, tS, tX) {  /** ec.base.setProperty : affecte les propriétés et les styles des tableaux à l'object **/
	    var oCible = $(oCible)		
		// atribues					   
		for (var name in tP) {
		    oCible[name] = tP[name];
	    }	
		// styles	
		if(!isEmpty(tS)) {
			oCible.setStyle(tS); 
		}	
		// atribues non standards
		if(!isEmpty(tX)) {
			for (var name in tX) {
				oCible.setAttribute(name, tX[name]); 
		    }	
		}  
		return oCible; 
	},  /** fin : ec.base.setProperty **/  
	
	idObject : function(tP) { /** dénomination unique des id des objects créés dynamiquement **/   
		var sRacine = isEmpty(tP) ? '' : tP.racine || '';	// racine du nom de l'id (option) 
		ec.base.compteur1++;
		return sRacine + 'OBJDYN' +  ec.base.compteur1;
	},  /** fin : ec.base.idObject **/    
	
	zIndex : function() { /** compteur des zIndex "modal" créés dynamiquement  **/   
		ec.base.compteur2++;
		return ec.base.compteur2;
	},  /** fin : ec.base.idObject **/  
	
	compteur1 : 0, /** utilisé par idObject **/    
	
	compteur2 : 9000 /** utilisé par zIndex **/  
	
}; /** fin : ec.base	 **/

ec.gdi = {	/* ec.gdi : espace de nom pour les fonctions graphiques **/	
	
	valCalibre : 1,	/** ec.gdi.valCalibre : valeur du calibrage de la vitesse d'exécution en millième de seconde **/	 
	
	temp1 : 0, /** utilisé par calibre **/ 
	
	temp2 : 0, /** utilisé par calibre **/ 
	
	calibre : function(tP) {	/** ec.gdi.calibre : calibre la vitesse d'exécution **/	
		var sUrl = tP.url || null;	// url de l'image à tester, à ajouter dans background	  
		var bTest = true;	
		var iTest = 0, iVal = 0, iRet = 0;
		
		if(document.body)
		{	  
			var oTest = $(document.createElement('div'));		
			oTest.setStyle({top:'100px', left:'0px', width:'1000px', height:'100px', position:'absolute', zIndex:'1000', border:'3px dotted blue', backgroundColor:'mediumpurple'}); 
			if(sUrl) {
			    oTest.setStyle({background: 'url('+sUrl+')'});
			}
			oTest.setAttribute('id', ec.base.idObject());
			document.body.appendChild(oTest);

			function fTest() { 
			   ec.gdi.opacity(oTest, {
			       duration:1, 
				   from:10, 
				   to:100, 
				   interval:10,
				   beforeStart: function(){
				       ec.gdi.temp1 = Date.getTime();
				   },
				   afterEnd: function(){
				       ec.gdi.temp2 = Date.getTime();	 
					   var t1 = new Number(ec.gdi.temp1);
					   var t2 = new Number(ec.gdi.temp2);	 
					   var dif = new Number(t2-t1);	
					   dif = (dif-1000)/100; 
					   dif = (dif<1) ? 1 : dif;
					   ec.gdi.valCalibre = dif;			 
					   if(oTest) { document.body.removeChild(oTest); }	  
					   ec.debug.print('ec.gdi.temp1='+t1+'\n'+'ec.gdi.temp2='+t2+'\n'+'dif='+dif+'\n');  
				   }
			    });	 
				
			    return 	dif;
			}
			  
			var iVal = fTest();	
			if(iVal>0) {
			    iRet = Math.round(iVal/100);
			} 
		}
		if(iRet==0) {iRet = 1;}
		ec.gdi.valCalibre = iRet;
		
		return iRet;
	}, /** fin : ec.gdi.calibre **/
	
	getPoint : function(oCible, sComp) { /** ec.gdi.getPoint : retourne les positions et dimensions de l'object **/ 
	    var iTop=0, iLeft=0, iWidth=0, iHeight=0;
		
		oCible = $(oCible);
		sComp = isEmpty(sComp) ? '' : sComp;
		if(oCible) { 
			var oPos = Position.positionedOffset(oCible);
			iLeft = oPos[0]+sComp;
			iTop = oPos[1]+sComp;	  
			var oDim = Element.getDimensions(oCible); 
			iWidth = oDim.width+sComp;
			iHeight = oDim.height+sComp;
		} 	 
		return {top:iTop, left: iLeft, width: iWidth, height: iHeight}
	}, /** fin : ec.gdi.getPoint **/
	
	transition : function(oCible, tP) {	/** ec.gdi.transition : effectue une transition de couleur entre deux couleur **/	
	    var aProps = $A(tP.proprietes) || $A([]);	// proprietés de style à modifier séparé par un point-virgule ex: 'border-color;color;background-color'
		var hColDebut = tP.colorDebut || '';	// couleur de début en hexadecimal
		var hColFin = tP.colorFin || '';	// couleur de fin en hexadecimal	
		var interval = isEmpty(tP.interval) ? 10 : tP.interval;  // intervale en millième de seconde entre chaque changement ou durée en seconde, l'interval est prioritaire  
		var iPas = isEmpty(tP.pas) ? 1 : tP.pas;  // multiplicateur de pas de transition  
		//var fDuration = isEmpty(tP.duration) ? null : tP.duration;	// durée de l'effet en seconde, ou intervale en millieme de seconde, l'interval est prioritaire 
		var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer l'effect 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin de effect	 
		var iR1 = 0.0, iV1 = 0.0, iB1 = 0.0, iR2 = 0.0, iV2 = 0.0, iB2 = 0.0;
		var fIdcR = 0.0, fIdcV = 0.0, fIdcB	= 0.0;
		var iNbPas = 0, idTime = 0; 
		var bRSens = true, bVSens = true, bBSens = true;
		
		hColDebut = hColDebut.replace("#", ''); 
		hColFin = hColFin.replace("#", '');  
		
		if(aProps.size()>0 && !isNaN(parseInt(hColDebut,16)) && !isNaN(parseInt(hColFin,16)) && hColDebut.length==6 && hColFin.length==6) {
			oCible = $(oCible);
			if(foncBeforeStart) { foncBeforeStart(); }	 	
			
			oCible._transition = function(r, v, b) {	
			    aProps.each(function(n){
				    oCible.style[n] = '#' + r.toColorPart() + v.toColorPart() + b.toColorPart();
				});	
			}	
			
			oCible._transitionProgress = function() {
				if(bRSens) {iR1+=(fIdcR*iPas)} else {iR1-=fIdcR*iPas};
				if(bVSens) {iV1+=fIdcV*iPas} else {iV1-=fIdcV*iPas};
				if(bBSens) {iB1+=fIdcB*iPas} else {iB1-=fIdcB*iPas};			   
				if(((bRSens&&iR1>=iR2)||(!bRSens&&iR1<=iR2)) && ((bVSens&&iV1>=iV2)||(!bVSens&&iV1<=iV2)) && ((bBSens&&iB1>=iB2)||(!bBSens&&iB1<=iB2))) {
					self.clearInterval(idTime); 
				    if(foncAfterEnd) { foncAfterEnd(); } 	
				} else {
					oCible._transition(parseInt(iR1,10), parseInt(iV1,10), parseInt(iB1,10));
				}
			}
			
			iR1 = parseInt(hColDebut.substring(0,2),'16');
			iV1 = parseInt(hColDebut.substring(2,4),'16');
			iB1 = parseInt(hColDebut.substring(4,6),'16');
			iR2 = parseInt(hColFin.substring(0,2),'16');
			iV2 = parseInt(hColFin.substring(2,4),'16');
			iB2 = parseInt(hColFin.substring(4,6),'16'); 
			
			iNbPas = Math.abs(iR1-iR2);
			iNbPas = Math.abs(iV1-iV2)>iNbPas ? Math.abs(iV1-iV2) : iNbPas;
			iNbPas = Math.abs(iB1-iB2)>iNbPas ? Math.abs(iB1-iB2) : iNbPas;	  
			
			fIdcR = Math.abs(iR1-iR2)/iNbPas; 	
			fIdcV = Math.abs(iV1-iV2)/iNbPas;
			fIdcB = Math.abs(iB1-iB2)/iNbPas;	
			
			bRSens = iR1<=iR2 ? true : false;
			bVSens = iV1<=iV2 ? true : false;
			bBSens = iB1<=iB2 ? true : false;
			
			iValProgress = 0;
			  	 
			if(interval) {
			    idTime = self.setInterval("$('"+oCible.getAttribute('id')+"')._transitionProgress();", interval);  
			} 
		} 
	}, /** fin : ec.gdi.transition **/
	
	masque : function(oSource, tP) {  /** ec.gdi.masque : applique un filtre par dessus l'object **/	  
	    var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer l'effect 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin de effect	
		var opacity = tP.opacity || null;	// opacité {}
		var oStyle = tP.style || null;	// style du masque ou nom css du style	
		var fOnclick = tP.onclick || null;	// evenement onclick du masque
		var oPoint = null;	
		var oCible = null;
		var oBackupStyle = ''; 
		var zIndex = null;
			
		if(foncBeforeStart) { foncBeforeStart(); }	 
				  
		if(oSource==window || oSource==document || oSource==document.body) {
	    	oSource = $(document.body);
			oPoint = {top:0, left: 0, width: screen.availWidth, height: screen.availHeight};	
		} else {		 
			oSource = $(oSource);			
	    	oPoint = ec.gdi.getPoint(oSource);
		}
		if(oPoint!=null){	
			oBackupStyle = {overflow: oSource.getStyle('overflow'), overflowX: oSource.getStyle('overflowX'), overflowY: oSource.getStyle('overflowY')};	
			oSource.setStyle({overflow: 'hidden', overflowX: 'hidden', overflowY: 'hidden'});	
			//oSource.setAttribute('scroll', false);	 
		 	oCible = $(document.createElement('div'));
			oCible.setStyle({top: oPoint.top + 'px', left: oPoint.left + 'px', width: oPoint.width + 'px', height: oPoint.height + 'px', position:'absolute'});
			oCible.setStyle({zIndex: ec.base.zIndex()});  
			if(oStyle!=null) {
				if(typeof(oStyle)=='object') {
					oCible.setStyle(oStyle);	
				} else {
					oCible.setAttribute('class', oStyle); 
				}
			}  
			oCible.setAttribute('id', ec.base.idObject({}));   
			oCible._unload = function(iVal) {	
				oSource.setStyle(oBackupStyle);
			}
			if(fOnclick!=null) {
				oCible.onclick = fOnclick;
			}
			if(opacity!=null) {		
				oCible.setOpacity(((isEmpty(opacity.taux)) ? opacity.from : opacity.taux)/100);
				document.body.appendChild(oCible); 
				ec.gdi.opacity(oCible, opacity);
			} else {
				document.body.appendChild(oCible);   
			}
		}
	    	    
	    if(foncAfterEnd) { foncAfterEnd(); } 	
		
		return oCible;
	    
	}, /** fin : ec.gdi.masque 	**/
	
	scale : function(oCible, tP) {	/** ec.gdi.scale : redimensionne l'object cible **/	  
	   	var iFrom = tP.from;	// taille au debut de de effet en pourcentage
		var iTo = tP.to;	// taille a la fin de de effet en pourcentage 
		var fDuration = tP.duration || null;	// durée de l'effet en seconde	  
	    var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer l'effect 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin de effect	 
		var interval = isEmpty(tP.interval) ? 10 : tP.interval;  // intervale en millième de seconde entre chaque changement
		var iPercent = tP.percent || null;  // pourcentage à appliquer sur les dimension de l'object
		var iDirection = tP.direction || 'top-left';
		var idTime = 0, iTauxProgress = 0;
		var bBoucle = false;
												  
		oCible = $(oCible);	 	
		var oPoint = ec.gdi.getPoint(oCible);

		if(foncBeforeStart) { foncBeforeStart(); }	 
		
		oCible._dimension = function(iVal) {	
			var oPTemp = ec.gdi.getPoint(oCible);	 	
			var iNewWidth = (oPoint.width*iVal)/100;
			var iNewHeight = (oPoint.height*iVal)/100; 	
			var newX = 0, newY = 0;
			var bSens = (iNewWidth>oPTemp.width) ? true : false; 
			
			switch(iDirection) {
			    case 'bottom-right':
					newX = oPTemp.left;  
				    newY = oPTemp.top;
				    break;	 
				case 'bottom-left':	
					if(bSens) {   
				        newX = oPoint.left-(oPTemp.width-oPoint.width);
					} else {
					    newX = oPoint.left+(oPoint.width-iNewWidth); 
					} 	
					newY = oPTemp.top;	 
				    break;	
				case 'top-right':	
					if(bSens) {   
				        newY = oPoint.top-(iNewHeight-oPoint.height);
					} else {
					    newY = oPoint.topp+(oPoint.height-iNewHeight); 
					} 	
					newX = oPTemp.left;	
				    break;
				case 'top-left':	
					if(bSens) {   
				        newY = oPoint.top-(iNewHeight-oPoint.height);	
						newX = oPoint.left-(oPTemp.width-oPoint.width);
					} else {
					    newY = oPoint.top+(oPoint.height-iNewHeight); 
						newX = oPoint.left+(oPoint.width-iNewWidth); 
					}  
				    break;
				case 'center':	
					if(bSens) {   
				        newY = oPoint.top-(iNewHeight-oPoint.height)/2;	
						newX = oPoint.left-(oPTemp.width-oPoint.width)/2;
					} else {
					    newY = oPoint.top+(oPoint.height-iNewHeight)/2; 
						newX = oPoint.left+(oPoint.width-iNewWidth)/2; 
					}   
				    break;
			}	
			oCible.setStyle({width: parseInt(iNewWidth,10)+'px', height: parseInt(iNewHeight,10)+'px', top: parseInt(newY,10)+'px', left: parseInt(newX,10)+'px'});	
		}  
		
		oCible._dimensionProgress = function(iVal) {
			var bSens = (iFrom>iTo) ? true : false;
			
			if(bSens) {
				if(iTauxProgress>iTo) {	 
					oCible._dimension(iTauxProgress);	
				    iTauxProgress+=iVal;
				} else {  
				    oCible._dimension(iTo); 
				  	self.clearInterval(idTime); 
					 
					if(foncAfterEnd) { foncAfterEnd(); } 	
				} 
			} else {
			    if(iTauxProgress<iTo) {	
			        oCible._dimension(iTauxProgress);	
					iTauxProgress+=iVal;
				} else {   
				    oCible._dimension(iTo);	
					self.clearInterval(idTime); 
		 
				    if(foncAfterEnd) { foncAfterEnd(); } 	
				} 
			}  
		}  
		 
		if(fDuration) {		 
			var iTempo = parseInt((fDuration*1000)/(interval+ec.gdi.valCalibre));  
			var iPas = 0;
			if(iFrom>iTo) {
				iPas = (iFrom-iTo)/iTempo;
			} else {
				iPas = (iTo-iFrom)/iTempo;
			} 	
			iTauxProgress = iFrom;	  	 
			idTime = self.setInterval("$('"+oCible.getAttribute('id')+"')._dimensionProgress("+iPas+");", interval); 	
		} else if(iPercent) { 
		    oCible._dimension(iPercent); 	   
			
			if(foncAfterEnd) { foncAfterEnd(); } 	
		} 
	}, /** fin : ec.gdi.scale **/
	
	flicker	: function(oCible, tP) {  /** ec.gdi.flicker : change le style de l'élément ou execute les functions à intervale régulier **/	  
	    var interval = isEmpty(tP.interval) ? 250 : tP.interval;  // intervale en millième de seconde entre chaque changement
		var style1 = tP.firstStyle || {} // premier style ou function
		var style2 = tP.secondStyle || {} // deuxième style ou function
		
		oCible = $(oCible);
		oCible.$styleBackup = oCible.style.cssText; 		
	
		oCible._firstFlicker = function() {	   
		    if(typeof(style1)=='function') { 
			    style1();	   
			} else {  
			    oCible.setStyle(style1);	
			}
			var idTime = self.setTimeout("$('"+oCible.getAttribute('id')+"')._secondFlicker();", interval); 
			oCible.$handlerFlicker = idTime;	
		}
		
		oCible._secondFlicker = function(style) {	
			if(typeof(style2)=='function') {
			    style2();	   
			} else {  
			    oCible.setStyle(style2);	
			}	 
		    var idTime = self.setTimeout("$('"+oCible.getAttribute('id')+"')._firstFlicker();", interval);   
			oCible.$handlerFlicker = idTime;
		} 
		
		var idTime = self.setTimeout("$('"+oCible.getAttribute('id')+"')._firstFlicker();", interval); 
	}, /** fin : ec.gdi.flicker **/	 
	
	stopFlicker	: function(oCible) {  /** ec.gdi.stopFlicker : arrête le flicker en cours sur l'élement et restaure les paramètres de style originaux **/	
	    
		if(isFinite(oCible)) {
		    self.clearTimeout(oCible);
		} else {
			oCible = $(oCible);
			var handler = oCible.$handlerFlicker;
			oCible.$handlerFlicker = null;	
			self.clearTimeout(handler);
			if(oCible.style.setAttribute) { 
	            oCible.style.setAttribute('cssText', oCible.$styleBackup);   
			} else  {
			    oCible.setAttribute("style", oCible.$styleBackup);	
			}  
		}
	}, /** fin : ec.gdi.stopFlicker **/
		
	opacity : function(oCible, tP) {  /** ec.gdi.opacity : applique un filtre d'opacité sur un element **/	
	    var iTaux = isEmpty(tP.taux) ? 0 : tP.taux; // taux d'opacité fixe (paramètre obligatoire)
		var iFrom = tP.from;	// taux d'opacité du début de effet
		var iTo = tP.to;	// taux d'opacité à la fin de effet	 	  
		var interval = isEmpty(tP.interval) ? 20 : tP.interval;  // intervale en millième de seconde entre chaque changement
		var fDuration = tP.duration || null;	// duré de l'effet en seconde, lié à 'from' et 'to'	### IMPORTANT : DOIT POSSEDER UN ID POUR FONCTIONNER ### 
		var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer l'effect 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin de effect
		var idTime = 0, iTauxProgress = 0;
		
		oCible = $(oCible); 
		if(foncBeforeStart) { foncBeforeStart(); } 
			
		oCible._opacity = function(iVal) {	
			oCible.style.opacity = (iVal / 100); 
	    	oCible.style.MozOpacity = (iVal / 100); 
	    	oCible.style.KhtmlOpacity = (iVal / 100); 
	    	oCible.style.filter = "alpha(opacity=" + iVal + ")";   
		}	
		
		oCible._opacityProgress = function(iVal) {
			var bSens = (iFrom>iTo) ? true : false;
			
			if(bSens) {
				if(iTauxProgress>iTo) {	 
					oCible._opacity(iTauxProgress);	
					iTauxProgress+=iVal;
				} else {  
				  oCible._opacity(iTo);
				  self.clearInterval(idTime); 
				  //ec.debug.print('t2Opa='+Date.getTime()+'\n');
				  if(foncAfterEnd) { foncAfterEnd(); } 	
				} 
			} else {
			    if(iTauxProgress<iTo) {	  
			        oCible._opacity(iTauxProgress);	
					iTauxProgress+=iVal;
				} else {  
				  oCible._opacity(iTo);	
				  self.clearInterval(idTime); 		  
				  //ec.debug.print('t2Opa='+Date.getTime()+'\n');
				  if(foncAfterEnd) { foncAfterEnd(); } 	
				} 
			}  
		}  				
		  
		if(fDuration && oCible.getAttribute('id')!='' && oCible.getAttribute('id')!=null) {	 
			var iNbInterval = parseFloat((fDuration*1000)/(interval+ec.gdi.valCalibre)); 
			//var iTempo = ((fDuration*1000)-(iTempo1*ec.gdi.valCalibre))/interval; 
			var iPas = 0;
			if(iFrom>iTo) {
				iPas = (iFrom-iTo)/iNbInterval;
			} else {
				iPas = (iTo-iFrom)/iNbInterval;
			} 		
			iPas = (iPas<1) ? 1 : iPas;
			//ec.debug.print('iNbInterval='+iNbInterval+' iTauxProgress='+iTauxProgress+' iPas='+iPas+' interval='+interval+' t1Opa='+Date.getTime()+'\n');
			iTauxProgress = iFrom;	
			oCible._opacityProgress(iPas);
			idTime = self.setInterval("$('"+oCible.getAttribute('id')+"')._opacityProgress("+iPas+");", interval); 
		} else {
			if(iTaux) {  
		    	oCible._opacity(iTaux);  
				if(foncAfterEnd) { foncAfterEnd(); }  
			}
		} 
	 		  
	},  /** fin : ec.gdi.opacity **/
	
	blur : function(oCible, tP) {  /** ec.gdi.blur : floute l'element **/	
	    var iTaux = isEmpty(tP.taux) ? 2 : tP.taux;	// taux de flou de 1 à 10
		var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer l'effect 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin de effect
		
		oCible = $(oCible);	
		 
		// création du conteneur
		var oBlur = ec.gdi.ghost(oCible);		 
		oBlur.setStyle({position:'absolute'});
		oBlur.setStyle(ec.gdi.getPoint(oCible, 'px'));    
		// création des clones	 
		var oNew1 = $(oCible.cloneNode(true)); 
		var oNew2 = $(oCible.cloneNode(true)); 
		var oNew3 = $(oCible.cloneNode(true)); 
		var oNew4 = $(oCible.cloneNode(true)); 
		oNew1.setStyle({border:'none'});
		oNew2.setStyle({border:'none'});
		oNew3.setStyle({border:'none'});
		oNew4.setStyle({border:'none'});
		new ec.gdi.opacity(oNew1, {taux:65});	
		new ec.gdi.opacity(oNew2, {taux:45});	
		new ec.gdi.opacity(oNew3, {taux:30});	
		new ec.gdi.opacity(oNew4, {taux:15});	
		oBlur.appendChild(oNew1);
		oBlur.appendChild(oNew2);
		oBlur.appendChild(oNew3);
		oBlur.appendChild(oNew4);	
		
		if(foncBeforeStart) { foncBeforeStart(); } 	
		
		oNew1.setStyle({top: '0px', left: -iTaux+'px', position: 'absolute'});
		oNew2.setStyle({top: '0px', left: iTaux+'px', position: 'absolute'});
		oNew3.setStyle({top: -iTaux+'px', left: '0px', position: 'absolute'});
		oNew4.setStyle({top: iTaux+'px', left: '0px', position: 'absolute'}); 
				
		if(foncAfterEnd) { foncAfterEnd(); }

	},  /** fin : ec.gdi.blur **/
	   
	slide : function(oCible, tP) {  /** ec.gdi.slide : applique un filtre d'opacité sur un element **/	
		var iDirection = tP.direction || 'up'; // direction de l'effet
		var interval = isEmpty(tP.interval) ? 10 : tP.interval;  // intervale en millième de seconde entre chaque changement
		var fDuration = isEmpty(tP.duration) ? 2 : tP.duration;	// duré de l'effet en seconde	  
		var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer l'effect 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin de effect
		var idTime = 0, iIdcProgress = 0;  
		
		oCible = $(oCible);	
		 
		// création du conteneur
		var oDimension = Element.getDimensions(oCible);  
		var iWidth = oDimension.width;
		var iHeight = oDimension.height; 	
		var oSlide = ec.gdi.ghost(oCible);		 
		// création du clone
		var oNew = $(oCible.cloneNode(true)); 
		oNew.setAttribute('id', oCible.getAttribute('id')+'ECCloneSlide'); 
		oNew.setStyle({top: '0px', left: '0px', position: 'absolute'});
		oSlide.appendChild(oNew);	
		// masquage de la cible
		oCible.hide();  	
		
		if(foncBeforeStart) { foncBeforeStart(); }
		 
		oNew._slide = function(iVal) {		 	 	   
			var newX = 0, newY = 0;
			
			switch(iDirection) {
				case 'up':	
				    newX = 0;
					newY = -iVal; 
				    break;	
				case 'down':	
					newX = 0;
					newY = iVal; 
				    break;
				case 'left':	
					newX = -iVal;
					newY = 0; 
				    break;
				case 'right':	
					newX = iVal;
					newY = 0; 
				    break;
			}	
			oNew.setStyle({top: newY+'px', left: newX+'px'});	
		}  
	
		oNew._slideProgress = function(iVal) {
			var bFin = false;
			
			iIdcProgress = parseInt(iIdcProgress+iVal);
			switch(iDirection) {
				case 'up':	
				    if(iIdcProgress<iHeight+1) {
						oNew._slide(iIdcProgress);	
					} else { 
						bFin = true;
					}
				    break;	
				case 'down':	
				    if(iIdcProgress<iHeight+1) {
						oNew._slide(iIdcProgress);	
					} else {	   
						bFin = true;
					}
				    break;	
				case 'left':	
					if(iIdcProgress<iWidth+1) {
						oNew._slide(iIdcProgress);	
					} else {	 
						bFin = true;
					} 
				    break;
				case 'right':	
					if(iIdcProgress<iWidth+1) {
						oNew._slide(iIdcProgress);	
					} else {   
						bFin = true;
					} 
				    break;
			}	
			if(bFin) {
			
			    oNew._slide(iIdcProgress);
	    		self.clearInterval(idTime);	
				oNew.remove(oNew);
				oSlide.remove(oSlide);	  
				
				oCible.show();  
				
				if(foncAfterEnd) { foncAfterEnd(); } 
			}
		} 
		  
		if(fDuration) {			 
			var iTempo = parseInt((fDuration*1000)/(interval+ec.gdi.valCalibre)); 
			var iPas = 0;
			switch(iDirection) {
				case 'up':	
				    iPas = iHeight/iTempo; 
				    break;	
				case'down':	
				    iPas = iHeight/iTempo; 
				    break;	
				case 'left':	
					iPas = iWidth/iTempo; 	 
				    break; 
				case 'right':	
					iPas = iWidth/iTempo; 	 
				    break;
			}	
			iIdcProgress = 0;	
			idTime = self.setInterval("$('"+oNew.getAttribute('id')+"')._slideProgress("+iPas+");", interval);	
		} 
	},  /** fin : ec.gdi.slide **/
	
	moveBy : function(oCible, tP) {  /** ec.gdi.moveBy : déplace un element **/	
		var x = tP.x;	// point x de déplacement en coordonnées absolues du conteneur (paramètre obligatoire)
		var y = tP.y;	// point y de déplacement en coordonnées absolues du conteneur (paramètre obligatoire) 
		var interval = isEmpty(tP.interval) ? 5 : tP.interval;  // intervale en millième de seconde entre chaque déplacement
		var pasX = isEmpty(tP.pasX) ? 30 : tP.pasX;  // pas du déplacement vertical en pixel
		var pasY = isEmpty(tP.pasY) ? 20 : tP.pasY;  // pas du déplacement horizontal en pixel
		var foncBeforeStart = tP.beforeStart || null;  // fonction a exécuter avant de commencer le déplacement 
		var foncAfterEnd = tP.afterEnd || null;  // fonction a exécuter après la fin du déplacement
		var idTime = null;	 
		
		oCible = $(oCible);		 
		
		if(foncBeforeStart) { foncBeforeStart(); } 	
		idTime = setInterval("$('"+oCible.getAttribute('id')+"')._deplace();", interval+ec.gdi.valCalibre); 
				
		oCible._deplace = function() {	  
		    var oPos = Position.positionedOffset(oCible);
			var posX = oPos[0], posY = oPos[1];
			var tmpX, tmpY; 
			var bx = false, by = false;	 
			
			if(x!='auto') {
				if(x>posX) {
					posX+=pasX; 
					bx=posX<x; 
					if(x<posX) { posX=x; }
				}
				else { 
					posX-=pasX;
					bx=posX>x;  
					if(x>posX) { posX=x; }
				}	
			}  
			if(y!='auto') {
				if(y>posY) {
					posY+=pasY; 
					by=posY<y; 
					if(y<posY) { posY=y; }
				}
				else { 
					posY-=pasY;
					by=posY>y;	 
					if(y>posY) { posY=y; }
				}	
			}
			// ************DEBUG**********	
			//ec.debug.print('bx='+bx+' by='+by+' posX='+posX+' posY='+posY+' idTime='+idTime+' interval='+interval+'\n');
			// ***************************  
			if(bx||by) { 
				tmpX = (x=='auto') ? 'auto' : posX+'px';
				tmpY = (y=='auto') ? 'auto' : posY+'px';	 
			    oCible.setStyle({left: tmpX, top: tmpY});	
			}
			else {	
				tmpX = (x=='auto') ? 'auto' : x+'px';
				tmpY = (y=='auto') ? 'auto' : y+'px';	   
				self.clearInterval(idTime);  
				oCible.setStyle({left: tmpX, top: tmpY});	 		
				if(foncAfterEnd) { foncAfterEnd(); }
			}
		}	    	   
	},  /** fin : ec.gdi.moveBy **/	  
	
	ghost : function(oSource, tP) {  /** ec.gdi.ghost : créé une copie vide et invisible de l'élément **/	
		var oGhost = $(document.createElement('div'));	
		var oDimension = Element.getDimensions(oSource);  
		var oPos = Position.positionedOffset(oSource); 
		oGhost.setStyle(ec.gdi.getPoint(oSource, 'px'));
		oGhost.setStyle({position: oSource.getStyle('position'), background: 'transparent', border: 'none', overflow: 'hidden', zIndex: oSource.getStyle('zIndex')}); 
		oGhost.setAttribute('id', oSource.id+'ECGhost');
		oSource.parentNode.appendChild(oGhost); 	
		
		return oGhost;

	}  /** fin : ec.gdi.ghost **/
	
}; /** fin : ec.gdi **/

ec.drag = {	/** ec.drag : espace de nom pour le dragdrop	 **/	 
	
	draggable : function(oSource, tP) {  /** ec.drag.draggable : rend l'object cible 'draggable' **/	 	
		oSource = $(oSource); 
	    oSource.$draggable = true;	
	    oSource.$isDragDrop = false;
	    oSource.$cible = isEmpty(tP.cible) ? oSource.getAttribute('id') : $(tP.cible).getAttribute('id');  
	    oSource.setStyle({cursor: 'move'});	 
		oSource.$actionEvent = 'DRAG';
		oSource.$isMoveEndDrag = isEmpty(tP.move_end_drag) ? false : tP.move_end_drag;  // déplace la cible à la fin du drag sur la position du ghost
		oSource.$isGhost = isEmpty(tP.ghost) ? true : tP.ghost;  // affiche un control fantôme pendant le drag sinon l'élement bouge lui même 	
		oSource.$isDragHide = isEmpty(tP.hide) ? false : tP.hide;  // masque le control source pendant le drag	   
		oSource.$isDragBack = isEmpty(tP.back) ? true : tP.back;  // retour visible de l'element du drag si relache du bouton 
		oSource.$beforeDrag = tP.beforeDrag || null;  // fonction a exécuter avant de commencer le déplacement 	
		oSource.$afterDrag = tP.afterDrag || null;  // fonction a exécuter après la fin du déplacement	
		oSource.$dragFlicker = tP.flicker || null;  // effet flicker à appliquer sur le ghost si drag 
		oSource.$dragStyle = tP.style || {};  // style du ghost sous forme de hash, 'style' est prioritaire sur 'opacity' et sur tout autres paramètres  
		//oSource.$cursor = tP.cursor || '';  // curseur à afficher lors du déplacement, 'cursor' est prioritaire sur 'opacity'	 
		oSource.$dragOpacity = isEmpty(tP.opacity) ? 50 : tP.opacity;  // taux d'opacité du ghost
		oSource.$isDragVertical = isEmpty(tP.vertical) ? true : tP.vertical;  // autorise le déplacement vertical  
		oSource.$isDragHorizontal = isEmpty(tP.horizontal) ? true : tP.horizontal;  // autorise le déplacement horizontal 	  
		   
	},  /** fin : ec.drag.draggable	**/
	
	move : function(e) {  /** ec.drag.move : débute le drag **/	
	   
	    if(e.type=='mousedown') {
			var oSource = $(Event.element(e));
			var oCible = ((oSource.$cible!=null) ? $(oSource.$cible) : oSource);

			if(oSource.$draggable && !oSource.$isDragDrop && oSource.$actionEvent=='DRAG') {
			    var oPos = Position.positionedOffset(oCible);
				var oriX = oPos[0];	   
				var oriY = oPos[1];		   
			    var difX = e.clientX - oriX;
				var difY = e.clientY - oriY;  	
				
				oSource.$isDragDrop = true; 	
				if(oSource.$isGhost) { 	
				    var hStyle = $H(oSource.$dragStyle);
					if(hStyle.toQueryString()!='') {
						var oGhost = ec.gdi.ghost(oCible);	
						oGhost.setStyle(oSource.$dragStyle); 
					} else {
					    var oGhost = $(oCible.cloneNode(true)); 
						oGhost.setStyle({left: oriX+'px'});	
				    	oGhost.setStyle({top: oriY+'px'}); 
						oGhost.setAttribute('id', oCible.getAttribute('id')+'ECCloneDrag'); 
				        new ec.gdi.opacity(oGhost, {taux:parseInt(oSource.$dragOpacity,10)});
					}	
					if(oSource.$dragFlicker){  	
					    ec.gdi.flicker(oGhost, oSource.$dragFlicker);
					}
				} else {   
				  	var oGhost = oSource;	
				    new ec.gdi.opacity(oGhost, {taux:0}); 
				} 
				oGhost.$draggable = false; 			
				oGhost.setStyle({zIndex: ec.base.zIndex(), position: 'absolute'});			 
			
				oGhost._dragMove = function(e) {  /** drag en cours, positionnne l'objet drag **/
					Event.stop(e);	
					if(oSource.$isDragVertical && oSource.$isDragHorizontal) {
				    	oGhost.setStyle({left:(e.clientX-difX)+'px', top:(e.clientY-difY)+'px'});	
					}
					else if(oSource.$isDragVertical) {
						oGhost.setStyle({top:(e.clientY-difY)+'px'});	
					}
					else if(oSource.$isDragHorizontal) {
						oGhost.setStyle({left:(e.clientX-difX)+'px'});
					}
					if(oSource.$isDragHide && oSource.visible()) {
				    	oCible.hide();
					}
				}	  
				
				oGhost._endDrag = function(e) {  /** fin du drag (mouseup) **/
					Event.stop(e);	
					Event.stopObserving(document, 'mousemove', oGhost._dragMove, false);
					Event.stopObserving(document, 'mouseup', oGhost._endDrag, false);	 
					oGhost.$isDragDrop = false; 
					if(oSource.$isDragBack) {
					    ec.gdi.moveBy(oGhost, {x:oriX, y:oriY, afterEnd: oGhost._endMove});
					} else { 	
					    if(oSource.$isMoveEndDrag) { 	
					        oCible.setStyle({left:(e.clientX-difX)+'px', top:(e.clientY-difY)+'px'});	
						} 
					    oGhost._endMove();
					}
				}	
				
				oGhost._endMove = function() {  /** fin du move sur l'objet ghost (en cas de move), ou fin du drag sans move **/
					oSource.$isDragDrop = false;	
					if(oSource.$isDragHide) {
				        oCible.show();
					} 	
					if(oGhost.$handlerFlicker) {
					    new ec.gdi.stopFlicker(oGhost.$handlerFlicker);
					}	 
					if(oSource.$isGhost) {
					    oGhost.remove(oGhost); 		
					}
					if(oSource.$afterDrag) { oSource.$afterDrag(); }
				}
				
				oCible.setStyle({zIndex: ec.base.zIndex()});
				if(oSource.$beforeDrag) { oSource.$beforeDrag(); }  
				Event.observe(document, 'mousemove', oGhost._dragMove, false);
				Event.observe(document, 'mouseup', oGhost._endDrag, false);  
				if(oSource.$isGhost) {
				   oCible.parentNode.appendChild(oGhost);	  
				}
				Event.stop(e);
			} 
		} 		   
	}  /** fin : ec.drag.move	**/
}; /** fin : ec.drag  **/

ec.resizes = {	/** ec.resizes : espace de nom pour le resizes	 **/	
	
	resizable : function(oSource, tP) {  /** ec.resizes.resizable : rend l'object cible 'resizable' **/	 		 
	    oSource = $(oSource); 
	    oSource.$resizes = true;	
	    oSource.$resizesEncours = false;
	    oSource.$cible = isEmpty(tP.cible) ? oSource.getAttribute('id') : $(tP.cible).getAttribute('id');    
	    oSource.$actionEvent = 'RESIZES';
	    oSource.$minWidth = isEmpty(tP.minWidth) ? 1 : parseInt(tP.minWidth, 10);  // largeur de redimensionnement minimal de l'object	
	    oSource.$minHeight = isEmpty(tP.minHeight) ? 1 : parseInt(tP.minHeight, 10);  // hauteur de redimensionnement minimal de l'object	
	    oSource.$maxWidth = isEmpty(tP.maxWidth) ? 10000 : parseInt(tP.maxWidth, 10);  // largeur de redimensionnement maximal de l'object	
	    oSource.$maxHeight = isEmpty(tP.maxHeight) ? 10000 : parseInt(tP.maxHeight, 10);  // hauteur de redimensionnement maximal de l'object	
		oSource.$beforeResizes = tP.beforeResizes || null;  // fonction a exécuter avant de commencer le redimensionnement 	
		oSource.$afterResizes = tP.afterResizes || null;  // fonction a exécuter après la fin du redimensionnement		 
		oSource.$duringResizes = tP.duringResizes || null;  // fonction a exécuter pendant le redimensionnement		 
		oSource.$isResizesVertical = isEmpty(tP.vertical) ? true : tP.vertical;  // autorise le redimensionnement vertical  
		oSource.$isResizesHorizontal = isEmpty(tP.horizontal) ? true : tP.horizontal;  // autorise le redimensionnement horizontal 	  
		   
	},  /** fin : ec.resizes.resizable	**/
	
    sizes : function(e) {  /** ec.resizes.sizes : débute le redimentionnement **/	
        
	    if(e.type=='mousedown') {
			var oSource = $(Event.element(e));
		    var oCible = $(oSource.$cible);
		    
			if(oSource.$resizes && !oSource.$resizesEncours && oSource.$actionEvent=='RESIZES') {	 	
			    var oPos = Position.positionedOffset(oCible);
				var oriX = oPos[0];	   
				var oriY = oPos[1];	
				var newWidth = oriX;	
				var newH = oriY;	   
                
				oSource.$resizesEncours = true; 	
				oSource._moveResizes = function(e) {  /** redimensionnement en cours **/
					Event.stop(e);	
					if(Event.isLeftClick(e)) {
					    newWidth = e.clientX-oriX;
					    newWidth = (newWidth<oSource.$minWidth ? oSource.$minWidth : (newWidth>oSource.$maxWidth ? oSource.$maxWidth : newWidth));
					    newHeight = e.clientY-oriY;
					    newHeight = (newHeight<oSource.$minHeight ? oSource.$minHeight : (newHeight>oSource.$maxHeight ? oSource.$maxHeight : newHeight));	 
						//ec.debug.print2('- e.clientX='+e.clientX+' - oriX='+oriX+' - newWidth='+newWidth+' - oSource.$minWidth='+oSource.$minWidth+'\r', '0', '0', '150', '30');
					    if(oSource.$isResizesVertical&&oSource.$isResizesHorizontal) {
				    	    oCible.setStyle({width:newWidth+'px', height:newHeight+'px'});	
					    } 
					    else if(oSource.$isResizesVertical) {
						    oCible.setStyle({height:newHeight+'px'});	
					    } 
					    else if(oSource.$isResizesHorizontal) {
						    oCible.setStyle({width:newWidth+'px'});
					    } 
					    if(oSource.$duringResizes) { oSource.$duringResizes(); }  
					}
				}	  
				
				oSource._endResizes = function(e) {  /** fin du redimensionnement (mouseup) **/
					Event.stop(e);	
					Event.stopObserving(document, 'mousemove', oSource._moveResizes, false);
					Event.stopObserving(document, 'mouseup', oSource._endResizes, false);	 
					oSource.$resizesEncours = false; 
					if(oSource.$afterResizes) { oSource.$afterResizes(); }
				}	
				
				oCible.setStyle({zIndex: ec.base.zIndex()});
				if(oSource.$beforeResizes) { oSource.$beforeResizes(); }  
				Event.observe(document, 'mousemove', oSource._moveResizes, false);
				Event.observe(document, 'mouseup', oSource._endResizes, false);  
				Event.stop(e);
			} 
		} 		   
	}  /** fin : ec.resizes.sizes	**/
}; /** fin : ec.resizes  **/

ec.json = {	/** ec.json : espace de nom pour json	 **/	
    
    sort : function(oJSon, tP) { /** ec.json.sort : effecture un trie dans un tableau de json sur un champ donné, retourne un tableau d'object json **/	 		
        var nomChamp = isEmpty(tP.champ) ? '' : tP.champ;	//  nom du champ de recherche (paramètre obligatoire)
        var bAsc = isEmpty(tP.sens) ? true : (tP.sens.toUpperCase()=='ASC') ? true : (tP.sens.toUpperCase()=='DESC') ? false : true;	//  sens du trie, ASC par defaut ( 'ASC' ou 'DESC' )
		var convert = isEmpty(tP.convert) ? 'ec.json.fV' : tP.convert;
		var type = isEmpty(tP.type) ? null : tP.type;	 
		var oData = oJSon;
        var a = $A(); 
		var b = $A();  	
        
        if(Array.isArray(oData) && nomChamp!='') {
            if(oData.length>0) {
                var valeur = 0;
                var nb = 0, idx = 0, idxT = 0, nb2 = 0; 
				nb = oData.length;
				for(var i=0; i<nb; i++) {  
					if(type==null) {  
						b[i] = eval(convert + '(oData[i][nomChamp])');
					} else {	
						b[i] = ec.json.convert(oData[i][nomChamp], type, false);
					}
	            } 		
	            nb2 = b.length;	 
                for(var j=0; j<nb2; j++) {  
                    valeur = b[0];
                    nb = b.length;	  
                    idx = 0;		 
                    for(var i=0; i<nb; i++) {  
						if(bAsc){
	                        if(b[i] <= valeur) {
	                            valeur = b[i]; 
	                            idx = i;
	                        } 	
						} else {
							if(b[i] >= valeur) {
	                            valeur = b[i]; 
	                            idx = i;
	                        } 	
						}
                    }
                    a[idxT] = oData[idx]; 
                    idxT++;	  	  
					oData.splice(idx, 1);
                    b.splice(idx, 1);
                }
            }
        }
        
        return a;
        
    }, /** fin : ec.json.sort	**/	 
	
find : function(oJSon, tP) {  /** ec.json.find : effecture une recherche dans un tableau de json sur un champ donné, retourne un tableau d'object json **/	 		
	    var idx = 0;
        var idxT = 0;
        var a = $A();    
        var sRequete = ''; 
          
        if(oJSon!=null) {  
	        if(Array.isArray(tP)) {
	            for(var i=0; i<tP.length; i++) {
	                if(Number.isPair(i))  { // requete
	                    sRequete += ec.json.requete(tP[i]);
	                } else { // opérateur booléan entre requete
 	                    sRequete += ' ' + tP[i].operateur + ' ';
	                }
	            }
	        } else {
	            sRequete = ec.json.requete(tP);
	        }
	        //alert(sRequete);
            while (oJSon[idx]!=null) {
                if(eval(sRequete)) {
                    a[idxT] = oJSon[idx];
                    idxT++;
                }
                idx++;
            }
        }
        
        return a;

    },  /** fin : ec.json.find	**/
    
    fV : function(x) { /** ec.json.fV : fonction vide	 **/	
        return x;
    },  /** fin : ec.json.fV	**/
    
    convert : function(x, type, bUpper) { /** ec.json.convert : converti en integer, float ou string **/	
        var xRet = null;
 
        if(x!=null) {
            switch(type) {
                case 'INTEGER':
                    xRet = parseInt(x, 10);
                    break;
                case 'INT':
                    xRet = parseInt(x, 10);
                    break;
                case 'FLOAT':
                    xRet = parseFloat(x.toString().replace(/,/g, "."));
                    break; 
                case 'STRING':
                    xRet = x.toString();
                    xRet = bUpper ? x.toUpperCase() : x;
                    break; 
			    case 'DATE':
                    xRet = Date.parse(Date.USString(x.toString()));
                    break;
			    case 'DATETIME':
                    xRet = Date.parse(Date.USString(x.toString()));
                    break;
                default:
                    xRet = x.toString();
                    xRet = bUpper ? x.toUpperCase() : x;
                    break;
            }
        }
        
        return xRet;
    },  /** fin : ec.json.convert	**/
    
    requete : function(tP) {  /** ec.json.requete : effectue une recherche dans un tableau de json sur un champ donné, retourne un tableau d'object json **/	 		
	    var separateur = isEmpty(tP.separateur) ? ';' : tP.separateur; //  separateur pour la fonction split
	    var nomChamp = isEmpty(tP.champ) ? '' : tP.champ;	//  nom du champ de recherche (paramètre obligatoire)
		var textRecherche = isEmpty(tP.text) ? new Array() : tP.text.toString().split(separateur);	//  tableau de texte a rechercher (paramètre obligatoire) 
		var bUpper = isEmpty(tP.bcase) ? true : tP.bcase; // tien compte de la case pour la recherche du texte (attention: ne concerne pas le nom du champ) (true/false)
        var bOperation = isEmpty(tP.operation) ? '==' : tP.operation; // opérateur de comparaison
        var bLike = (bOperation.toUpperCase()=='LIKE') ? true : false; // indexOf != -1
        var sType = isEmpty(tP.type) ? 'STRING' : tP.type.toUpperCase(); // type de la donnée (STRING, INTEGER, FLOAT)
        var bNotLike = (bOperation.toUpperCase()=='NOT LIKE') ? true : false; // indexOf == -1
        var fFonction = isEmpty(tP.fonction) ? 'ec.json.fV' : tP.fonction; // fonction de traitement de la donnée avant comparaison
        var sLikeTest = (bOperation.toUpperCase()=='LIKE') ? '!=-1' : (bOperation.toUpperCase()=='NOT LIKE') ? '==-1' : '';   
        var sRequete = '';
        
        if(bLike || bNotLike) {
            for(var i=0; i<textRecherche.length; i++) {
                sRequete += "(ec.json.convert(" + fFonction + "(oJSon[idx]['" + nomChamp + "']), '" + sType + "'," + bUpper + ")" + ".indexOf(ec.json.convert(\"" + textRecherche[i] + "\", '" + sType + "'," + bUpper + "))" + sLikeTest + ")";  
                sRequete += (i!=textRecherche.length-1) ? (bNotLike ? "&&" : "||") : "";
            }
        } else {
            for(var i=0; i<textRecherche.length; i++) {
                sRequete += "(ec.json.convert(" + fFonction + "(oJSon[idx]['" + nomChamp + "']), '" + sType + "'," + bUpper + ")" + bOperation + "ec.json.convert(\"" + textRecherche[i] + "\", '" + sType + "'," + bUpper + "))";  
                sRequete += (i!=textRecherche.length-1) ? (bOperation=='!=' ? "&&" : "||") : "";
            }
        }
        return sRequete;
    }, /** fin : ec.json.requete	**/	

	sortCol : function(oJSon, tP) { /** ec.json.sortCol : (fonction propre à la structure V2 (SCHEMA et DATA)) retourne un tableau représentant l'index des colonnes d'un tableau json trié sur la valeur d'un champ donné **/	 		
        var nomChamp = isEmpty(tP.champ) ? '' : tP.champ;	//  nom du champ de recherche (paramètre obligatoire)   
		var condition = isEmpty(tP.condition) ? 'true' : tP.condition;	//  filtre, condition à appliquer    
		var bAsc = isEmpty(tP.sens) ? true : (tP.sens.toUpperCase()=='ASC') ? true : (tP.sens.toUpperCase()=='DESC') ? false : true;	//  sens du trie, ASC par defaut ( 'ASC' ou 'DESC' ) 
        var tRes = new Array();

        if(Array.isArray(oJSon) && nomChamp!='') {
            if(oJSon.length>0) {  
				var nb = oJSon.length;	 
                var valeur = 0;
                var idxDel = 0;	
				var idx = 0;
				var tTemp1 = new Array(); 
				
				for(var i=0; i<nb; i++) {   
					if(eval(condition)) {  
						tTemp1.push(i);
					} 
				}	 		
				nb = tTemp1.length;	 
				while(nb>0) { 
					valeur = oJSon[tTemp1[0]][nomChamp];	
					idx = tTemp1[0];	
                    idxDel = 0;  
					for(var i=0; i<nb; i++) {  
						if(eval('oJSon[tTemp1[i]][nomChamp]' + ((bAsc) ? '<=' : '>=') + 'valeur')) {
                            valeur = oJSon[tTemp1[i]][nomChamp]; 
							idx = tTemp1[i];
                            idxDel = i;	  
                        }
					} 
					tRes.push(idx);
                    tTemp1.splice(idxDel, 1); 
					nb = tTemp1.length;	  
				}
            }
        }
        
        return tRes;
        
    }, /** fin : ec.json.sort	**/	

    idxCol : function(oJSon, tP) { /** ec.json.idxCol : (fonction propre à la structure V2 (SCHEMA et DATA)) retourne l'index de la colonne par rapport au nom du champ **/	 		
        var champ = isEmpty(tP.champ) ? '' : tP.champ;	//  nom du champ
        
        return ec.json.find(oJSon[0], {champ:'NOM', text:champ})[0].INDEX;
    } /** fin : ec.json.idxCol	**/	

}; /** fin : ec.json  **/	 
	
ec.ctrl = {	/** ec.ctrl : espace de nom pour le controle	 **/	
	
	elementClick : function(e) {
        var oCible;
        
        if (!e) {
            var e=window.event;
        }
        if (e.target) {
          oCible=e.target;
        } else if (e.srcElement) {
          oCible=e.srcElement;
        } 
        if (oCible.nodeType==3) { // bug Safari 
          oCible = oCible.parentNode;
        }
        
        return oCible;
    },

	window : function(tP) {  /** ec.ctrl.window : fenetre redimentionnable **/	 
	    var oCible = isEmpty(tP.cible) ? document.body : $(tP.cible);
	    var oCss = isEmpty(tP.css) ? null : tP.css;
        var top = isEmpty(tP.top) ? null : tP.top;
        var left = isEmpty(tP.left) ? null : tP.left;
        var width = isEmpty(tP.width) ? '100px' : tP.width;
        var height = isEmpty(tP.height) ? '100px' : tP.height;
        var minWidth = isEmpty(tP.minWidth) ? 10 : parseInt(tP.minWidth, 10);
        var minHeight = isEmpty(tP.minHeight) ? 10 : parseInt(tP.minHeight, 10);
        var maxWidth = isEmpty(tP.maxWidth) ? 10000 : parseInt(tP.maxWidth, 10);
        var maxHeight = isEmpty(tP.maxHeight) ? 10000 : parseInt(tP.maxHeight, 10);
        var dragOpacity = isEmpty(tP.dragOpacity) ? 100 : tP.dragOpacity;
        var idTable1 = ec.base.idObject({racine: 'TAB'});
        var idCadre = ec.base.idObject({racine: 'DATA'});
        var idCaption = ec.base.idObject({racine: 'CAP'});
        var idBarreEtat = ec.base.idObject({racine: 'CAP'});
        var idCentre = ec.base.idObject({racine: 'CENTRE'});
        var idRedimensionne = ec.base.idObject({racine: 'REDIM'});
        var iHauteurCaption = 25;
        var iHauteurEtat = 20;
        
        // cadre conteneur
        var oCadre = ec.base.setProperty($(document.createElement('div')), 
			{className:oCss.cadreExterne, id:idCadre},
			{top:top, left:left, width:width, height:height, position:'absolute', zIndex: ec.base.zIndex()}
		);
        
        // table du caption et du contenu
        var oRow = null;
        var oTable1 = ec.base.setProperty($(document.createElement('table')), 
			{className:oCss.barreCaption, id:idTable1, border:'0', cellPadding:'0', cellSpacing:'0'});
        if(Prototype.Browser.IE)
        {
            oTable1.setStyle({height:(parseInt(height, 10)-(iHauteurCaption+iHauteurEtat))+'px'});
        }
        
        oRow = oTable1.insertRow(0);
        ec.base.setProperty(oRow.insertCell(0), {className:'hg'});
        ec.base.setProperty(oRow.insertCell(1), {className:'hc', innerHTML:'&nbsp;', id:idCaption});
        ec.base.setProperty(oRow.insertCell(2), {className:'hd'});
        
        oRow = oTable1.insertRow(1);
        ec.base.setProperty(oRow.insertCell(0), {className:'cg'});
        ec.base.setProperty(oRow.insertCell(1), {className:'cc', innerHTML:'&nbsp;', id:idCentre, align:'left', valign:'top'});
        ec.base.setProperty(oRow.insertCell(2), {className:'cd'});

        // table de la bare d'état du bas
        var oTable2 = ec.base.setProperty($(document.createElement('table')), {className:oCss.barreEtat, border:'0', cellPadding:'0', cellSpacing:'0'});
        
        oRow = oTable2.insertRow(0);
        ec.base.setProperty(oRow.insertCell(0), {className:'bg'});
        ec.base.setProperty(oRow.insertCell(1), {className:'bc', innerHTML:'&nbsp;', id:idBarreEtat, align:'left', valign:'top'});
        ec.base.setProperty(oRow.insertCell(2), {className:'bd', id:idRedimensionne});
        
        // table conteneur 
        var oTableCont = ec.base.setProperty($(document.createElement('table')), {className:oCss.cadreInterne, border:'0', cellPadding:'0', cellSpacing:'0'});
        
        oRow = oTableCont.insertRow(0);
        ec.base.setProperty(oRow.insertCell(0), {className:'haut', align:'left', valign:'top'});
        oRow = oTableCont.insertRow(1);
        ec.base.setProperty(oRow.insertCell(0), {className:'bas', align:'left', valign:'top'});
        
        oTableCont.rows[0].cells[0].appendChild(oTable1);
        oTableCont.rows[1].cells[0].appendChild(oTable2);
        
        oCadre.appendChild(oTableCont); 
        oCible.appendChild(oCadre); 
         
        new ec.drag.draggable(idCaption, {
            hide:true, 
            ghost:true, 
            back:false, 
            move_end_drag:true, 
            opacity:70, 
            cible: idCadre, 
            afterDrag:function() {
                //$(idCadre).setStyle({zIndex: ec.base.zIndex()});
            }
        }); 
        
        new ec.drag.draggable(idBarreEtat, {
            hide:true, 
            ghost:true, 
            back:false, 
            move_end_drag:true, 
            opacity:dragOpacity, 
            cible: idCadre, 
            afterDrag:function() {
                //$(idCadre).setStyle({zIndex: ec.base.zIndex()});
            }
        }); 
        
        new ec.resizes.resizable(idRedimensionne, {
            cible: idCadre, 
            minWidth: minWidth,
            minHeight: minHeight, 
            maxWidth: maxWidth,
            maxHeight: maxHeight, 
            duringResizes:function() {
               if(Prototype.Browser.IE)
               {
                    var oPoint = ec.gdi.getPoint($(idCadre));
                    var height = oPoint.height-(iHauteurCaption+iHauteurEtat)
                    if(!isNaN(height) && height>0)
                    {
                        $(idTable1).setStyle({height:height+'px'});
                    }
            	}
            }
        }); 
        
        Event.observe(document.body, 'mousedown', ec.drag.move.bindAsEventListener(ec.drag));
        Event.observe(document.body, 'mousedown', ec.resizes.sizes.bindAsEventListener(ec.resizes));
    
        return {cadre:idCadre, caption:idCaption, centre:idCentre, etat:idBarreEtat};
	
	},  /** fin : ec.ctrl.window	**/
	
	createTableau : function(tP) { /** ec.ctrl.createTableau : création d'une table **/	 		
        var oCible = isEmpty(tP.cible) ? document.body : $(tP.cible);	
		var oCss = isEmpty(tP.css) ? null : tP.css;	 // class des styles
		var oDim = isEmpty(tP.dim) ? null : tP.dim;
		var tCol = isEmpty(tP.tCol) ? null : tP.tCol;  // colonnes triées
		var nbLignAff = isEmpty(tP.affLigne) ? null : tP.affLigne; // nombre de lignes a afficher
		var idxLigneDep = isEmpty(tP.idxLigne) ? 0 : tP.idxLigne;
		var affTitreCol = isEmpty(tP.affTitreCol) ? false : tP.affTitreCol; // affiche les titres des colonnes
		var idxTrie = isEmpty(tP.idxTrie) ? null : tP.idxTrie;	// index des données a afficher
		var ascTrie = isEmpty(tP.ascTrie) ? null : tP.ascTrie;	// sens du trie
		var autoWidth = isEmpty(tP.autoWidth) ? false : tP.autoWidth;  
		var cmptLigne = isEmpty(tP.cmptLigne) ? false : tP.cmptLigne; // complète par des lignes vides si pas assez de données 
		var fonctionTrieAff = isEmpty(tP.trieAff) ? null : tP.trieAff;  // fonction de trie
		var fonctionClick = isEmpty(tP.clickLigne) ? null : tP.clickLigne;  // fonction de à déclencher sur le click sur une ligne
		var fonctionMouseOver = isEmpty(tP.mouseoverLigne) ? null : tP.mouseoverLigne;  // fonction de à déclencher sur le passage de la souris sur une ligne
		var fonctionMouseOut = isEmpty(tP.mouseoutLigne) ? null : tP.mouseoutLigne;  // fonction de à déclencher quant la souris sort d'une ligne
		var idxClick = isEmpty(tP.idxClick) ? null : tP.idxClick;	// index de la ligne cliquée
        var oJSon = tP.data;

		var oSchema = oJSon.SCHEMA[0];
		var oData = oJSon.DATA[0];
		var nbLignTot = oData.length;	 
		var nbCol = 0;	 
		var iDivWidth = 0; 	
		var oRet = null;
		var oRow = null;   
		var bFlag1 = false;
			
		oCible.update('');	
		nbLignAff = ((nbLignAff==null) ? nbLignTot : idxLigneDep+nbLignAff);
	  		   
		var oDivCont = new Element('div', {'class':oCss.DivCont}); 
		oCible.appendChild(oDivCont);	
		var oDivTitre = new Element('div', {'class':oCss.DivData});		
		oDivCont.appendChild(oDivTitre);	
		var oDivData = new Element('div', {'class':oCss.DivData});	 
		oDivCont.appendChild(oDivData);
        if(oSchema.length>0) {			 
			if(!Object.isArray(tCol)) {
				tCol = ec.json.sortCol(oJSon.SCHEMA[0], {champ:'ORDRE', sens:'ASC', condition:'oJSon[i].VISIBLE'});	
			}
			var nbCol = tCol.length;	
			var oTabTitre = new Element('table', {'class':oCss.TabTitre, cellPadding:'0', cellSpacing:'0', id:ec.base.idObject()}); 
			var oCelTitre = null;
			oDivTitre.appendChild(oTabTitre);
			oTabTitre.setStyle({width:'100%'});  	
			oRow = oTabTitre.insertRow(0);
			bFlag1 = false;
			for(var i=0; i<nbCol; i++) {  	   
				if(affTitreCol && !bFlag1) {
					ec.base.setProperty(oRow.insertCell(0), 
						{noWrap:true, align:'center', vAlign:'middle', className:'cell'},
						{width:'25px'}	
					); 
					iDivWidth += 20;  
					bFlag1 = true;
				} 	
			    if(idxTrie!=null && oSchema[tCol[i]].INDEX==idxTrie) {	
				    oCelTitre = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
					    {noWrap:false, align:'center', vAlign:'middle', className:(ascTrie ? 'cellAsc' : 'cellDesc'), innerHTML:oSchema[tCol[i]].LABEL},
					    {width:(((i+1)==nbCol) ? 'auto' : oSchema[tCol[i]].WIDTH+'px')},
					    {idxTrie:oSchema[tCol[i]].INDEX, tag:(ascTrie ? 'ASC' : 'DESC')}
				    ); 	
			    } else {
				    oCelTitre = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
					    {noWrap:false, align:'center', vAlign:'middle', className:'cell', innerHTML:oSchema[tCol[i]].LABEL},
					    {width:(((i+1)==nbCol) ? 'auto' : oSchema[tCol[i]].WIDTH+'px')},
					    {idxTrie:oSchema[tCol[i]].INDEX, tag:''}
				    ); 	
			    }
			    iDivWidth += (oSchema[tCol[i]].WIDTH+10); 
			    
			    Event.observe(oCelTitre, 'click', function(event) {	 
				    if(fonctionTrieAff) { fonctionTrieAff(Event.element(event)); } 	
			    });
			}	

			if(nbLignTot>0) {				  
				var oTabData = new Element('table', {'class':oCss.TabData, cellPadding:'0', cellSpacing:'0', id:ec.base.idObject()}); 
				var sdata = '';
				var iLimitCmpt = 0;
				var bComplete = false;
				var bPair = false;
				var oCell = null;
				
				nbLignAff = (oData.length<nbLignAff && !cmptLigne) ? oData.length : nbLignAff;
				bComplete = (nbLignAff && oData.length<nbLignAff) ? true : false;
				iLimitCmpt = (bComplete) ? oData.length : nbLignAff;
				oDivData.appendChild(oTabData);
				oTabData.setStyle({width:'100%'});  
				for(var j=0; j<(nbLignAff-idxLigneDep); j++) { 
				    oRow = oTabData.insertRow(j);
				    
				    if(fonctionClick) {
				        Event.observe(oRow, 'click', function(event) {	 
				            fonctionClick(Event.element(event));
			            });
			        }
			        
			        if(fonctionMouseOver) {
				        Event.observe(oRow, 'mouseover', function(event) {	 
				            fonctionMouseOver(Event.element(event));
			            });
			        }
			        
			        if(fonctionMouseOut) {
				        Event.observe(oRow, 'mouseout', function(event) {	
				            fonctionMouseOut(Event.element(event));
			            });
			        }
			        
					bFlag1 = false;
					for(var i=0; i<nbCol; i++) {  
				        sdata = '';
					    if(affTitreCol && !bFlag1) { 
						    oCell = ec.base.setProperty(oRow.insertCell(0), 
							    {noWrap:true, align:'center', vAlign:'middle', className:'cellT', innerHTML:(idxLigneDep+j+1), id:(idxLigneDep+j)},
							    {width:'25px'},
							    {select:'0'}	
						    );
						    bFlag1 = true; 
					    } 
					    if(j<iLimitCmpt) {
					        sdata = (oSchema[tCol[i]].NBCHAR!=null) ? String.left(oData[idxLigneDep+j][tCol[i]], oSchema[tCol[i]].NBCHAR) : oData[idxLigneDep+j][tCol[i]];
					        if(oSchema[tCol[i]].NBCHARSP!=null) {
					            sdata = (oData[idxLigneDep+j][tCol[i]].indexOf(' ')>oSchema[tCol[i]].NBCHARSP || oData[idxLigneDep+j][tCol[i]].indexOf(' ')==-1) ? String.left(oData[idxLigneDep+j][tCol[i]], oSchema[tCol[i]].NBCHARSP) : oData[idxLigneDep+j][tCol[i]];
					        }
					        if(oSchema[tCol[i]].NBSPCHAR!=null) {
					            var k=0;
					            var nbCar = oData[idxLigneDep+j][tCol[i]].length;
					            var idxSP = -1;
					            sdata = oData[idxLigneDep+j][tCol[i]];
					            while (k<nbCar) {
					                idxSP = oData[idxLigneDep+j][tCol[i]].substring(k, oSchema[tCol[i]].NBSPCHAR).lastIndexOf(' ');
					                if(idxSP==-1) {
					                    sdata = String.insere(sdata, ' ', k+oSchema[tCol[i]].NBSPCHAR);
					                    k += oSchema[tCol[i]].NBSPCHAR;
					                } else {
					                    k += (idxSP+1);
					                }
					            }
					        }
					    }
					    if(idxClick==(idxLigneDep+j)) {
					         var oCell = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
						        {noWrap:false, align:'center', innerHTML:sdata, className:'cellSS'}, 
						        {}
					        ); 
					        oCell.setStyle({width: oSchema[tCol[i]].WIDTH+'px'});  
					    } else {
					        var oCell = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
						        {noWrap:false, align:'center', innerHTML:sdata, className:(bPair ? 'cell1' :'cell2')}, 
						        {width:oSchema[tCol[i]].WIDTH+'px'}
					        ); 
					        oCell.setStyle({width: oSchema[tCol[i]].WIDTH+'px'});  
					    }
					}
					bPair = !bPair;	
				}
				if(autoWidth) { 
				    for(var i=0; i<nbCol+1; i++) { 
				        oTabTitre.rows[0].cells[i].setStyle({width: oTabData.rows[0].cells[i].getWidth()+'px'});  
				    }
				}
			}	
			oDivTitre.setStyle({width: iDivWidth+'px'});  
			oDivData.setStyle({width: iDivWidth+'px'});  
			oDivCont.setStyle({width: iDivWidth+'px'});  
		}
			   
		ec.base.setProperty(oDivCont, {}, {}, {tCol:tCol, idxTrie:idxTrie, ascTrie:ascTrie})	
					
        return {divCont:oDivCont, divTitre:oDivTitre, data:oDivData, tabTitre:oTabTitre, tabData:oTabData};
    }, /** fin : ec.ctrl.createTableau	**/
    
    createTableau2 : function(tP) { /** ec.ctrl.createTableau2 : création d'une table **/	 		
        var oCible = isEmpty(tP.cible) ? document.body : $(tP.cible);	
		var oCss = isEmpty(tP.css) ? null : tP.css;	 // class des styles
		var oDim = isEmpty(tP.dim) ? null : tP.dim;
		var tCol = isEmpty(tP.tCol) ? null : tP.tCol;  // colonnes triées
		var nbLignAff = isEmpty(tP.affLigne) ? null : tP.affLigne; // nombre de lignes a afficher
		var idxLigneDep = isEmpty(tP.idxLigne) ? 0 : tP.idxLigne;
		var affTitreCol = isEmpty(tP.affTitreCol) ? false : tP.affTitreCol; // affiche les titres des colonnes
		var idxTrie = isEmpty(tP.idxTrie) ? null : tP.idxTrie;	// index des données a afficher
		var ascTrie = isEmpty(tP.ascTrie) ? null : tP.ascTrie;	// sens du trie
		var autoWidth = isEmpty(tP.autoWidth) ? false : tP.autoWidth;  
		var cmptLigne = isEmpty(tP.cmptLigne) ? false : tP.cmptLigne; // complète par des lignes vides si pas assez de données 
		var fonctionTrieAff = isEmpty(tP.trieAff) ? null : tP.trieAff;  // fonction de trie
		var fonctionClick = isEmpty(tP.clickLigne) ? null : tP.clickLigne;  // fonction de à déclencher sur le click sur une ligne
		var fonctionMouseOver = isEmpty(tP.mouseoverLigne) ? null : tP.mouseoverLigne;  // fonction à déclencher sur le passage de la souris sur une ligne
		var fonctionMouseOut = isEmpty(tP.mouseoutLigne) ? null : tP.mouseoutLigne;  // fonction à déclencher quant la souris sort d'une ligne
		var idxClick = isEmpty(tP.idxClick) ? null : tP.idxClick;	// index de la ligne cliquée
		var bSelectLigne = isEmpty(tP.selectLigne) ? false : tP.selectLigne;	// force la sélection de la ligne à la création
        var oJSon = tP.data;

		var oSchema = oJSon.SCHEMA[0];
		var oData = oJSon.DATA[0];
		var nbLignTot = oData.length;	 
		var nbCol = 0;	 
		var iDivWidth = 0; 	
		var oRet = null;
		var oRow = null;   
		var bFlag1 = false;
			
		oCible.update('');	
		nbLignAff = ((nbLignAff==null) ? nbLignTot : idxLigneDep+nbLignAff);
	  		   
		var oDivCont = new Element('div', {'class':oCss.DivCont}); 
		oCible.appendChild(oDivCont);	
        if(oSchema.length>0) {			 
			if(!Object.isArray(tCol)) {
				tCol = ec.json.sortCol(oJSon.SCHEMA[0], {champ:'ORDRE', sens:'ASC', condition:'oJSon[i].VISIBLE'});	
			}
			var nbCol = tCol.length;	
			var oTable = new Element('table', {'class':oCss.TabGen, cellPadding:'0', cellSpacing:'0', id:ec.base.idObject()}); 
			var oCelTitre = null;
			oDivCont.appendChild(oTable);
			oTable.setStyle({width:'100%'});  	
			
            // data
			if(nbLignTot>0) {				  
				var sdata = '', sdataTmp = '';
				var iLimitCmpt = 0;
				var bComplete = false;
				var bPair = false;
				var oCell = null;
				
				nbLignAff = (oData.length<nbLignAff && !cmptLigne) ? oData.length : nbLignAff;
				bComplete = (nbLignAff && oData.length<nbLignAff) ? true : false;
				iLimitCmpt = (bComplete) ? oData.length : nbLignAff; 
				for(var j=0; j<(nbLignAff-idxLigneDep); j++) { 
				    oRow = oTable.insertRow(j);
				    
				    if(fonctionClick) {
				        Event.observe(oRow, 'click', function(event) {	 
				            fonctionClick(Event.element(event));
			            });
			        }
			        
			        if(fonctionMouseOver) {
				        Event.observe(oRow, 'mouseover', function(event) {	 
				            fonctionMouseOver(Event.element(event));
			            });
			        }
			        
			        if(fonctionMouseOut) {
				        Event.observe(oRow, 'mouseout', function(event) {	
				            fonctionMouseOut(Event.element(event));
			            });
			        }
			        
					bFlag1 = false;
					for(var i=0; i<nbCol; i++) {  
				        sdata = '', sdataTmp = '';
					    if(affTitreCol && !bFlag1) { 
						    oCell = ec.base.setProperty(oRow.insertCell(0), 
							    {noWrap:true, align:'center', vAlign:'middle', className:'cellT', innerHTML:(idxLigneDep+j+1), id:(idxLigneDep+j)},
							    {width:'25px'},
							    {select:'0'}	
						    );
						    bFlag1 = true; 
					    } 
					    if(j<iLimitCmpt) {
					        if(oSchema[tCol[i]].CONCAT!=null) {
					            var tChamps = oSchema[tCol[i]].CONCAT.split(';'); 
					            if(tChamps.length>0) {
					                if(oSchema[tCol[i]].CONCATFORMAT!=null) {
					                    var sTempo = new String(oSchema[tCol[i]].CONCATFORMAT);
					                    for(var xx=0; xx<tChamps.length; xx++) {    
					                        sTempo = sTempo.replace(String.trim(tChamps[xx]), oData[idxLigneDep+j][ec.json.idxCol(oJSon.SCHEMA, {champ:String.trim(tChamps[xx])})]);
					                    }
					                    sdataTmp = eval(sTempo);
					                } else {
					                    for(var xx=0; xx<tChamps.length; xx++) {    
                                            sdataTmp += " " + oData[idxLigneDep+j][ec.json.idxCol(oJSon.SCHEMA, {champ:String.trim(tChamps[xx])})];
					                    }
					                }
					            } else {
					                sdataTmp = oData[idxLigneDep+j][tCol[i]];
					            }
					        } else {
					            sdataTmp = oData[idxLigneDep+j][tCol[i]];
					        }
					        sdata = (oSchema[tCol[i]].NBCHAR!=null) ? String.left(sdataTmp, oSchema[tCol[i]].NBCHAR) : sdataTmp;
					        if(oSchema[tCol[i]].NBCHARSP!=null) {
					            sdata = (sdataTmp.indexOf(' ')>oSchema[tCol[i]].NBCHARSP || sdataTmp.indexOf(' ')==-1) ? String.left(sdataTmp, oSchema[tCol[i]].NBCHARSP) : sdataTmp;
					        }
					        if(oSchema[tCol[i]].NBSPCHAR!=null) {
					            var k=0;
					            var nbCar = sdataTmp.length;
					            var idxSP = -1;
					            sdata = sdataTmp;
					            while (k<nbCar) {
					                idxSP = sdataTmp.substring(k, oSchema[tCol[i]].NBSPCHAR).lastIndexOf(' ');
					                if(idxSP==-1) {
					                    sdata = String.insere(sdata, ' ', k+oSchema[tCol[i]].NBSPCHAR);
					                    k += oSchema[tCol[i]].NBSPCHAR;
					                } else {
					                    k += (idxSP+1);
					                }
					            }
					        }
					    }
					    if(idxClick==(idxLigneDep+j)) {
					         var oCell = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
						        {noWrap:false, align:'center', innerHTML:sdata, className:'cellSS'}, 
						        {}
					        ); 
					        oCell.setStyle({width: oSchema[tCol[i]].WIDTH+'px'});  
					    } else {
					        var oCell = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
						        {noWrap:false, align:'center', innerHTML:sdata, className:(bPair ? 'cell1' :'cell2')}, 
						        {width:oSchema[tCol[i]].WIDTH+'px'}
					        ); 
					        oCell.setStyle({width: oSchema[tCol[i]].WIDTH+'px'});  
					    }
					}
					bPair = !bPair;	
				}
				if(autoWidth) { 
				    for(var i=0; i<nbCol+1; i++) { 
				        oTable.rows[0].cells[i].setStyle({width: oTable.rows[0].cells[i].getWidth()+'px'});  
				    }
				}
			}	
			
			// titre
			oRow = oTable.insertRow(0);
			bFlag1 = false;
			for(var i=0; i<nbCol; i++) {  	   
				if(affTitreCol && !bFlag1) {
					ec.base.setProperty(oRow.insertCell(0), 
						{noWrap:true, align:'center', vAlign:'middle', className:'cell'},
						{width:'25px'}	
					); 
					iDivWidth += 20;  
					bFlag1 = true;
				} 	
			    if(idxTrie!=null && oSchema[tCol[i]].INDEX==idxTrie) {	
				    oCelTitre = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
					    {noWrap:false, align:'center', vAlign:'middle', className:(ascTrie ? 'cellAsc' : 'cellDesc'), innerHTML:oSchema[tCol[i]].LABEL},
					    {width:(((i+1)==nbCol) ? 'auto' : oSchema[tCol[i]].WIDTH+'px')},
					    {idxTrie:oSchema[tCol[i]].INDEX, tag:(ascTrie ? 'ASC' : 'DESC')}
				    ); 	
			    } else {
				    oCelTitre = ec.base.setProperty(oRow.insertCell((affTitreCol ? i+1 : i)), 
					    {noWrap:false, align:'center', vAlign:'middle', className:'cell', innerHTML:oSchema[tCol[i]].LABEL},
					    {width:(((i+1)==nbCol) ? 'auto' : oSchema[tCol[i]].WIDTH+'px')},
					    {idxTrie:oSchema[tCol[i]].INDEX, tag:''}
				    ); 	
			    }
			    iDivWidth += (oSchema[tCol[i]].WIDTH+10); 
			    
			    Event.observe(oCelTitre, 'click', function(event) {	 
				    if(fonctionTrieAff) { fonctionTrieAff(Event.element(event)); } 	
			    });
			}	
			// ** //
			oTable.setStyle({width: iDivWidth+'px'});  
			oDivCont.setStyle({width: iDivWidth+'px'});  
		}
			   
		ec.base.setProperty(oDivCont, {}, {}, {tCol:tCol, idxTrie:idxTrie, ascTrie:ascTrie})	
	
		if(bSelectLigne && idxClick!=null && fonctionClick) {
		    fonctionClick(oTable.rows[1].cells[1]);
		}
						
        return {divCont:oDivCont, table:oTable};
    } /** fin : ec.ctrl.createTableau2	**/
}; /** fin : ec.ctrl  **/	
/****/


/** fonctions diverses utilitaires **/
/**/
function isEmpty(v) { 

   if(v===undefined || v===null || v==NaN) {
       return true;
    } else { 
	   return false;
	}	
}	

//
function valideDate(date)
{		
	var bRet = false;
	var datecut = date.split('/');
	    if ( datecut[0] > 31 || datecut[1] > 12 || datecut[2] < 1850 || datecut[2] > 3000 || date.length!=10){
	        bRet = false
	    }
	    else {
	        bRet = true
	    }
	
 	return bRet;
}	
//

/* Déclenche un évènement */
// ActivateEvent($('test'), 'click', 'MouseEvents');
// ActivateEvent($('test'), 'blur', 'HTMLEvents');
// 'KeyEvents' 'KeyboardEvent'
function ActivateEvent(target, eventName, typeEvent, keyCode) {
    if(document.dispatchEvent) 
    {
        if(target.dispatchEvent)
        {
            var oEvent = document.createEvent(typeEvent);
            if(!isEmpty(keyCode))
            {
                oEvent.initKeyEvent(eventName, true, true, window, false, false, false, false, 0, keyCode);
            } else {
                oEvent.initEvent(eventName, true, true);
            }
            target.dispatchEvent(oEvent);
        }
    }
    else
    {   
       if(document.fireEvent) 
       {   
           var oEvent = document.createEventObject();
           if(!isEmpty(keyCode))
           {
                oEvent.keyCode = keyCode;
           }
           target.fireEvent("on"+eventName, oEvent);      
       }
       else
       {
           eval(target+"."+eventName+"()");
       }
    }
}
/**/
function valideEmail(chaine)
{		
	var bRet = false;
	var regexp = /\w[\w\-\.]*@\w[\w\-\.]*\.[a-z]{2,}/i;		  
	
	if(chaine != "") 
  	{
    	if(regexp.test(chaine))                 
		{
      		bRet = true;
    	} 
	}
 	return bRet;
}	
/**/
window.msgBox = function(t, s)
{ 
	var ss = new String(""); 
	var i = s.indexOf('\n');	 
	if(i==-1) { i = s.indexOf(String.fromCharCode(13)); }	
	if(i==-1) { i = s.length; }	 
	
	if(i>0) {  
		ss = t.replace(/\n/,'\n\xA0\xA0\xA0\xA0');
		ss = (String.trim(ss)!='') ? ss + ' \n' : '';
		ss += String.repete('\x5F', i) + '\n\n' + '\xA0\xA0\xA0\xA0' + s + '\n\n' + String.repete('\xAF', i) + '\n';  
		alert(ss);
	}
}  
/**/
window.addFavori = function()
{
    if (window.sidebar) 
    {    
        // Firefox
        window.sidebar.addPanel(window.document.title, window.location.href, "");
    } 
    else 
    {
        if (window.external && typeof(window.external.AddFavorite) !== "undefined") 
        {
            // Internet Explorer
            window.external.AddFavorite(window.location.href, window.document.title);
        }
        else 
        {  
            // Opera, Google Chrome and Safari
            alert("Votre navigateur ne supporte pas cette fonctionnalité !");
        } 
    }
}
/**/
window.addDemarrage = function()
{
    this.style.behavior='url(#default#homepage)';
    this.setHomePage(window.location.href);
}
/**/
String.repete = function(s, nb)
{
	var tmp = new String("");
	
	for(i=1;i<=nb;i++) 
	{
		tmp+=s; 	  
	}
	return tmp; 
}
/**/
String.complete = function(oCible, format) 
{
    var r = '';
    if(oCible)
    {
        var bObj = false;
        var s= '';
        
        if(typeof(oCible)=='object') {
            oCible = $(oCible);
            s = String.trim(oCible.value);
            bObj = true;
        } else {
            s = String.trim(oCible);
        }
        r = s;
        var nbs = String.trim(s).length;
        var nbf = String.trim(format).length;
        if(nbf>0 && nbs>0)
        {
            if(nbs<nbf)
            {
                r = format.substring(nbs, (nbf-nbs)+1) + s;
            }
        }
        if(bObj) {
            oCible.value = r;
        }
    }
    return r;
}
/**/
String.trim = function(st)
{
    var txt = new String(st);
    if(txt!='') {
	    return txt.replace(/(^\s*)|(\s*$)/g,''); 
    } else {
        return '';
    }
}
/**/
String.left = function(Chaine, n) 
{
    var sRet = new String("");
    var iLen = Chaine.length;
    
    if (n > 0 && iLen != 0)
    {
        if (n > iLen)
        {
            sRet = Chaine;
        }
        else
        {
            sRet = Chaine.substring(0, n);
        }
    }
    return sRet;
}
/**/
String.right = function(Chaine, n)
{
    var sRet = new String("");
    var iLen = Chaine.length;
    
    if (n > 0 && iLen != 0)
    {
        if (n > iLen)
        {
            sRet = Chaine;
        }
        else
        {
            sRet = Chaine.substring(iLen, iLen - n);
        }
    }
    return sRet;
}
/**/
String.escapeJS = function(Chaine)
{
    Chaine = isEmpty(Chaine) ? '' : Chaine;
    Chaine =  Chaine.replace('\\\\', '\\');
    Chaine =  Chaine.replace('\\', '\\\\');
    Chaine =  Chaine.replace("'", "\\'"); 
    Chaine =  Chaine.replace('"', '\\"'); 
    
    return Chaine;
}
/**/
String.insere = function(Chaine1, Chaine2, pos)
{
    return Chaine1.substr(0, pos-1) + Chaine2 + Chaine1.substr(pos-1, Chaine1.length-pos);
}
/**/ 
Date.getTime = function()
{
    var t1 = new Date();
	return t1.getTime();
}
/**/
Date.isDate = function(d) 
{
 	if (d == "") 
  		return false;
  		
  	e = new RegExp("^[0-9]{1,2}\/[0-9]{1,2}\/([0-9]{2}|[0-9]{4})$");
  	
  	if (!e.test(d)) 
    	return false; 
	
	j = parseInt(d.split("/")[0], 10); 
	m = parseInt(d.split("/")[1], 10); 
	a = parseInt(d.split("/")[2], 10); 
	if (a < 1000) 
	{
	    if (a < 89)  a+=2000; 
	        else a+=1900;
	}
	
	if (a%4 == 0 && a%100 !=0 || a%400 == 0) fev = 29;
	    else fev = 28;

	nbJours = new Array(31,fev,31,30,31,30,31,31,30,31,30,31);
	
	return ( m >= 1 && m <=12 && j >= 1 && j <= nbJours[m-1] );
}

/**/
Date.JourSemaine = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
/**/
Date.USString = function(sDt)
{
    var sRet = '';
    var tDt = '';
    
    if(String.trim(sDt)!='') 
    {
        tDt = sDt.split('/');
        if(tDt.length==3)
        {
            sRet = tDt[1] + '/' + tDt[0] + '/' + tDt[2];
        }
    }
    
    return sRet;
}
/**/
Date.dateAdd = function(part, nb, oDate)
{
    var oDt = new Date(oDate);
    
	switch(part)
	{
		case "M":
			oDt.setMonth(oDate.getMonth() + nb);
			break;
		case "Y":
			oDt.setFullYear(oDate.getFullYear() + nb);
			break;
		case "D":
			oDt.setDate(oDate.getDate() + nb);
			break;
		case "H":
			oDt.setHours(oDate.getHours() + nb);
			break;
		case "N":
			oDt.setMinutes(oDate.getMinutes() + nb);
			break;
		case "S":
			oDt.setSeconds(oDate.getSeconds() + nb);
			break;
		default:
	}
	
	return oDt;
}


/**/
Date.IJourSemaine = function(sDt, bFR)
{
    var iJour = -1;
    bFR = isEmpty(bFR) ? false : bFR;
    
    if(Date.isDate(sDt))
    {
        var sDateUS = Date.USString(sDt)
        if(sDateUS!='')
        {
            d = new Date(sDateUS);
            var iJour = d.getDay();
            if(bFR)
            {
                iJour = (iJour==0) ? 6 : iJour-1;
            }
        }
    }
    
    return iJour;
}

/**/
Number.isPair = function(val)
{
    cible = new Number(val);
    res = new Number(0);
    
    if(cible==0) return true;
    res = cible / 2;
    return (Math.round(res) == res) ? true : false;
}
/**/
Array.isArray = function(o)
{
   return (o.constructor.toString().indexOf("Array") == -1) ? false : true;
}
/**/
function quiALeFocus(e) 
{
    var cible = ''; 
    
    if ("activeElement" in document)
    { 
       cible = document.activeElement; //Si IE
    } 
    else  
    { 
       cible = e ? e.explicitOriginalTarget : null;  // Si Firefox (e = event)
    }
    
    return cible;
}
/**/
function PCoockie(nom, donnee) 
{
// ecriture d'un coockie standard valable 1 an	   
	var dtNow = new Date();
	var dtExpire = new Date();

	dtExpire.setTime(dtNow.getTime() + 1000*60*60*24*365);
	ECookie(nom, donnee, dtExpire);
}
/**/
function ECookie(nom, donnee, expire)
{
// création d'un coockie 
	document.cookie = nom + "=" + escape(donnee) + ((expire == null) ? "" : ("; expires=" + expire.toGMTString()));   
}
/**/
function LCookie(nom) 
{
// lecture d'un cookie
	var debut; 
	var fin;
	var ret = '';
   
	nom += "=";
	if (document.cookie.length > 0) 
	{
		debut = document.cookie.indexOf(nom);
		if (debut != -1) 
		{
			debut += nom.length;
			fin = document.cookie.indexOf(";",debut);
			if (fin == -1) 
			{
				fin = document.cookie.length;
			}
			ret = unescape(document.cookie.substring(debut, fin));
		}
	}
	return ret;
}  
/**/
function EffaceCombo(objX) {  
	if(objX){
		var NB = objX.length;
		
		while(NB!=0){
			objX.remove(NB-1);
			NB=objX.length;
			if(NB==0) {
				objX.remove(NB);
			}
		}
	}
} 
/**/
