﻿
/* Validator object */

function Validator(constraints, options)
{
	this.constraints = constraints;
	
	if(options != undefined)
	{
		this.beforeValidation = options.beforeValidation;
		this.onConstraintFail = options.onConstraintFail;
		this.onConstraintSuccess = options.onConstraintSuccess;
		this.onValidationFail = options.onValidationFail;
		this.onValidationSuccess = options.onValidationSuccess;
		this.breakAfterFail = options.breakAfterFail;	
		this.defaultFunction = options.defaultFunction;
	}
	
	if(this.defaultFunction === undefined)
	{
		this.defaultFunction = Validation.nonEmpty;
	}
}

Validator.prototype.addConstraints = function(constraints)
{
	for(var i = 0; i < constraints.length; i++)
	{
		this.constraints[this.constraints.length] = constraints[i];
	}
}

Validator.prototype.validate = function()
{
	if(this.beforeValidation)
	{
		this.beforeValidation(this);
	}

	var isValid = true;
	
	for(var i = 0; i < this.constraints.length; i++)
	{
		if(this.constraints[i])
		{
			var result;
			var fn = this.constraints[i].fn ? this.constraints[i].fn : this.defaultFunction;
			if(fn.constructor == Array)
			{
				result = true;
				for(var j = 0; j < fn.length; j++)
				{
					if(!fn[j](this.constraints[i]))
					{
						result = false;
						break;
					}
				}
			}			
			else
			{
				result = fn(this.constraints[i]);
			}
			var callback = result ? this.onConstraintSuccess : this.onConstraintFail;
			if(callback)
			{
				callback(this.constraints[i]);
			}
			if(this.breakAfterFail && !result)
			{
				if(this.onValidationFail)
				{
					this.onValidationFail();
				}
				return false;
			}
			isValid = isValid && result;
		}
	}
	
	var callback = isValid ? this.onValidationSuccess : this.onValidationFail;
	if(callback)
	{
		callback();
	}
				
	return isValid;
}

/* Validation functions */

var Validation = new Object();

Validation.nonEmpty =	function (constraint)
{
	return document.getElementById(constraint.control).value != "";
}		
		
Validation.lengthBetween =	function (constraint)
{
  var ctrl = document.getElementById(constraint.control);
  if(ctrl.value == "" && constraint.allowEmpty) return true;
	return ctrl.value.length >= constraint.from && ctrl.value.length <= constraint.to;
}
		
Validation.isChecked = function (constraint)
{
	return document.getElementById(constraint.control).checked;
}		

Validation.radioSelected = function (constraint)
{
	var rb = document.getElementsByName(constraint.name);
	for(var i = 0; i < rb.length; i++)
	{
		if(rb[i].checked) return true;
	}
	return false;
}

Validation.checkboxesChecked = function (constraint)
{
	var cb = document.getElementsByName(constraint.name);
  var min = constraint.min ? constraint.min : 0;
  var max = constraint.max ? constraint.max : cb.length;
	var cnt = 0;
	for(var i = 0; i < cb.length; i++)
	{
		if(cb[i].checked) cnt++;
	}
	return (cnt >= min) && (cnt <= max);
}
		
Validation.isDate =	function (constraint)
{
	var val = document.getElementById(constraint.control).value;
	if(constraint.allowEmpty && val == "") return true;
	if(Validation._int_RegExp(val, "^[0-1][0-9]/[0-3][0-9]/[1-9][0-9]{3}$"))
	{
		var dt = new Date(val);
		var arr = val.split("/");
		return (dt.getFullYear() == arr[2]) && (dt.getMonth() == arr[0] - 1) && (dt.getDate() == arr[1]);
	}
	return false;
}
		
Validation.isNumber =	function (constraint)
{
  var pattern = constraint.allowEmpty ? "^[0-9]*$" : "^[0-9]+$";
	return Validation._int_RegExp(document.getElementById(constraint.control).value, pattern);
}

Validation.isAmount = function(constraint)
{
  var pattern = constraint.allowEmpty ? "^([0-9]+(\\.[0-9]{1,2})?)?$" : "^[0-9]+(\\.[0-9]{1,2})?$";
	return Validation._int_RegExp(document.getElementById(constraint.control).value, pattern);
}
		
Validation.isEmail = function (constraint)
{
  var pattern = constraint.allowEmpty 
    ? "^([0-9a-zA-Z\\-\\.\\_]+@([0-9a-zA-Z\\-]+\\.)+[0-9a-zA-Z]+)?$" 
    : "^[0-9a-zA-Z\\-\\.\\_]+@([0-9a-zA-Z\\-]+\\.)+[0-9a-zA-Z]+$";
	return Validation._int_RegExp(document.getElementById(constraint.control).value, pattern);
}
		
Validation.isPhone = function (constraint)
{
	return Validation._int_RegExp(document.getElementById(constraint.control).value, "^[\\+\\-0-9\\(\\).#x ]+(ext[\\+\\-0-9\\(\\).# ]+)?$");
}

Validation.regExp = function (constraint)
{
	return Validation._int_RegExp(document.getElementById(constraint.control).value, constraint.pattern);
}

/* For internal use only */

Validation._int_RegExp = function(value, pattern)
{
  var regExp = new RegExp(pattern);
	return regExp.test(value);
}
