var $n = {
	/* 	hasAttributes : retourne true si l'element passe en parametre correspond a tous les attributs passes, on peut aussi donner des attributs que l'on ne veut pas, afin de filtrer tous les &eacute;lements
		ex : if (hasAttributes(div, {nodeName:"div", className:"foobar"), {className:"idontwant"} ) doStuff();
		ici on recherche tous les DIV qui on la classe "foobar", mais on ne prend pas ceux qui ont la classe "idontwant" ex : <div class="foobar idontwant"> ne sera pas recupere.
	*/
	hasAttr : function(n, a, not) {
		var re, at;
		if (n.nodeType!=1) return false;
		function check(attr) {
			for (var i in attr) {
				at = (typeof n[i]) !="undefined" ? n[i] : n.getAttribute(i);
				re = attr[i] instanceof RegExp ? re : new RegExp("\\b" + attr[i] + "\\b","i");
				if (!at || !re.test(at)) 
					return false;
			}
			return true;
		};
		if (not && check(not))	return false;
		if (check(a)) return true;
		return false;
	},
	/* getByTagName : equivalent a element.getElementsByTagName, mais compatible avec IE5 et IE5.5 pour l'histoire du "*" */
	getByTagName : function(n, tag) {
		return  (tag=="*") ? (n.all ? n.all : n.getElementsByTagName("*")) : n.getElementsByTagName(tag);
	},
	/* fonction qui retourne le premier element correspondant aux attributs donnes */
	node : function(n, a, not) {
		return $n.nodes(n, a, not, true);
	},
	/* fonction qui retourne tous les elements correspondant selon "a" */
	nodes : function(n, a, not, oneNode, arrElms) {
		var aRetElms=[];
		if (!a) a = {};
		if (typeof a == "string") a = {nodeName:a}; //si une chaine de caract&egrave;res pass&eacute;e en param&egrave;tre, cela signifie qu'on ne veut que r&eacute;cup&eacute;rer des tags
		if (a.nodeName && a.nodeName=="*") delete a.nodeName;
		var elms = arrElms || $n.getByTagName(n, (a.nodeName || "*"));
		for (var i=0; i<elms.length; i++) {
			var x = elms[i];
			if ($n.hasAttr(x, a, not)) {
				if (oneNode) return x;
				else aRetElms.push(x);
			}
		}
		if (oneNode) return null;
		return aRetElms;
	},
	/* childs : retourne tous les noeuds enfants de l'element  */
	childs : function(n, a, not) {
		return $n.nodes(n, a, not, false, n.childNodes);
	},
	firstChild : function(n, a, not) {
		return $n.nodes(n, a, not, true, n.childNodes);
	},
	lastChild : function(n, a, not) {
		var node = $n.nodes(n, a, not, false, n.childNodes);
		return node[node.length-1];
	},
	move : function(n, a, not, action) {
		while (n) {
			if ($n.hasAttr(n, a, not)) return n;
			n = n[action];
		}
		return null;
	},
	after : function(n, a, not) { 
		return $n.move(n, a, not, "nextSibling");
	},
	before : function(n, a, not) {
		return $n.move(n, a, not, "previousSibling");
	},
	parent : function(n, a, not) {
		return $n.move(n, a, not, "parentNode");
	}
}
/* fonctions raccourcis */
var getNode = $n.node,
	getNodes = $n.nodes,
	getChildNodes = $n.childs,
	getNextSibling = $n.after,
	getPreviousSibling = $n.before,
	getParent = $n.parent,
	hasAttributes = $n.hasAttr,
	getElementsByTagName = $n.getByTagName;



var formval={
	defaultErrorMessage:"Ce champ est erron\u00E9",
	defaultPosition:"beforefield",
	globalErrorMsg : "",
	callbackfunctions : function() {
		//fixColumns();
		//if (popLayer.pop) popLayer.resize();
	},
	lineInput : {nodeName:"(div|p|li)"},
	validationFunc:{
		requiredgroup:function(field) {
			var self = this;
			var returnMessage=true;
			var allFields = field.getAttribute('requiredgroupothers').split(',');
			allFields.each(function(field) {
				field = $(field);
				if (self.required(field)!=true) returnMessage = false;
			});
			
			return returnMessage;
			
		},
		required:function(field) {
			var returnMessage=true;
			switch(field.type) {
				case "text":
				case "file":
				case "password":
				case "textarea":
					if (field.value=="") returnMessage="text";
					break;
				case "checkbox":
				case "radio":
					var sameElt = formval.getSameElements(field);
					var onecheck=false;
					for (var i=0; i<sameElt.length; i++) {
						if (sameElt[i].checked)
							onecheck=true;
					}
					if (!onecheck) returnMessage=field.type;
					break;
				case "select-one":
				case "select-multiple":
					if(field.selectedIndex==0) 
						returnMessage="select";
					break;
			}
			return returnMessage;
		},
		duo:function(field) {
			returnMessage = true;
			var allFields = field.getAttribute('completewith').split(',');
			
			for(i=0; i<allFields.length; i++){ 
				if(document.getElementById(allFields[i]).value == '' && field.value != '') returnMessage = false;
			}
			
			return returnMessage;
			
			
		},
		atleastone:function(field) {
			returnMessage = false;
			var allFields = field.getAttribute('atleast').split(',');
			
			for(i=0; i<allFields.length; i++){ 
				if(document.getElementById(allFields[i]).value != '') returnMessage = true;
			}
			
			return returnMessage;
			
			
		},
		email:function(field) {return (field.value=="" || !!field.value.match(/^[a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,6}$/i));},
		name:function(field) {return (field.value=="" || !!field.value.match(/^([a-zA-Z]|\s|\'|\.|\-)+$/));},
		pseudo:function(field) {return !!field.value.match(/^[a-zA-Z0-9_\-]{3,20}$/);},
		image:function(field) {return (field.value=="" || !!field.value.match(/^.+\.(gif|jpe?g|png)$/));},
		dateOptional:function(field) {
			if(field.value=="") return true;
			else{
				var dateSplit = field.value.split('/');
				var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, dateSplit[0]);
				if (date.getDate()!=dateSplit[0] || date.getMonth()!=parseInt(dateSplit[1])-1 || date.getFullYear()!=dateSplit[2]) {
					return false;
				}
				return true;
			}
		},
		dateValid:function(field) {
			var dateSplit = field.value.split('/');
			
			if( !!dateSplit[0].match(/[0-9]{2}/) && !!dateSplit[1].match(/[0-9]{2}/) && !!dateSplit[2].match(/[0-9]{4}/) ) return true;
			return false;
		},
		dateValidOptional:function(field) {
			if(field.value=="") return true;
			
			var dateSplit = field.value.split('/');
			
			if( !!dateSplit[0].match(/[0-9]{2}/) && !!dateSplit[1].match(/[0-9]{2}/) && !!dateSplit[2].match(/[0-9]{4}/) ) return true;
			return false;
		},
		date:function(field) {
			var dateSplit = field.value.split('/');
			var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, dateSplit[0]);
			if (date.getDate()!=dateSplit[0] || date.getMonth()!=parseInt(dateSplit[1])-1 || date.getFullYear()!=dateSplit[2]) {
				return false;
			}
			return true;
		},
		dateMax:function(field) {
			var dateSplit = field.value.split('/');
			var date = new Date(dateSplit[2], parseInt(dateSplit[1])-1, dateSplit[0]);
			return !(date.getTime()>new Date().getTime())
		},
		codepostal:function(field){return !!field.value.match(/\d[ab0-9]\d{3}/);},
		cpordep:function(field){if (field.value=="") return true; return !!field.value.match(/\d[ab0-9](\d{3})?/i);},
		phonenumber:function(field){if (field.value=="") return true; return !!field.value.match(/^\d{10}$/);},
		rio:function(field) { if (field.value=="") return true; return (!!field.value.replace(/\W|_/gi, "").match(/^[\dA-Za-z]{12}$/));},
		phonenumber2:function(field){
			var val = field.value;
			if (val=="") return true; 
			var cleanNum = val.match(/(\+)?\d+/g)
			if (!cleanNum) return false;
			cleanNum = cleanNum.join(""); //on recupere le numero de telephone en version nettoyee.
			if (!cleanNum.match(/^\+?(33|033|0033)?0?[1-9]\d{8}$/)) return false; //on checke reelement le numero de telephone
			return !!val.match(/^(\d|\s|-|\.|\\|\/|_|\+)+$/); //on check si des caract&egrave;res autres que chiffes,-,+,.,_,/,\  sont pr&eacute;sents
		},
		numbers:function(field){if (field.value=="") return true; return !!field.value.match(/^\d+$/);},
		numcommande:function(field){if (field.value=="") return true; return !!field.value.match(/\d{10}/);},
		alphanum:function(field){if (field.value=="") return true; return !!field.value.match(/^[\dA-Za-z\s]+$/);},
		heure:function(field){if (field.value=="") return true; return !!field.value.match(/^[\dA-Za-z\s\:]+$/);},
		decimal:function(field){if (field.value=="") return true; return !!field.value.match(/^\d+([.,]\d+)?$/);},
		equalsto:function(field) {
			var equalsFieldId = field.getAttribute("equalsto");
			var equalsField = document.getElementById(equalsFieldId);
			return (field.value==equalsField.value);
		},
		minimum:function(field) {
			if (field.nodeName!="FIELDSET") return true;
			var minNum = field.getAttribute("minimum_num") || 1;
			var properties = field.getAttribute("minimum_field") || "text,femail";
			var properties = properties.split(/,/g);
			var inputs = field.getElementsByTagName("input");
			var counter = 0;
			for (var i=0; i<inputs.length; i++) {
				var x=inputs[i];
				if (x.type==properties[0] && new RegExp(properties[1]).test(x.name) && x.offsetHeight>0) {
					if (formval.validationFunc["required"](x)===true) {
						counter++;
					}
				}
			}
			return counter<minNum ? ([false,minNum]) : true;
		},
		minimumLetter:function(field){
			if (field.value=="") return true; 
			var minLength = field.getAttribute("minlength")
			return  (field.value.length>=minLength) ? true : [false,minLength];
		},
		requiredexclusif:function(field) {
			var reqExclusifField = document.getElementById(field.getAttribute("reqexclusiffield"));
			if (!reqExclusifField) {
				alert("Vous n'avez pas associe le bon champ, verifiez l'attribut reqexclusif");
				return false;
			}
			if (field.getAttribute("requiredexclusifcondition")) {
				if (field.getAttribute("requiredexclusifcondition")=="noempty") {
					if (field.value!="" || reqExclusifField.value!="") return true;
					else return false;
				}
			} else 
				if ((field.value=="" && reqExclusifField.value=="") || (field.value!="" && reqExclusifField.value!="") ) return false;
		},
		siret : function(field) {
			var siret = field.value;
			if (siret=="") return true;
			var estValide;
			if ( (siret.length != 14) || (isNaN(siret)) )
				estValide = false;
			else {
				// Donc le SIRET est un numérique à 14 chiffres
				// Les 9 premiers chiffres sont ceux du SIREN (ou RCS), les 4 suivants
				// correspondent au numéro d'établissement
				// et enfin le dernier chiffre est une clef de LUHN.
				var somme = 0;
				var tmp;
				for (var cpt = 0; cpt<siret.length; cpt++) {
					if ((cpt % 2) == 0) { // Les positions impaires : 1er, 3è, 5è, etc...
						tmp = siret.charAt(cpt) * 2; // On le multiplie par 2
						if (tmp > 9)
							tmp -= 9; // Si le résultat est supérieur à 9, on lui soustrait 9
						}
					else
						tmp = siret.charAt(cpt);
					somme += parseInt(tmp);
				}
				estValide =  ((somme % 10) == 0) // Si la somme est un multiple de 10 alors le SIRET est valide
			}
			return estValide; 
		}
	},
	errorMessages:{
		required:{
			checkbox:"Cette case doit \u00EAtre coch\u00E9e",
			radio:"Vous devez s\u00E9lectionner une de ces options",
			text:"Attention, ce champ est obligatoire",
			select:"Vous devez s\u00E9lectionner une de ces options"
			
		},
		requiredoptional:this.required,
		duo:"Une information associ\u00E9e &agrave; ce champ est manquante",
		email:"Cette adresse e-mail est erron\u00E9e",
		name:"Ce champ ne doit comporter que des lettres, et les caract&egrave;res suivants : '-",
		numbers:"Ce champ ne doit comporter que des chiffres",
		numcommande:"Le num&eacute;ro de commande doit comporter 10 chiffres",
		alphanum:"Ce champ ne doit comporter que des chiffres et/ou des lettres",
		heure:"Ce champ ne doit comporter que des chiffres et/ou des lettres ou le caractère :",
		decimal:"Ce champ ne doit comporter que des chiffres",
		phonenumber:"Ce champ ne doit comporter que des chiffres",
		phonenumber2:"Veuillez v\u00E9rifier votre num\u00E9ro de t\u00E9l\u00E9phone",
		equalsto:"Ce champ doit &ecirc;tre identique au pr&eacute;c&eacute;dent",
		codepostal:"Ce code postal est erron\u00E9",
		cpordep:"Vous ne pouvez mettre qu'un num\u00E9ro de d\u00E9partement ou un code postal",
		pseudo:'Attention, votre pseudo doit contenir uniquement 20 caract&egrave;res, des lettres et des num\u00E9ros et les signes "_" et "-"',
		image:"Votre fichier n'est pas au bon format",
		minimum:"Vous devez remplir au moins ## champ",
		minimumLetter:"Vous devez remplir au moins ## caract&egrave;res",
		requiredexclusif:"Vous devez remplir au moins un des champs",
		siret:"Le num\u00E9ro siret n'est pas valide",
		rio:"Le code rio n\u0027est pas valide (12 caract&egrave;res)",
		date:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		dateOptional:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		dateMax:"La date doit &ecirc;tre inf&eacute;rieure &agrave; la date en cours",
		dateValid:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		dateValidOptional:"La date est erron\u00E9e ou n'est pas au format JJ/MM/AAAA",
		atleastone:"Vous devez remplir au moins l'un des champs"
	},
	getMessagePosition:function(field){
		var element=field;
		var position="";
		if (field.getAttribute("position")) {
			var position = field.getAttribute("position");
			if (!position.match(/^(before|after)(label|parentnode|field)$/)) {
			 	position = formval.defaultPosition;
			}
			var arrPos = position.match(/^(before|after)(label|parentnode|field)$/);
			switch(arrPos[2]) {
				case "label" : 
					var node = field;
					while(node.nodeName!="LABEL") {
						node=node.previousSibling;
					}
					if (node.nodeName=="LABEL") element=node;
					break;
				case "parentnode" : 
					var parentPos = field.getAttribute("parentnode_pos") ? parseInt(field.getAttribute("parentnode_pos")) : 1;
					var element=field;
					for (var i=0; i<parentPos; i++) {
						element=element.parentNode;
					}					
					break;
			}
			return [arrPos[1],element];
		} else {
			return [formval.defaultPosition.match(/(before|after)(label|parentnode|field)/)[1],element]
		}
	},
	getSameElements:function(field) { //return an array of elements in form who have same nodeName, name and type
		var aReturnElements=[];
		var elt=field.form.elements;
		for (var i=0; i<elt.length; i++) {
			if (elt[i].nodeName==field.nodeName && elt[i].name==field.name && elt[i].type==field.type) {
				aReturnElements.push(elt[i]);
			}
		}
		return aReturnElements;
	},
	check:function(theForm, showOnlyOneMessage, otherReturnValues) {
		formval.globalErrorMsg = "";
		var scrollTop = document.body.scrollTop;
		var finalErrorMessage="";
		var hasError=false;
		var elm = theForm.elements;
		for (var i=0; i<elm.length; i++) {
			var x=elm[i];
			if (x.getAttribute("validation") && x.offsetHeight && x.offsetHeight>0 && !x.disabled) {
				var validOptions = x.getAttribute("validation").split(/\s+/g);
				finalErrorMessage="";
				for (var j=validOptions.length-1; j>=0; j--) {
					if (typeof(formval.validationFunc[validOptions[j]])=="function") {
						var returnMessage = formval.validationFunc[validOptions[j]](x);
						var quantity = typeof(returnMessage)=="object" && returnMessage.length ? returnMessage[1] : 0;
						returnMessage = typeof(returnMessage)=="object" && returnMessage.length ? returnMessage[0] : returnMessage;
						if (returnMessage==false || typeof(returnMessage)=="string") { //si message erreur ou index de tableau associatif
							hasError=true;
							if (x.getAttribute(validOptions[j]+"_em")!=null) { //si le champ possede un message personnalis&eacute; pour l'erreur alors on affihce
								finalErrorMessage=x.getAttribute(validOptions[j]+"_em");
							} else { //sinon
								if (typeof(returnMessage)=="string") { //si le message d'erreur est un index de tableau associatif
									finalErrorMessage=formval.errorMessages[validOptions[j]][returnMessage]; //on va chercher le message associ&eacute; &agrave; cet index
								} else {
									if (formval.errorMessages[validOptions[j]] && typeof(formval.errorMessages[validOptions[j]])=="string") { //si le message d'error est false
										finalErrorMessage=formval.errorMessages[validOptions[j]]; //alors on retourne le message d'erreur associ&eacute;
										if (quantity>0) finalErrorMessage=finalErrorMessage.replace(/\#\#/g,quantity);
									}
									else finalErrorMessage=formval.defaultErrorMessage; //sinon on affiche le message d'erreur par d&eacute;faut pour tout champ
								}
							}
						} else {
							formval.clearMessage(x);
						}						
					}
				}
				if (finalErrorMessage!="") formval.showMessage(x, finalErrorMessage);
			}
		}
		document.body.scrollTop=scrollTop;
		var secondErrorValue=false;
		if (otherReturnValues!=null) {
			if(typeof(otherReturnValues)=="boolean") {
				secondErrorValue=!otherReturnValues;
			} else {
				for (var i=0; i<otherReturnValues.length; i++) {
					if (!otherReturnValues[i]) secondErrorValue = true;
				}
			}
		}
		
		hasError = hasError || secondErrorValue;
		if (showOnlyOneMessage) {
			if (showOnlyOneMessage==true) {
				elm = null;
			} else {
				var elm = document.getElementById(showOnlyOneMessage);
			}
			if (hasError) {
				alert(formval.globalErrorMsg);
			} else {
				if (elm) elm.className=elm.className.replace(/\berrorAlertShow\b/g,"");
			}
		}
		return (!hasError); //return true si aucune erreur sinon false;
	},
	checkIfErrorMessageBefore:function(field) {
		var node = field;
		var i=0;
		while(node.previousSibling && i<=2) {
			if (node.nodeType==1 && node.className.match(/\berrormsg\b/))
				return node;
			node=node.previousSibling;
			i++;
		}
		return null;
	},
	clearMessage:function(field) {
		if (field.getAttribute("typemessage") && field.getAttribute("typemessage")=="aspect") {
			if (field.getAttribute("rel") && field.getAttribute("rel")!="") {
				var elm = document.getElementById(field.getAttribute("rel"));
				elm.className = elm.className.replace(/\berror\b/g,"");
			}
		} else {
			if (field.associatedErrorMessage) {
				field.associatedErrorMessage.style.display="none";
			}
		}
	},
	insertAfter:function(parent, nodeToInsert, nodeInDom) {
		nodeToInsert = nodeInDom.appendChild(nodeToInsert);
		return nodeToInsert;
	},
	showMessage:function(field, msg) {
		formval.globalErrorMsg += "- " + msg + "\n";
		if (field.getAttribute("typemessage") && field.getAttribute("typemessage")=="aspect") {
			if (field.getAttribute("rel") && field.getAttribute("rel")!="") {
				var elm = document.getElementById(field.getAttribute("rel"));
				elm.className+=" error";
			}
		} else {
			if (!field.associatedErrorMessage) {
				if (!formval.checkIfErrorMessageBefore(field)) {
					var pos = formval.getMessagePosition(field);
					var parentField = getParent(field, formval.lineInput);
					var label = getNode(parentField, {nodeName:"label"});
					if (label)
						var msgField = formval.insertAfter(label.parentNode, document.createElement("span"),label);
					else 
						var msgField = formval.insertAfter(parentField.parentNode, document.createElement("span"),parentField);
					msgField.className="errormsg";
					field.associatedErrorMessage=msgField;
				} else {
					field.associatedErrorMessage = formval.checkIfErrorMessageBefore(field);
				}
			}
			field.associatedErrorMessage.innerHTML=msg;
			field.associatedErrorMessage.style.display="";	
		}
	}
}

/* addFormActions */

/* Add maxlength on textareas */
function maxLengthOntextarea() {
	var container = document.body;
	var textareas = container.getElementsByTagName("textarea");
	for (var i=0; i<textareas.length; i++) {
		var x= textareas[i];
		if (x.getAttribute("maxlength")) {
			addEvent(x, "keyup", checkMaxlength);
			addEvent(x, "keydown", checkMaxlength);
			addEvent(x, "blur", checkMaxlength);
		}
	}
}
function checkMaxlength(e) {
	var maxL = parseInt(this.getAttribute("maxlength"));
	if (this.value.length>maxL) {
		this.value=this.value.substr(0,maxL);
		this.scrollTop = this.scrollHeight;
	}
}
/* /maxlength */


function formInput(inputId, attributes) {
	var inp = document.getElementById(inputId);
	if (!inp) return;
	for (var i in attributes) {
		inp.setAttribute(i,attributes[i]);
	}
}



// fonction de desactivation de champs

function disabler(fieldFrom, tabValues, fieldsTo ){
	for( var i=0; i<tabValues.length; i++ ){
		if(document.getElementById(fieldFrom).value == tabValues[i]) {
			for( var j=0; j<fieldsTo.length; j++) document.getElementById(fieldsTo[j]).disabled = true;
			exit;
		}
	}
	
	for( var j=0; j<fieldsTo.length; j++) document.getElementById(fieldsTo[j]).disabled = false;

}


function toggleDisabled(fieldsTo, toggle, fieldsToClear){
	
	//alert(toggle);
	
	for( var j=0; j<fieldsTo.length; j++){  
		if(parseInt(toggle) == 1){ 
			document.getElementById(fieldsTo[j]).disabled = true;
			for(var i=0; i<fieldsToClear.length; i++) document.getElementById(fieldsToClear[i]).value = '';
		}else document.getElementById(fieldsTo[j]).disabled = false;
		
	}
}



// fonction de somme de champs

function makeSum(fieldsFrom, fieldTo ){
	
	var somme = 0;
	
	for( var i=0; i<fieldsFrom.length; i++ ){ 
		if(document.getElementById(fieldsFrom[i]).value != '') somme += parseInt(document.getElementById(fieldsFrom[i]).value);
	}
	
	document.getElementById(fieldTo).value = somme;

}


function makeTotal(fieldsFrom, fieldTo){
	

	
	
	var somme = 0;
	
	var beware = false;
	
	for( var i=0; i<fieldsFrom.length; i+=2 ){ 
		
		if(document.getElementById(fieldsFrom[i]).value == '') document.getElementById(fieldsFrom[i]).value = 0;
		
		if(isNaN(parseInt(document.getElementById(fieldsFrom[i]).value)*parseInt(document.getElementById(fieldsFrom[i+1]).value)) == false){
	
			somme += parseInt(document.getElementById(fieldsFrom[i]).value)*parseInt(document.getElementById(fieldsFrom[i+1]).value);
			
		}else beware = true;
	}
	
	
	
	if(beware == false) document.getElementById(fieldTo).value = somme;
	
}





