//validacion de formularios
//Paco Ramos
//fjrmoyano@gmail.com

$(document).ready(function () {
	$('.send').each(function () {
		var element = $(this);
		element.click(function (e) {
			e.preventDefault();
			var frm = element.closest('form');
			if (validateForm(frm) == true) {
				return false;
			} else {
				frm.submit();
				return true;
			}
		});
	});
});

function validateForm(form) {
	var arrClasses = new Array('required','minlength','maxlength','rangelength','minvalue','maxvalue','rangevalue','email','url','dateJS','dateISO','number','digits','creditcard','accept','equalto');
	var msg = new Array();
	var err = new Boolean(false);
	
	$(form).find('input, textarea, select').each(function () {
		var param = String();
		var classes = new String($(this).attr('class'));
		var name = new String($(this).attr('name'));
		var type = new String($(this).attr('type'));
		var idx = -1;
		var idxf = -1;
		var class_ = new String();
		var str = new String();
		
		if (type=='text' || type=='radio' || type=='checkbox' || type=='password' || type=='password' || type == '' || type == 'textarea' || type == 'select-one' || type == 'select-multiple') {
			$(this).removeClass('error');
			
			for(var i in arrClasses) {
				idx = classes.indexOf(arrClasses[i]);
				
				if (idx > -1) {
					//obtengo el nombre de la clase
					class_ = classes.substr(idx + arrClasses[i].length);
					idxf = class_.indexOf(" ");
					class_ = (idxf > 0)? class_.substr(0,idxf):class_;
					
					//obtengo la cadena de parametros pasados
					if (type == 'radio') {
						ret = validationSwitch(arrClasses[i], $(form).find("input[name='" + name + "']:checked").val(), class_);
					} else if (type == 'checkbox') {
						var selectedItems = new Array();
						$(form).find('input[name="' + name + '"]:checked').each(function() {selectedItems.push($(this).val());});

						ret = validationSwitch(arrClasses[i], selectedItems, class_);
					} else {
						ret = validationSwitch(arrClasses[i], $(this).val(), class_);
					}
					
					
					if (! ret) {
						err = true;
						str = "";
						
						name = name.replace("[]","");
						
						if (isset(messages) && isset(messages.customized) && isset(messages.customized[name]) && isset(messages.customized[name][arrClasses[i]])) {
							str = messages.customized[name][arrClasses[i]];
						} else if (isset(messages) && isset(messages[arrClasses[i]])){
							str = messages[arrClasses[i]];
						}
						
						if (str != "") {
							param = String(class_).replace("_", "-").split("-");
							
							if (isset(param[0])) {
								str = String(str).replace('{0}', param[0]);
							}
							
							if (isset(param[1])) {
								str = String(str).replace('{1}', param[1]);
							}
							
							$(this).addClass('error');
							
							msg.push(str);
						}
					}
				}
			}
		}
	});
	
	if (err == true) {
		try {
			//alert(msg.join("\r\n"));
			Sexy.error('<div class="error">' + msg.join("</div><div class=\"error\">") + '</div>');
		}
		catch(e) {
			alert(msg.join("\r\n"));
		}
	}
	
	return err;
}

function isset () {
    var a = arguments, l = a.length, i = 0, undef;    
    if (l === 0) {
        throw new Error('Empty isset'); 
    }
        while (i !== l) {
        if (a[i] === undef || a[i] === null) {
            return false; 
        }
        i++;     }
    return true;
}

function validationSwitch(validationType, value, classParameters) {
	var parameter = String(classParameters).replace("_", "-");
	
	var param = new Array(String(parameter).split("-"));
	
	// alert("param: " + param[0][0] + " // " + param[0][1]);
	
	switch(validationType) {
		case 'required':
			return required(value);
		case 'minlength':
			return minlength(value, parameter);
		case 'maxlength':
			return maxlength(value, param[0][0]);
		case 'rangelength':
			return rangelength(value, param[0][0], param[0][1]);
		case 'minvalue':
			return min(value, param[0][0]);
		case 'maxvalue':
			return max(value, param[0][0]);
		case 'rangevalue':
			return range(value, param[0][0], param[0][1]);
		case 'email':
			return email(value);
		case 'url':
			return url(value);
		case 'dateJS':
			return date(value);
		case 'dateISO':
			return dateISO(value);
		case 'number':
			return number(value);
		case 'digits':
			return digits(value);
		case 'creditcard':
			return creditcard(value);
		case 'accept':
			return accept(value, classParameters);
		case 'equalTo':
			return equalTo(value, param[0][0]);
		default:
			return true;
	}
}

function required(value) {
	if (typeof value == 'object') {
		return (value && (value.length > 0));
	} else {
		return $.trim(value).length > 0;
	}
}

function minlength(value, minValue) {
	if (typeof value == 'object') {
		return (value && (value.length >= minValue));
	} else {
		return $.trim(value).length >= minValue;
	}
}

function maxlength(value, maxValue) {
	if (typeof value == 'object') {
		return (value && (value.length <= maxValue));
	} else {
		return $.trim(value).length <= maxValue;
	}
}

function rangelength(value, minValue, maxValue) {
	if (typeof value == 'object') {
		var length = value? value.length:0;
	} else {
		var length = $.trim(value);
	}
	
	return (length >= minValue && length <= maxValue);
}

function min(value, minValue) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (value[i] >= minValue);
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = (value >= minValue);
	}
	
	return ret;
}

function max(value, maxValue) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (value[i] <= maxValue);
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = (value <= maxValue);
	}
	
	return ret;
}
		
function range(value, param0, param1) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (value[i] >= param0 && value[i] <= param1);
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = (value >= Number(param0) && value <= Number(param1));
	}
	
	return ret;
}
		
function email(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value[i]));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
	}
	
	return ret;
}

function url(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value[i]));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
	}
	
	return ret;
}

function date(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (!/Invalid|NaN/.test(new Date(value[i])));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = !/Invalid|NaN/.test(new Date(value));
	}
	
	return ret;
}

function dateISO(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value[i]));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
	}
	
	return ret;
}

function number(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value[i]));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
	}
	
	return ret;
}

function digits(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (/^\d+$/.test(value[i]));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = /^\d+$/.test(value);
	}
	
	return ret;
}

function creditcard(value) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					if (/[^0-9-]+/.test(value[i]))
						return false;
					var nCheck = 0,
						nDigit = 0,
						bEven = false;

					value[i] = value[i].replace(/\D/g, "");

					for (var n = value[i].length - 1; n >= 0; n--) {
						var cDigit = value[i].charAt(n);
						var nDigit = parseInt(cDigit, 10);
						if (bEven) {
							if ((nDigit *= 2) > 9)
								nDigit -= 9;
						}
						nCheck += nDigit;
						bEven = !bEven;
					}

					ret = ret && ((nCheck % 10) == 0);
				}
			}
		} else {
			ret = false;
		}
	} else {
			// accept only digits and dashes
		if (/[^0-9-]+/.test(value))
			return false;
		var nCheck = 0,
			nDigit = 0,
			bEven = false;

		value = value.replace(/\D/g, "");

		for (var n = value.length - 1; n >= 0; n--) {
			var cDigit = value.charAt(n);
			var nDigit = parseInt(cDigit, 10);
			if (bEven) {
				if ((nDigit *= 2) > 9)
					nDigit -= 9;
			}
			nCheck += nDigit;
			bEven = !bEven;
		}

		ret = ((nCheck % 10) == 0);
	}
	
	return ret;
}

function accept(value, param) {
	var ret = new Boolean(true);
	param = typeof param == "string" ? param.replace(/-/g, '|') : "png|jpe?g|gif";
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (value[i].match(new RegExp(".(" + param + ")$", "i")));
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = value.match(new RegExp(".(" + param + ")$", "i"));
	}
	
	return ret;
}

function equalTo(value, param) {
	var ret = new Boolean(true);
	
	if (typeof value == 'object') {
		if (value) {
			for(var i in value) {
				if (typeof value != 'object') {
					ret = ret && (value[i] == param);
				}
			}
		} else {
			ret = false;
		}
	} else {
		ret = (value == param);
	}
	
	return ret;
}
