// ###### CAPTURES DES EVENEMENTS ######################################################################################################################################
function iniFunctions(e){
	form_bindFormulaires(); // Capture tous les évènement sur les éléments de formulaire qui respectent la syntaxe
	funcExec();
}

function stopEvent(e){ // Stop la propagation de l'event e
	if(e.stopPropagation){
		e.stopPropagation();
		e.preventDefault();
	} else {
		e.cancelBubble=true;
		e.returnValue=false;
	}
}

// ###### AJAX #########################################################################################################################################################
function AJXcall(page,form,chmp){
	if($(chmp)){
		new Ajax.Request(page,{		
//		new Ajax.Request("./ajax/"+page,{
				method: 'post',
				postBody: Form.serialize(form),
				onComplete:function(req){
					Element.update($(chmp),req.responseText);
	//				Element.scrollTo($(chmp));
					form_bindFormulaires();
				}
			});
		Element.update(chmp,'<img src="./images/indicator.gif">');
	}
}

// ###### FORMULAIRES D'INTERFACE (BOUTONS)  ###########################################################################################################################
var REGEX_field_VALUE=/^JS:(.*)$/;
var REGEX_field_COMMANDE=/^([VASLMCEKFXIP]{1})_([^']*)(_'?([^']*)'?)?$/;
var REGEX_field_IMAGE=/^([0-9]+)x([0-9]+)(\-(.*))?$/;

function form_bindElements(formIn){ // Surveille tous les éléments d'un formulaire en fonction de leur type
	var elts=Form.getElements(formIn); // On récupère tous les boutons image ---
	for(var index=0;index<elts.length;index++){
		var nom=elts[index].id;
		if(elts[index].id.match(REGEX_field_VALUE)){
			switch(elts[index].type){
				case "button":
				case "submit":
				case "image":
					var evt='click';
					break;
				case "text":
				case "select-one":
				case "checkbox":				
					var evt='change';
					break;
			}
			Event.observe(elts[index],evt,form_btnExec,false);
		}
	}
}

function form_bindFormulaires(){ // Capture tous les evenement de tous les éléments qui répondent au format de tous les formulaires de la page
	var forms=document.forms;
	for(var index=0;index<forms.length;++index){form_bindElements(forms.item(index));}
}

function form_btnExec(e){ // Execute les commandes des boutons des formulaires
	var elt=Event.element(e);
	if(str=elt.id.match(REGEX_field_VALUE)){
		str=strExplode(/[^\|]+/,str[1]);
		if(str.length<1){
			return 0;
		} else {
			var tst=1;
			for(var index=0;index<str.length;index++){
				if(tst){tst=form_func(str[index],elt,e);}
			}
		}
	}
}

function form_func(func,elt,e){ // Change la valeur du champ de form par valeur
	if(prm=$(func.match(REGEX_field_COMMANDE))){
		var form=elt.up('form');
		if(prm){			
//	alert($A(prm).inspect());
			switch(prm[1]){
				case "V":  //Change la valeur du champ prm[2] par prm[4]
					var chmp=$(form.elements[prm[2]]);
					if($(prm[4])){prm[4]=$F($(prm[4]));}
					var val=(prm[4]=='this')?$F(elt):prm[4];
//	alert(chmp.name+"-->'"+val+"'");
					chmp.value=val;
					return 1;
					break;
				case "A": // Change le paramètre action du formulaire prm[2] sinon par defaut celui qui contient le champ
					var form=(prm[2]!='')?prm[2]:form;
					var val=(prm[4]=='this')?valeur:prm[4];
					$(form).action=val;
					return 1;
					break;
				case "S": // Soumet le formulaire prm[2] sinon par defaut celui qui contient le champ
					var form=prm[2]?prm[2]:form;
					$(form).submit();
					return 1;
					break;
				case "L": // Change de page (document.location)
					var val=(prm[2]=='this')?valeur:prm[2];
					document.location=val;
					return 1;
				case "M": // Boite d'alerte avec message
					alert(prm[4]);
					return 1;
				case "C": // Boite de confirmation avec message
					if(!confirm(prm[4])){
						stopEvent(e);
						return 0;
					} else {
						return 1;
					}
				case "E": // Evalue la validité du forlulaire avant de le soummettre
					return checkForm(form);
				case "F": // Fonction à exécuter avec paramètres
					var val=(prm[4]=='this')?valeur:prm[4];
					var str=prm[2]+"('"+val+"')";
					eval(str);
					return 1;
				case "X": // Fonction Ajax soumets à prm[2] la valeur de tous les champs du formulaire courant en POST et met à jour le contenu prm[4] 
					stopEvent(e);
					AJXcall(prm[2],form,prm[4]);
					return 1;
				case "I": // Ouvre une vignette (image dans une nouvelle fenêtre) à l'aide de la fonction vignette
					stopEvent(e);
					if(tx=$(prm[4].match(REGEX_field_IMAGE))){vignette(prm[2],tx[1],tx[2],tx[4]);}
					return 1;
				case "P": // Pop Up : ouvre l'url dans une nouvelle fenêtre
					popUp(prm[2]);
					return 1;
			}
		}
	}
}

// ###### CHAINES DE CARACTERES ########################################################################################################################################
function strExplode(token,texte){ // Similaire à la fonction PHP Explode
	var str=[];
	texte.scan(token,function(match) {str.push(match[0]);});
	return str;
}

// ###### NAVIGATEURS (from PHPBB) #####################################################################################################################################
var clientPC=navigator.userAgent.toLowerCase();
var clientVer=parseInt(navigator.appVersion);
var is_ie=((clientPC.indexOf("msie")!=-1) && (clientPC.indexOf("opera")==-1));
var is_nav=((clientPC.indexOf('mozilla')!=-1) && (clientPC.indexOf('spoofer')==-1) && (clientPC.indexOf('compatible')==-1) && (clientPC.indexOf('opera')==-1) && (clientPC.indexOf('webtv')==-1) && (clientPC.indexOf('hotjava')==-1));
var is_saf=((clientPC.indexOf('safari')!=-1));

var is_moz=0;
var is_win=((clientPC.indexOf("win")!=-1) || (clientPC.indexOf("16bit")!=-1));
var is_mac=(clientPC.indexOf("mac")!=-1);


// ###### FORMULAIRES ##################################################################################################################################################
// ## une partie du code est adaptée du livre : Bien développer pout le Web 2.0, de Christophe Courteneuve (Editions Eyrolles 2006)
// Être compatible avec MSIE...
if ('undefined'==typeof Node)
    Node={ELEMENT_NODE: 1, TEXT_NODE: 3 };

var REGEX_AUTO_FIELD=/^[^_]+(_Req)?(_([0-9]+|Txt|EMail|Int|Dbl|Date|Radio|Len)(_[0-9.]+){0,2})?$/;
var REGEX_BLANK=/^\s*$/;
var REGEX_TXT=/^[^%$<>]+$/;
var REGEX_EMAIL=/^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9_\.\-]+\.[a-zA-Z]{2,3}$/;
var REGEX_DAY=/^(0?[1-9]|[1-2][0-9]|3[01])$/;
var REGEX_MONTH=/^(0?[1-9]|1[0-2])$/;
var REGEX_TYPED_FIELD=/_(Txt|EMail|Int|Dbl|Date|Radio|Len)(_([0-9.]+))?(_([0-9.]+))?$/;
var REGEX_YEAR=/^[0-9]{2,4}$/;

var MSG_BLANK=' est vide.';
var MSG_UNCHECKED=' n\'est pas coché.';
var MSG_RADIO=' n\'est pas défini(e). ';
var MSG_BAD_CHARS=' comporte des caractères interdits.';
var MSG_BAD_EMAIL=' n\'est pas une adresse e-mail valide.';
var MSG_NOT_A_DATE=' n\'est pas une date.';
var MSG_NOT_A_DOUBLE=' n\'est pas un nombre.';
var MSG_NOT_AN_INTEGER=' n\'est pas un nombre entier.';
var MSG_TOO_LOW=' est trop petit(e).';
var MSG_TOO_HIGH=' est trop grand(e).';
var MSG_BAD_LENGTH=' n\'a pas le bon nombre de  caractères';

function checkForm(form){
	var errors='';
	var faulty=null;
//alert($A(form.elements).inspect());
	for(var index=0;index<form.elements.length;++index){
		var field=form.elements.item(index);
		if(!field.id.match(REGEX_AUTO_FIELD)){continue;}
		var value=getFieldValue(field);
		if(!value && field.value){value=field.value;}		
//alert(field.name+"=>"+field.value);
		if(field.id.match(/_Req/)){
			var mess=null;
			if(value.match(REGEX_BLANK)){mess=MSG_BLANK;}
			if(field.type=='checkbox' && !field.checked){mess=MSG_UNCHECKED}
			if(mess){
				errors+='"'+getFieldName(field)+'"'+mess+'\n';				
				faulty=faulty || field;
				continue;
			}			
		}
		var match=field.id.match(REGEX_TYPED_FIELD);
		if(match){			
//alert($A(match).inspect());
			var type=match[1];
			var min=match[3];
			var max=match[5];
			var error=checkTypedField(value,type,min,max);
			if(error){
				errors+='"'+getFieldName(field)+'"'+error+'\n';
				faulty=faulty || field;
			}
		}
	}
	if(!faulty){
		return 1;
	} else {
		alert(errors);
		faulty.focus();
		return 0;
	}
}

function checkTypedField(value,type,min,max) {
    // Valeurs par défaut pour les bornes
    min=min || Number.NEGATIVE_INFINITY;
    max=max || Number.POSITIVE_INFINITY;
    var val;
	 switch(type){
		case 'Txt':
			if(!value.match(REGEX_TXT)){return MSG_BAD_CHARS;}
			break;
		case 'EMail':
			if(!value.match(REGEX_EMAIL)){return MSG_BAD_EMAIL;}
			break;			
		case 'Date':
			var comps=value.split('/');
			if(3!=comps.length || !comps[0].match(REGEX_DAY) || !comps[1].match(REGEX_MONTH) || !comps[2].match(REGEX_YEAR)){return MSG_NOT_A_DATE;}
			break;
		case 'Radio':
			if(!getRadioVal(value)){return MSG_RADIO;}
			break;
		case 'Len':
			if(value.length<min || value.length>max){return MSG_BAD_LENGTH+" (min. : "+min+", max. : "+max+")";}
			break;	
		case 'Int':
			try{
				val=parseInt(value,10);
				if(String(val)!=value){throw val;}
			} catch(e) {return MSG_NOT_AN_INTEGER;}
		case 'Dbl':
			try{
				val=parseFloat(value);
				if(String(val) != value){throw val;}
			} catch(e) {return MSG_NOT_A_DOUBLE;}
	 }
    if('Int'==type || 'Dbl'==type){
        if(val<min){return MSG_TOO_LOW;}
        if(val>max){return MSG_TOO_HIGH;}
    }
    return null;
}

function getFieldName(field){
	var label=getLabelFor(field);
	if(!label){return field.name;}
	var text='';
	var node=label.firstChild;
	// Parcours en profondeur, dérécursifié, du fragment sous le libellé
	while(true){
		if(Node.ELEMENT_NODE==node.nodeType && node.hasChildNodes()){
			node=node.firstChild;
		} else { 
			if(Node.TEXT_NODE==node.nodeType){text+=node.nodeValue;}
			if(node.nextSibling){
				node=node.nextSibling;
			} else {
				node=node.parentNode;
				if(node==label){break;}
				node=node.nextSibling;
			}			
		}
	}
	return text;
}

function getFieldValue(field){
	var value='';
	switch(field.tagName){
		case 'INPUT':
			value=field.value;
			break;
		case 'SELECT':
			if(-1<field.selectedIndex){
				var opt=field.options[field.selectedIndex];
				value=opt.value;
				if(!value && !('value' in opt)){value=opt.text;}
        }
	}
	return value;
}

function getLabelFor(field){
	var labels=document.getElementsByTagName('label');
	for(var index=0;index<labels.length;++index){
		var label=labels.item(index);
		if (label.htmlFor==field.id){return label;}
	}
	return null;
}

function getRadioVal(field){
	var val=null;
	var rad=document.getElementsByName(field);
	for(var index=0;index<rad.length;++index){
		if(rad.item(index).checked){val=rad.item(index).value;}
	}
	return val;
}

// ------ Actions "dynamiques" des formulaires -------
function checkAll(nom){
	var elts=document.getElementsByName(nom);
	for(var index=0;index<elts.length;++index){elts.item(index).checked=true;}
}

function uncheckAll(nom){
	var elts=document.getElementsByName(nom);
	for(var index=0;index<elts.length;++index){elts.item(index).checked=false;}
}

// ------ Calculs pour les formulaires de type bon de commande, factures etc. ------
function dateCalc(nom){ // Calcul de la valeur du champ caché de date : nom à partir des ses champs de choix de jour, mois et année
	var form=($(nom)).up('form');
	var jour=form.elements[nom+'Jour'].value;
	var mois=form.elements[nom+'Mois'].value;
	var annee=form.elements[nom+'Annee'].value;
	($(nom)).value=annee+"-"+mois+"-"+jour;
}

function timeCalc(nom){ // Calcul de la valeur du champ caché de timestamp
	var form=($(nom)).up('form');
	var jour=form.elements[nom+'Jour'].value;
	var mois=form.elements[nom+'Mois'].value;
	var annee=form.elements[nom+'Annee'].value;
	var heure=form.elements[nom+'Heure'].value;
	var minutes=form.elements[nom+'Minutes'].value;
	var secondes=form.elements[nom+'Secondes'].value;	
	($(nom)).value=annee+"-"+mois+"-"+jour+" "+heure+":"+minutes+":"+secondes;
}

function dateRefresh(nom){ // Met les champs de choix de date à la date du jour
	var form=($(nom)).up('form');
	aujourdhui=new Date;
	var jour=aujourdhui.getDate();
	var mois=aujourdhui.getMonth()+1;
	var annee=aujourdhui.getFullYear();
	if(jour<10){jour="0"+jour;}
	if(mois<10){mois="0"+mois;}
	form.elements[nom+'Jour'].value=jour;	
	form.elements[nom+'Mois'].value=mois;
	form.elements[nom+'Annee'].value=annee;
}

function timeRefresh(nom){ // Met tous les champs de choix de timestamp à la date et heure du jour
	var form=($(nom)).up('form');
	aujourdhui=new Date;
	var jour=aujourdhui.getDate();
	var mois=aujourdhui.getMonth()+1;
	var annee=aujourdhui.getFullYear();
	var heure=aujourdhui.getHours();
	var minutes=aujourdhui.getMinutes();
	var secondes=aujourdhui.getSeconds();
	if(jour<10){jour="0"+jour;}
	if(mois<10){mois="0"+mois;}
	if(heure<10){heure="0"+heure;}
	if(minutes<10){minutes="0"+minutes;}
	if(secondes<10){secondes="0"+secondes;}
	form.elements[nom+'Jour'].value=jour;	
	form.elements[nom+'Mois'].value=mois;
	form.elements[nom+'Annee'].value=annee;
	form.elements[nom+'Heure'].value=heure;
	form.elements[nom+'Minutes'].value=minutes;
	form.elements[nom+'Secondes'].value=secondes;
}

function calc_lignes(qte,pu,montant){ // Affiche dans montantXX le resultat de qteXX*puXX (si qte est numérique) 
	var tags=document.getElementsByTagName("input");
	var lg=qte.length;
	for($i=0;$i<tags.length;$i++){
		var nom=tags[$i].name;
		var deb=nom.substring(0,lg);
		var index=nom.substring(lg,nom.length);
		if(deb==qte){
			if(!isNum(tags[$i].value)){
				alert("ATTENTION, seules les valeurs numériques sont admises !");
				tags[$i].value=0;
			} else {
				document.all[montant+index].value=Number(document.all[qte+index].value*document.all[pu+index].value);
			}
		}
	}	
}

function calc_total(prefix,chmpTotal){	// Calcul le total de tous les champs dont le nom commence par prefix et affiche le resultat dans chmpTotal
	var tags=document.getElementsByTagName("input");
	var lg=prefix.length;
	var total=0;
	for($i=0;$i<tags.length;$i++){
		var nom=tags[$i].name;
		var deb=nom.substring(0,lg);
		if(nom==chmpTotal){champ=tags[$i];}
		if(deb==prefix){			
			if(!isNum(tags[$i].value)){
				alert("ATTENTION, seules les valeurs numériques sont admises !");
				return false;
			} else {
				total+=Number(tags[$i].value);
			}
		}
	}
	champ.value=total;
}

function calc_limit(defaut,limite,valeur,dest){ //  Affiche dans dest defaut si valeur<limite sinon 0
	var taux=defaut;
	if(document.all[valeur].value>=limite){taux=0;}
	document.all[dest].value=taux;
}

function calc_add(dest,valeur){ // Affiche dans  dest, valeur additionnée de la valeur de tous les champs passés en paramètre à sa suite 
	var total=0;
	if(document.all[valeur].value>0){
		for($i=1;$i<calc_add.arguments.length;$i++){total=total+Number(document.all[calc_add.arguments[$i]].value);}
	}
	document.all[dest].value=total;
}

function isNum(checkStr){ // Vérifie si une valeur est bien numérique
	REGEX_isNUM=/[0-9\.]+/;
	if(checkStr.match(REGEX_isNUM)){return TRUE;} else {return FALSE;}
}


// ###### IMAGES #######################################################################################################################################################
function vignette(nomimg,tx,ty){ // Ouvre une nouvelle fenètre au milieu de l'écran à la taille xy de l'image nomimg
	var args=vignette.arguments;
	var largeurE=screen.width;
	var hauteurE=screen.height;
	var espL=(largeurE-tx)/2;
	var espH=(hauteurE-ty)/2;
	var taille="width="+tx+",height="+ty;
	var winPos=",left="+espL+",top="+espH;
	var params=taille+winPos+",directories=no,location=no,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,toolbar=no";
	zoom=window.open('','',params);
	zoom.document.write('<html><body leftmargin=0 topmargin=0 marginwidth=0 marginheight=0 onblur=\"window.close()\">');
	zoom.document.write('<img src="'+nomimg+'" width='+tx+' height='+ty+' border=0 onmouseout=\"window.close()\" onmousedown=\"window.close()\">');
	zoom.document.write('</body></html>');	
}

// ##### POP UP ########################################################################################################################################################
function popUp(url){ // Ouvre une nouvelle fenètre au milieu de l'écran avec comme source URL
	var args=vignette.arguments;
	var largeurE=screen.width;
	var hauteurE=screen.height;
	var tx=(largeurE-1024)?1024:largeurE;
	var ty=(hauteurE-768)?768:hauteurE;
	var espL=(largeurE-tx)/2;
	var espH=(hauteurE-ty)/2;
	var taille="width="+tx+",height="+ty;
	var winPos=",left="+espL+",top="+espH;
	var params=taille+winPos+",directories=no,location=yes,menubar=no,resizable=yes,scrollbars=yes,status=no,titlebar=yes,toolbar=no";
	zoom=window.open(url,'',params);
}

// ##### FLASH #########################################################################################################################################################
function putFlashIn(filename,width,height,dest){
	var inner='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,16,0" width="'+width+'" height="'+height+'">\n';
	inner+='<param name=movie value="'+filename+'">\n';
	inner+='<param name="quality" value="high">\n';
	inner+='<embed src="'+filename+'" quality="high" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="'+width+'" height="'+height + '">\n';
	inner+='</embed>\n';
  	inner+='</object>\n';
	Element.update($(dest),inner);
}

// ##### CADDIE : fonctions AJAX pour les caddies ######################################################################################################################
function caddie_resume(divTo){ // Ajoute à la valeur au caddie et retourne le tout dans divTo après une attente
	var timer=setTimeout("caddie_affResume('"+divTo+"')",100);
} 

function caddie_affResume(divTo){
	if($(divTo)){
		new Ajax.Updater(divTo,'caddie_resume.php',
		{
			insertion: Insertion.bottom,
			onComplete: function(req){
					form_bindFormulaires();
				}
		});
		Element.update(divTo,'<img src="./images/indicator.gif">');		
	}	
}

// ###### INITIALISE LES FONCTIONS DE CAPTURE DES EVENEMENTS APRES LE CHARGEMENT DE LA PAGE ############################################################################
Event.observe(window,"load",iniFunctions,false);
