function isValid(v,e) {
	this.init(v,e);
}

function isNumber(v,e) {
	this.init(v,e);
}

function isFloat(v,e) {
	this.init(v,e);
}

function isGreaterThan(v,e) {
	this.init(v,e);
}

function isLessThan(v,e) {
	this.init(v,e);
}

function isDate(v,e) {
	this.init(v,e);
	this.updateable = true;
}

function isFutureDate(v,e) {
	this.init(v,e);
	this.updateable = true;
}

function isPastDate(v,e) {
	this.init(v,e);
	this.updateable = true;
}

function isNotPastDate(v,e) {
	this.init(v,e);
	this.updateable = true;
}


function isEmail(v,e) {
	this.init(v,e);
}

function isZip(v,e) {
	this.init(v,e);
}

function isPosInt(v,e) {
	this.init(v,e);
}

function isCC(v,e){
	this.init(v,e);
}

function isCVV(v,e){
	this.init(v,e);
}

function isAlpha(v,e){
	this.init(v,e);
}

function isRegExp(v,e){
	this.init(v,e);
}


// ***************************************************************************

function Data_initialize(v,e) {
	this.required = false;
	this.error = new String();
	this.value = v;
	this.elementPath = e;
	this.updateable = false;
	this.parameter = "";
}

function Data_getError() {
	return this.error;
}

function Data_setParameter(p) {
	return this.parameter = p;
}

function Data_canUpdate() {
	return this.updateable;
}

function Data_isValid() {
	return true;
}

function Data_isDate(d){
	function inRange(nbr,brange,erange){
		if ((nbr >= brange) && (nbr <= erange )) {
			return true;
		}
		return false;
	}

	function pad(value){
		if (value < 10) {
			return "0" + value;
		} else {
			return value;
		}
	}
	
	var daysinmonth = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	var x = d.split("/");
	if (x.length == 3){
		if (!isNaN(x[0]) && !isNaN(x[1]) && !isNaN(x[2])) {
			for (var i=0;i<3;i++){
				x[i] = parseFloat(x[i]);
			}
			if (inRange(x[0],1,12)) {
				if (x[2] % 4 == 0) { 
					daysinmonth[1] = 29;
				}
				if (inRange(x[1],1,daysinmonth[x[0]-1])) {
					if (x[2] < 22) {
						x[2] = 2000 + x[2];
					} else if (x[2] < 100) {
						x[2] = 1900 + x[2];
					}

					if (inRange(x[2],1900,2100)) {
						this.value = pad(x[0]) + "/" + pad(x[1]) + "/" + x[2];
						return true;
					}
				}
			}
						
		}
	}
	return false;
}

// ***************************************************************************

function IsDate_isValid() {
	if (!this.isDate(this.value)) {
		this.error = "is an invalid date";
		return false;
	} else {
		return true;
	}
}

function IsPastDate_isValid() {
	if (!this.isDate(this.value)) {
		this.error = "is an invalid date";
		return false;
	} else {
		var today = new Date();
		var past = Date.parse(this.value);
		if (past.valueOf() > today.valueOf()) {
			this.error = "must be in the past";
			return false;
		}
		return true;
	}
}

function IsFutureDate_isValid() {
	if (!this.isDate(this.value)) {
		this.error = "is an invalid date";
		return false;
	} else {
		var today = new Date();
		var future = Date.parse(this.value);
		if (future.valueOf() < today.valueOf()) {
			this.error = "must be in the future";
			return false;
		}
		return true;
	}
}

function IsNotPastDate_isValid() {
	if (!this.isDate(this.value)) {
		this.error = "is an invalid date";
		return false;
	} else {
		var today = new Date();
		today.setHours(0);
		today.setMinutes(0);
		today.setSeconds(0);
		today.setMilliseconds(0);
		var future = Date.parse(this.value);
		if (future.valueOf() < today.valueOf()) {
			this.error = "must be in the future";
			return false;
		}
		return true;
	}
}


function IsEmail_isValid() {

	var reg = new RegExp("^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$");
	if (!reg.test(this.value)){
		this.error = "is in an unrecognized format";
		return false;
	} else {
	
		return true;
	}


//	if ((this.value.indexOf("@") == -1) || (this.value.indexOf(".") == -1)) {
//		this.error = "is in an unrecognized format";
//		return false;
//	} else {
//		return true;
//	}
}

function IsGreaterThan_isValid() {
	if (this.isNumber()) {
		var i = parseInt(this.value);
		if (i < this.parameter) {
			this.error = "must be greater than " + this.parameter;
			return false;
		} else {
			return true;
		}
	} else {
		return false;
	}
}

function IsLessThan_isValid() {
	if (this.isNumber()) {
		var i = parseInt(this.value);
		if (i > this.parameter) {
			this.error = "must be less than " + this.parameter;
			return false;
		} else {
			return true;
		}
	} else {
		return false;
	}
}

function IsNumber_isValid() {
	if (isNaN(this.value)) {
		this.error = "must be a valid number";
		return false;
	}
	
	if (this.value.indexOf(".") != -1) {
		this.error = "cannot contain a decimal point";
		return false;
	}
	
	return true;
}

function IsFloat_isValid() {
	if (isNaN(this.value)) {
		this.error = "must be a valid number";
		return false;
	}
	
	return true;
}

function IsZip_isValid() {
	if (this.value.length==5){
		if (isNaN(this.value)){
			this.error = "is invalid";
			return false;
		}
		return true;
	}

	if (this.value.length==10) {
		//zip plus 4
		if (this.value.indexOf("-") != 5) {
			this.error = "is missing hypen";
			return false;
		}
		var n = this.value.substring(0,4) + this.value.substring(6,9);
		if (!isNaN(n)) {
			this.error = "is invalid";
			return false;
		}
		return true;
	}
	
	this.error = "be either 5 digits or zip+4 format";	
	return false;
}

function IsPosInt_isValid() {
	var reg = new RegExp("^[0-9]*$","i");
	if(!reg.test(this.value)){
		this.error = "must be all digits";
		return false;
	}
	return true;
}

function IsCVV_isValid() {
	this.parameter = 99;
	if (this.isGreaterThan()) {
		this.parameter = 1000;
		if (this.isLessThan()) {
			return true;
		}
	}
	return false;
}

function isCC_isValid() {
	if ( this.value.length > 16) {  
		this.error = "must be 15 or 16 digits";
		return false;
	}

	var sum = 0; 
	var mul = 1; 
	var len = this.value.length;
	var digit;
	var tproduct;

	for ( i = 0; i < len; i++) {
		digit = this.value.substring( len - i - 1, len - i);
		tproduct = parseInt( digit, 10) * mul;

		if( tproduct >= 10) {
			sum += ( tproduct % 10) + 1;
		} else {
			sum += tproduct;
		}

		if( mul == 1) { 
			mul++; 
		} else { 
			mul--; 
		}
	}

	if (( sum % 10) == 0) {
		 return true; 
	} else { 
		this.error = "is invalid";
		return false; 
	}
}

function isAlpha_isValid() {
	var reg = new RegExp("^[a-z]+$","i");
	if (!reg.test(this.value)){
		this.error = "must be all letters";
		return false;
	}
	return true;
}

function isRegExp_isValid(){
	var reg = new RegExp(this.parameter,"g");
	if (!reg.test(this.value)){
		this.error = "is invalid";
		return false;
	}
	return true;
}

// ***************************************************************************

isFloat.prototype.init = Data_initialize;
isFloat.prototype.getError = Data_getError;
isFloat.prototype.canUpdate = Data_canUpdate;
isFloat.prototype.isValid = IsFloat_isValid;

isNumber.prototype.init = Data_initialize;
isNumber.prototype.getError = Data_getError;
isNumber.prototype.canUpdate = Data_canUpdate;
isNumber.prototype.isValid = IsNumber_isValid;

isGreaterThan.prototype.init = Data_initialize;
isGreaterThan.prototype.getError = Data_getError;
isGreaterThan.prototype.canUpdate = Data_canUpdate;
isGreaterThan.prototype.setParameter = Data_setParameter;
isGreaterThan.prototype.isNumber = IsNumber_isValid;
isGreaterThan.prototype.isValid = IsGreaterThan_isValid;

isLessThan.prototype.init = Data_initialize;
isLessThan.prototype.getError = Data_getError;
isLessThan.prototype.canUpdate = Data_canUpdate;
isLessThan.prototype.setParameter = Data_setParameter;
isLessThan.prototype.isNumber = IsNumber_isValid;
isLessThan.prototype.isValid = IsLessThan_isValid;

isValid.prototype.init = Data_initialize;
isValid.prototype.getError = Data_getError;
isValid.prototype.canUpdate = Data_canUpdate;
isValid.prototype.isValid = Data_isValid;

isDate.prototype.init = Data_initialize;
isDate.prototype.getError = Data_getError;
isDate.prototype.canUpdate = Data_canUpdate;
isDate.prototype.isDate = Data_isDate;
isDate.prototype.isValid = IsDate_isValid;

isPastDate.prototype.init = Data_initialize;
isPastDate.prototype.getError = Data_getError;
isPastDate.prototype.canUpdate = Data_canUpdate;
isPastDate.prototype.isDate = Data_isDate;
isPastDate.prototype.isValid = IsPastDate_isValid;

isFutureDate.prototype.init = Data_initialize;
isFutureDate.prototype.getError = Data_getError;
isFutureDate.prototype.canUpdate = Data_canUpdate;
isFutureDate.prototype.isDate = Data_isDate;
isFutureDate.prototype.isValid = IsFutureDate_isValid;

isNotPastDate.prototype.init = Data_initialize;
isNotPastDate.prototype.getError = Data_getError;
isNotPastDate.prototype.canUpdate = Data_canUpdate;
isNotPastDate.prototype.isDate = Data_isDate;
isNotPastDate.prototype.isValid = IsNotPastDate_isValid;

isEmail.prototype.init = Data_initialize;
isEmail.prototype.getError = Data_getError;
isEmail.prototype.canUpdate = Data_canUpdate;
isEmail.prototype.isValid = IsEmail_isValid;

isZip.prototype.init = Data_initialize;
isZip.prototype.getError = Data_getError;
isZip.prototype.canUpdate = Data_canUpdate;
isZip.prototype.isValid = IsZip_isValid;

isPosInt.prototype.init = Data_initialize;
isPosInt.prototype.getError = Data_getError;
isPosInt.prototype.canUpdate = Data_canUpdate;
isPosInt.prototype.isValid = IsPosInt_isValid;

isCVV.prototype.init = Data_initialize;
isCVV.prototype.getError = Data_getError;
isCVV.prototype.canUpdate = Data_canUpdate;
isCVV.prototype.isValid = IsCVV_isValid;
isCVV.prototype.isNumber = IsNumber_isValid;
isCVV.prototype.isGreaterThan = IsGreaterThan_isValid;
isCVV.prototype.isLessThan = IsLessThan_isValid;

isCC.prototype.init = Data_initialize;
isCC.prototype.getError = Data_getError;
isCC.prototype.canUpdate = Data_canUpdate;
isCC.prototype.isValid = isCC_isValid;

isAlpha.prototype.init = Data_initialize;
isAlpha.prototype.getError = Data_getError;
isAlpha.prototype.canUpdate = Data_canUpdate;
isAlpha.prototype.isValid = isAlpha_isValid;

isRegExp.prototype.init = Data_initialize;
isRegExp.prototype.getError = Data_getError;
isRegExp.prototype.canUpdate = Data_canUpdate;
isRegExp.prototype.isValid = isRegExp_isValid;
isRegExp.prototype.setParameter = Data_setParameter;


