/*
** $Id: form_checker.js,v 1.2 2009/02/12 15:41:57 jhuet Exp $
** Validation de formulaires - RnD - (c) 2008
*/
// add_load_event
function add_load_event (fn) {
	var of = window.onload;
	if (typeof window.onload != 'function') { window.onload = fn; return; }
	window.onload = function() { of(); fn(); }
}

// add_onchange_event
function add_onchange_event (c, fn) {
	var of = c.onchange;
	if (typeof c.onchange != 'function') { c.onchange = fn; return;}
	c.onchange = function() { of.apply(this, arguments); fn.apply(this, arguments); }
}

// trim
function trim(s) { return s.replace(/(^\s*)|(\s*$)/g,''); }
String.prototype.trim = function(){ return trim(this); }

// get_value
function get_value(lst) { return ((lst.selectedIndex >= 0) ? lst.options[lst.selectedIndex].value : null); }
// reset options
function reset_options_ex(ctrl, flag) {
	if (!ctrl || !ctrl.options) return;
	for (var i=0;i<ctrl.options.length;i++)
		ctrl.options[i].selected = flag;
}
function reset_options(ctrl) { reset_options_ex(ctrl, false); }
// count_checked
function count_checked(ctrl)
{
	if (!ctrl.length)
		return (ctrl.checked ? 1 : 0);
	for (var cnt=0, i=0; i<ctrl.length; i++)
		if (ctrl[i].checked) cnt ++;
	return cnt;
}
// set_checked
function set_checked(ctrl, val)
{
	if (!ctrl.length)
		ctrl.checked = (ctrl.value == val || val == null);
	else
	{
		for (var i=0; i<ctrl.length; i++)
			ctrl[i].checked = (ctrl[i].value == val || val == null);
	}
}

// is_xxx functions
function is_percentage(fld) { return ( fld.value.match( /^[\d]{1,2}$/ ) ); }
function is_number(fld) { return ( fld.value.match(/^\d+$/) ); }
function is_email(fld) { return fld.value.match(/^[a-z0-9\.\-\_]+@([a-z0-9\-\_]+\.)+[a-z]{2,4}$/i); }
function is_year(fld) { return fld.value.match(/^(18|19|20)[0-9]{2}$/); }
function is_telephone(fld) { return fld.value.match(/^[0-9 \.]{10,14}$/); }
function is_zip(fld) { return fld.value.match(/^[0-9]{5}$/); }
function is_date(fld) {
	var a = fld.value.split(/[\/\-\:]/), d = new Date(a[2], a[1]-1, a[0]);
	return (!isNaN( d ) && a[2] > 0 && d.getYear()%100==a[2]%100 && d.getMonth()==a[1]-1 && d.getDate()==a[0]);
}

// form_init
function form_init (f) {
	f.fc = new formChecker();
	// parcourir les éléments pour traiter les input[type=text]
	for (var c, i=0, l = f.elements.length; i < l; i++) {
		c = f.elements[i];
		switch (c.nodeName)
		{
		case 'INPUT':
			if (!(c.type=='text' || c.type=='radio' || c.type=='checkbox'))
				break;
		case 'SELECT':
		case 'TEXTAREA':
			add_onchange_event (c, form_onchange);
			break;
		default:
			/* do ntohing */
		}
	}
	// ajouter un onsubmit
	f.onsubmit = form_onsubmit;
	// ajouter les labels
	setTimeout(function () { add_label_properties (f); }, 1);
}

/* fonctions pour gérer les évènmeents */
function form_onchange() {
	return this.form.fc.run(this.form, this);
}
function form_onsubmit() {
	return this.fc.run(this);
}

// add a label property to all input / select / textarea element
function add_label_properties (f) {
	// Collect all label elements in form, init vars
	if ( typeof f.getElementsByTagName == 'undefined' ) return;
	var label, elem, i=0, j=0, labels = f.getElementsByTagName("label");
	// Loop through labels retrieved
	while ( label = labels[i++] )
	{	
		// For Opera 6
		if ( typeof label.htmlFor == 'undefined' ) return;
		// Retrieve element
		elem = f.elements[label.htmlFor];
		if ( typeof elem == 'undefined' ) { // No element found for label
			alert( "No element found for label: " + label.htmlFor );
		} else if ( typeof elem.label != 'undefined' ) { // label property already added
			continue;
		} else if ( typeof elem.length != 'undefined' && elem.length > 1 && elem.nodeName != 'SELECT' ) { // For checkbox arrays and radio-button groups
			for ( j = 0; j < elem.length; j++ ) {
				elem.item( j ).label = label;
			}
		} else  {
			// Regular label
			elem.label = label;
		}
	}
}

// about class attributes
function hasClassName(el, className) {
	if (!el) return false;
	var regexp = new RegExp('(^|\\s)' + className + '($|\\s)', 'ig');
	return (el.className && el.className.search(regexp) != -1);
};
function addClassName(el, className) {
	if (!el || hasClassName(el, className)) return;
	if (el.className && el.className!="")
		el.className += " " + className;
	else
		el.className = className;
}
function removeClassName(el,className) {
	if (el && el.className && hasClassName(el, className)) {
		var regexp = new RegExp('(^|\\s)' + className + '($|\\s)', 'ig');
		el.className = el.className.replace(regexp,'');
	}
}

// objet formChecker
function formChecker () {
	this.err = "";
	this.ctrl = null;
	this.alert_type;
	this.hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;
	// construit la chaîne d'erreur, garde le premier contrôle et modifie la présentation
	this.add_error = function (ctrl, err_msg) {
		var i, label = "", o = null;
		if (ctrl.length && ctrl.length > 0 && ctrl.nodeName != 'SELECT') {
			o = ctrl[0];
			for (i=0; i<ctrl.length; i++) {
				if (this.hasInnerText)
					label += (label=="") ? ctrl[i].label.innerText : " / " + ctrl[i].label.innerText;
				else
					label += (label=="") ? ctrl[i].label.textContent : " / " + ctrl[i].label.textContent;
			}
		} else {
			o = ctrl;
			if (this.hasInnerText)
				label = ctrl.label.innerText;
			else
				label = ctrl.label.textContent;
		}		
		if (!this.ctrl) this.ctrl = o;		
		if(err_msg)
			this.err += err_msg + '\n';
		else
			this.err += 'Vous devez préciser "'+ label + '"!\n';
		// on visualise l'erreur
		if (o.parentNode && o.parentNode.nodeName=='P') {
			addClassName(o.parentNode, 'alerte');
		}
		return false;
	}
	// suppirme la présentation 'erreur'
	this.remove_error = function (ctrl) {
		if (!ctrl) return;
		if (ctrl.length && ctrl.length > 0 && ctrl.nodeName!='SELECT')
			ctrl = ctrl[0];
		if (ctrl.parentNode && ctrl.parentNode.nodeName=='P')
			removeClassName(ctrl.parentNode,'alerte');
		return true;
	}
	this.is_needed = function (c) {
		if (!c || !c.label) return false;
		return hasClassName(c.label, 'oblig');
	}
	this.check_select = function(c) {
		if (!this.is_needed(c)) return;
		if (c.selectedIndex==-1 || (c.selectedIndex == 0 && c.options[0].value==""))
			return this.add_error (c);
		return this.remove_error(c);
	}
	this.check_radio = function (c) {
		if (!this.is_needed(c)) return;
		if (c && count_checked (c)==0)
			return this.add_error (c);
		return this.remove_error(c);
	}
	// pour les input type=text
	this.check_field = function (c, test) {
		if (!c) return;
		if (!c.value.trim().length)
			test = !this.is_needed(c);
		if (!test)
			return this.add_error(c);
		return this.remove_error(c);
	}
	this.check_text = function (c) {
		if (c.className.match(/(^|\s)year(\s|$)/))
			return this.check_field(c, is_year(c));
		else if (c.className.match(/(^|\s)date(\s|$)/))
			return this.check_field(c, is_date(c));
		else if (c.className.match(/(^|\s)email(\s|$)/))
			return this.check_field(c, is_email(c));
		else if (c.className.match(/(^|\s)int(\s|$)/))
			return this.check_field(c, is_number(c));
		else if (c.className.match(/(^|\s)percent(\s|$)/))
			return this.check_field(c, is_percent(c));
		else if (c.className.match(/(^|\s)zip(\s|$)/))
			return this.check_field(c, is_zip(c));
		return this.check_field(c, true);
	}
	this.check_control = function (c) {
		switch (c.nodeName) 
		{
		case 'SELECT':
			this.check_select (c);
			break;
		case 'INPUT':
			switch (c.type)
			{
			case 'text':
			case 'password':
				this.check_text (c);
				break;
			case 'radio':
			case 'checkbox':
				this.check_radio (c);
				break;
			default: /* submit, hidden */
				break;
			}
			break;
		case 'TEXTAREA':
			this.check_text (c);
			break;
		default:
			/* do nothing */
		}
	}
	this.run = function (f, c) {
		this.err = "";
		this.ctrl = null;
		if (!f) return;
		if (c && c != 'undefined')	{
			this.check_control (c);
		} else {
			for (var i=0, l = f.elements.length; i < l; i++) {
				this.check_control (f.elements[i]);
			}
		}
		// check des doubles champs
		if(this.field_match.length)
		{
			for(var i=0; i<this.field_match.length; i++)
			{
				if( f[this.field_match[i][0]].value.trim().length
					&& f[this.field_match[i][1]].value.trim().length
					&& f[this.field_match[i][0]].value != f[this.field_match[i][1]].value)
				{
					this.add_error(f[this.field_match[i][1]], this.field_match[i][2]);
				}
			}
		}		
		// s'il y a des erreurs on ne valide pas le formulaire
		if (!this.err.length)
			return true
		if (!c || c == 'undefined')
		{
			if(this.alert_type == 'alert')
				alert("Le formulaire n'est pas valide !\n" + this.err);
		}
		if (this.ctrl) {
			if (this.ctrl.select) this.ctrl.select();
			if (this.ctrl.focus) this.ctrl.focus();
		}
		return false;
	}
	this.field_match = [];
	// les champs a tester deux a deux sont passé à form_field_match
	this.form_field_match = function (arr) {
		if(!arr || arr.length < 2) return;
		this.field_match.push(arr);
	}
	this.set_alert_type = function (type) {
		if(!type) return;
		this.alert_type = type;
	}
}