// 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 this.replace(/(^\s*)|(\s*$)/g, "");
}

// add a leading zero
function add_lz(x) {
	return( x<0 || x>9 ? '' : '0') + x; 
}
// reload
function reload(win)
{
	if (!win.frames.length && win != self)
		win.location.reload(true);
	for (var i=0; i<win.frames.length; i++)
	{
		if (win != self)
			reload(win.frames[i]);
	}
}

// reset options
function reset_options_ex(ctrl, flag) {
	var i;
	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);
	else
	{
		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,3}$/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_date(fld) {
	if ( !fld.value.match(/^[0-3]?[0-9][-\/ ][01]?[0-9][-\/ ](19|20)?[0-9]{2}$/) )
		return false;
	re = /^([0-3]?[0-9])[-\/ ]([01]?[0-9])[-\/ ]((19|20)?[0-9]{2})$/;
	var m = re.exec(fld.value);
	if (m == null) 
		return false;
	var max = 31;
	if (m[1] < 1 || m[2] < 1 || m[2] > 12)
		return false;
	if (m[2] == 4 || m[2] == 6 || m[2] == 9 || m[2] == 11)
		max = 30;
	else if (m[2] == 2)
		max = (m[3] % 4 == 0 && (m[3] % 100 != 0 || m[3] % 1000 == 0)) ? 29 : 28;
	if (m[1] > max)
		return false;
	return true;
}

// get_value
function get_value(lst)
{
	return ((lst.selectedIndex >= 0) ? lst.options[lst.selectedIndex].value : null);
}

// form_init
function form_init (f) {
	f.fc = new formChecker();
	// parcourir les éléments pour traiter les input[type=text]
	var l = f.elements.length;
	for (var i=0; i < l; i++) {
		var 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 labels = f.getElementsByTagName("label");
	var label, elem, i = j = 0;
	// 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.hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;

	// trouve le container d'un contrôle
	this.find_container = function (p)
	{
		var max = 5;
		while (max > 0)
		{
			max--;
			if (!p.parentNode || p == p.parentNode) return null;
			p = p.parentNode;
			if (p.nodeName=='P' || p.nodeName=='DIV')
				return p;
			if (p.nodeName=='FIELDSET' || p.nodeName=='FORM')
				return null;
		}
	}
	// construit la chaîne d'erreur, garde le premier contrôle et modifie la présentation
	this.add_error = function (ctrl) {
		var label = "", c = 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;
		this.err += 'Vous devez préciser "'+ label + '"!\n';
		// on visualise l'erreur
		p = this.find_container (o);
		if (p) addClassName(p, '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];
		p = this.find_container (ctrl);
		if (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.form[c.name])==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));
		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':
				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 {
			var l = f.elements.length;
			for (i=0; i < l; i++) {
				this.check_control (f.elements[i]);
			}
		}
		// s'il y a des erreurs on ne valide pas le formulaire
		if (!this.err.length)
			return true
		if (!c || c == 'undefined')
			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;
	}
}