// A generic form validator  
// (©) Brian Lalonde http://webcoder.info/downloads/validate.html
// License: http://creativecommons.org/licenses/by-sa/2.0/
// Adapted by Víncolo 

var vsmlang;				// Define el idioma en que se muestran los mensajes de error
var vsmsubmit = false;		// Usado para resaltar el campo solo cuando el onblur es llamado por el submit del form
var status = '';							// y no cuando se produce realmente el evento
var errorHandle = 'alert';
function vsmFormFocus() {
  if(!document.forms.length) return;
  var els= document.forms[0].elements;
  for(var i= 0; i < els.length; i++)
    if(els[i].type != 'hidden') { els[i].focus(); return; }
}

function vsmSubmit(frm, lang, funct) {
  if (funct != undefined) 
		errorHandle=funct;
  lang = lang.toLowerCase();
  if (lang != 'en' && lang !='pt' && lang !='es') {
  	 vsmlang='en';
  } else {
  	 vsmlang=lang;
  }
 // if (canCheckByBlur(frm)) return checkByBlur(frm);
 return checkByBlur(frm);
}

function canCheckByBlur(frm) { 
  for(var index= 0; index < frm.elements.length; index++) {
    var el= frm.elements[index];
    if(!el.type) continue;
    if(el.type != 'hidden' && el.name && typeof(el.onblur)=='function') return true;
  }
  return false;
}

function checkByBlur(frm) {
	status = '';
	vsmsubmit = true;
	for(var index= 0; index < frm.elements.length; index++)
		if(frm.elements[index].type == 'submit' || frm.elements[index].type == 'image') frm.elements[index].disabled= true;

	for(var index= 0; index < frm.elements.length; index++) {
		var el= frm.elements[index];
		if(!el.type) continue;
		if(el.type != 'hidden' && el.onblur) {
			el.onblur();
			if(status) {
				eval(errorHandle+"(status)");
				try {	/* Intenta hacer foco en el control */
					el.focus(); 
				} catch (error) {
					alert(error);
				}
				vsmsubmit = false;
				for(var index= 0; index < frm.elements.length; index++)
					if(frm.elements[index].type == 'submit' || frm.elements[index].type == 'image') frm.elements[index].disabled= false;
				return false; 
			}
		}
	}

	return true;
}

function vsmFieldDescription(fld) { 
  if(fld.title) return fld.title;
  if(fld.id && document.getElementsByTagName) {
    for(var i= 0, lbl= document.getElementsByTagName('LABEL'); i < lbl.length; i++)
      if(lbl[i].htmlFor==fld.id) return lbl[i].nodeValue||lbl[i].textContent||lbl[i].innerText;
    for(var i= 0, lbl= document.getElementsByTagName('label'); i < lbl.length; i++)
      if(lbl[i].htmlFor==fld.id) return lbl[i].nodeValue||lbl[i].textContent||lbl[i].innerText;
  }
  return fld.name;
}

/* Funciones de validación */

function vsmRequired(fld) {
	if(fld.disabled) return true;
	var ok= false;
	switch(fld.type) {
		case 'checkbox':
			if(fld.checked) ok= true;
			break;
		case 'radio':
			var radios = fld.form[fld.name];
			ok = false;
			for(var i= 0; i < radios.length; i++) {
				if (radios[i].checked) ok=true;
			}
			break;
		case 'select-one':
			//&& fld.options[fld.selectedIndex].value.length!=0
			if(fld.selectedIndex!=-1) ok= true;
			break;
		default:
			if(fld.value.length) ok= true;
			break;
	}
	if (ok) {
		return true;
	} else {
		switch (vsmlang) {
		case 'es': status= 'El campo '+vsmFieldDescription(fld)+' no puede ser omitido.'; break; 
		case 'pt': status= 'Deve preencher o campo '+vsmFieldDescription(fld)+'.'; break; 
		default:   status= 'The '+vsmFieldDescription(fld)+' field cannot be left blank.'; break; 
		}
		if (vsmsubmit && fld.type != 'checkbox' && fld.type != 'radio') fld.className = 'vsmformerror';
		return false;
	}
}

function vsmConfirmation(fld, confirmfld) {
	if(fld.disabled) return true;
	if(fld.value != confirmfld.value) {
		switch (vsmlang) {
			case 'es': status= 'Los campos '+vsmFieldDescription(fld)+' y '+vsmFieldDescription(confirmfld)+' deben ser idénticos.'; break; 
			case 'pt': status= 'Os campos '+vsmFieldDescription(fld)+' e '+vsmFieldDescription(confirmfld)+' devem ser iguais.'; break; 
			default: status= 'The '+vsmFieldDescription(fld)+' field does not match the '+vsmFieldDescription(confirmfld)+' field.'; break; 
		}
		if (vsmsubmit) {fld.className = 'vsmformerror'; confirmfld.className = 'vsmformerror'}
		return false;
	}
	return true;
}

function vsmLength(fld, min, max) { 
	// set minimum and/or maximum field lengths
	if(fld.disabled) return true;
	var len= fld.value.length;
	if(min > -1 && len < min) {
		switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(fld)+' debe tener al menos '+min+ ' caracteres; Actualmente tiene '+len+'.'; break;
			case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' deve conter no mínimo '+min+ ' caracteres; Atualmente contem '+len+'.'; break;
			default:   status= 'The '+vsmFieldDescription(fld)+' field must be at least '+min+ ' characters long; it is currently '+len+' characters long.'; break;
		}
		if (vsmsubmit) fld.className = 'vsmformerror';
		return false;
	}
  	if(max > -1 && len > max) { 
		switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(fld)+' debe tener un máximo de '+max+ ' caracteres; Actualmente tiene '+len+'.'; break;
			case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' deve conter no máximo '+max+ ' caracteres; Atualmente contem '+len+'.'; break;
			default:   status= 'The '+vsmFieldDescription(fld)+' field must be no more than '+max+' characters long; it is currently '+len+' characters long.'; break; 
		}
		if (vsmsubmit) fld.className = 'vsmformerror';
		return false;
	}
  	return true;
}

function vsmInteger(fld, min, max) { 
	// Controla que el campo sea entero entre los valores min y max
	if(fld.disabled) return true;
	if(fld.value && fld.value != parseInt(fld.value)) {
		switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(fld)+' debe ser numérico.'; break;
			case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' deve ser numérico.'; break;
			default:   status= 'The '+vsmFieldDescription(fld)+' field must be a number.'; break;
		}
		if (vsmsubmit) fld.className = 'vsmformerror';
		return false;
	}
	
	if(fld.value < min || fld.value > max) {
		switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(fld)+' debe ser numérico entre '+min+ ' y '+max+'.'; break;
			case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' deve ser numérico entre '+min+ ' y '+max+'.'; break;
			default:   status= 'The '+vsmFieldDescription(fld)+' field must be a number between '+min+ ' and '+max+'.'; break;
		}
		if (vsmsubmit) fld.className = 'vsmformerror';
		return false;
	}
  	return true;
}


function vsmTrim(str) {
	return str.replace(/^\s*|\s*$/g,"");
}

function vsmAllowChars(fld, chars) { 
	// provide a string of acceptable chars for a field
	if(fld.disabled) return true;
	for(var i= 0; i < fld.value.length; i++) {
		if(chars.indexOf(fld.value.charAt(i)) == -1) {
			switch (vsmlang) {
				case 'es': status= 'El campo '+vsmFieldDescription(fld)+' contiene caracteres no permitidos.\r\n" '+fld.value.charAt(i)+' " no es un caracter permitido.\r\nLos caracteres permitidos son:\r\n'+chars; break;
				case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' contem caracteres não permitidos.\r\n" '+fld.value.charAt(i)+' " não é um caracter permitido.\r\nOs caracteres permitidos são:\r\n'+chars; break;
				default: status= 'The '+vsmFieldDescription(fld)+' contain invalid characters. It may only contain the following characters:\r\n'+chars; break; 
			}
			if (vsmsubmit) fld.className = 'vsmformerror';
			return false;
		}
	}
	return true;
}

function vsmDisallowChars(fld, chars){ 
	// provide a string of unacceptable chars for a field
	if(fld.disabled) return true;
	for(var i= 0; i < fld.value.length; i++) {
    	if(chars.indexOf(fld.value.charAt(i)) != -1) {
	 		switch (vsmlang) {
				case 'es': status= 'El campo '+vsmFieldDescription(fld)+' no puede contener ninguno de los siguientes caracteres:\r\n'+chars; break; 
				case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' não pode conter nenhum dos seguintes caracteres:\r\n'+chars; break; 
				default: status= 'The '+vsmFieldDescription(fld)+' field cannot contain any of the following characteres:\r\n'+chars; break; 
			}
			if (vsmsubmit) fld.className = 'vsmformerror';
			return false;
  		}
	}
	return true;
}

function vsmEmail(fld) { 
	if(!fld.value.length||fld.disabled) return true; // blank fields are the domain of requireValue 
	fld.value = vsmTrim(fld.value.toLowerCase());
	var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,8})+$/;
	if (!filter.test(fld.value)) {
		switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(fld)+' no es una dirección de correo válida.'; break;
			case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' não é um endereço válido'; break;
			default:   status= 'The '+vsmFieldDescription(fld)+' field must contain a valid email address.'; break;
		}
		if (vsmsubmit) fld.className = 'vsmformerror';
		return false;
	}
	return true;
}

function vsmFile(fld, allowedfiletypes) {
	var ok = true;
	if(!fld.value.length||fld.disabled) return true; 
	// Obtiene la extension el archivo
	var filepath = fld.value;
	if(filepath.lastIndexOf(".") == -1) ok = false;
	if (ok) {
		var fileext = (filepath.substring(filepath.lastIndexOf(".")+1)).toLowerCase();
		if ((allowedfiletypes+',').indexOf(fileext+',') == -1) ok = false;
	} 
	if (!ok) {
		switch(vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(fld)+' no contiene un archivo válido.\r\n\r\nTipos de archivos válidos:\r\n' + allowedfiletypes.toUpperCase(); break;
			case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' não é um arquivo válido.\r\n\r\nTipos de arquivos validos:\r\n' + allowedfiletypes.toUpperCase(); break;
			default:   status= 'The '+vsmFieldDescription(fld)+' field must contain a valid file type.\r\n\r\nValid file types:\r\n' + allowedfiletypes.toUpperCase(); break;
		}
		if (vsmsubmit) fld.className = 'vsmformerror';
		return false;
	} 
	return true;
}

function vsmDate(fld, format) {
	// Esta ok si el campo está vacio o disabled
	if(!fld.value.length||fld.disabled) return true; 
	// Normaliza la fecha quitando los espacios y convirtiendo cualquier separador en /
	fld.value = vsmTrim(fld.value);
	var d = fld.value.replace(/\D/g, '/');
	// Obtiene los valores separados por /
	dateArray = d.split('/');
	if (dateArray.length == 3) {
		format = format.toLowerCase();
		switch(format) {
			case 'ymd': year=dateArray[0]; month = dateArray[1]; day = dateArray[2]; break;
			case 'dmy': year=dateArray[2]; month = dateArray[1]; day = dateArray[0]; break;
			case 'mdy': year=dateArray[2]; month = dateArray[0]; day = dateArray[1]; break;
		}
		ok = vsmValidDate(year, month, day);
		if (ok) {
			fld.value = d;
			return true;
		}
		
	}
	switch (vsmlang) {
		case 'es': status= 'El campo '+vsmFieldDescription(fld)+' no es una fecha válida.'; break;
		case 'pt': status= 'O campo '+vsmFieldDescription(fld)+' não é uma data válida'; break;
		default:   status= 'The '+vsmFieldDescription(fld)+' field must contain a valid date.'; break;
	}
	if (vsmsubmit) fld.className = 'vsmformerror';
	return false;
}

function vsmComboDate(yearfld, monthfld, dayfld, required) {
	if (typeof(required)=='undefined') required = false;
	if (yearfld.disabled || monthfld.disabled || dayfld.disabled) return true;
	if (!yearfld.value.length && !monthfld.value.length && !dayfld.value.length) {
		if (required) {
			switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(yearfld)+' no puede quedar vacío.'; break; 
			case 'pt': status= 'Deve preencher o campo '+vsmFieldDescription(yearfld)+'.'; break; 
			default:   status= 'The '+vsmFieldDescription(yearfld)+' field cannot be left blank.'; break; 
			}
			if (vsmsubmit) {yearfld.className = 'vsmformerror'; monthfld.className = 'vsmformerror'; dayfld.className = 'vsmformerror';}
			return false;
		} else {
			return true;
		}
	}
	ok =  vsmValidDate(yearfld.value, monthfld.value, dayfld.value);
	if (!ok) {
		switch (vsmlang) {
			case 'es': status= 'El campo '+vsmFieldDescription(yearfld)+' no es una fecha válida.'; break;
			case 'pt': status= 'O campo '+vsmFieldDescription(yearfld)+' não é uma data válida'; break;
			default:   status= 'The '+vsmFieldDescription(yearfld)+' field must contain a valid date.'; break;
		}
		if (vsmsubmit) {yearfld.className = 'vsmformerror'; monthfld.className = 'vsmformerror'; dayfld.className = 'vsmformerror';}
	}
	return ok;
}

function vsmValidDate(year, month, day) {
	if (!isNaN(day) && !isNaN(month) && !isNaN(year)) {
		month = month-1;
		var dteDate=new Date(year,month,day);
		if ((day==dteDate.getDate()) && (month==dteDate.getMonth()) && (year==dteDate.getFullYear())) return true;
	}
	return false;
}

function vsmDependants(enabled, elements) { 
	// Para Activar/Desactivar campos
	// convenience function to enable/disable dependant fields, passed in as an array 
	if(!elements.length) return true;
	for(var i= 0; i < elements.length; i++) {
    	elements[i].disabled= !enabled;
	}
}
