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 isEmail(v,e) {
	this.init(v,e);
}

function isZip(v,e) {
	this.init(v,e);
}

function isYN(v,e) {
	this.init(v,e);
}
function isTF(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 IsEmail_isValid() {
	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 IsYN_isValid() {
	if (this.value.length>=1){
		var val = this.value.toLowerCase( );
		val = val.substr(0,1); // get first char
		if (val=='y' || val=='n'){
			return true;
		}
	}
	this.error = "is invalid (please specify Y/N)";
	return false;
}
function IsTF_isValid() {
	if (this.value.length>=1){
		var val = this.value.toLowerCase( );
		val = val.substr(0,1); // get first char
		if (val=='t' || val=='f'){
			return true;
		}
	}
	this.error = "is invalid (please specify T/F)";
	return false;
}


// ***************************************************************************

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;

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;

isYN.prototype.init = Data_initialize;
isYN.prototype.getError = Data_getError;
isYN.prototype.canUpdate = Data_canUpdate;
isYN.prototype.isValid = IsYN_isValid;

isTF.prototype.init = Data_initialize;
isTF.prototype.getError = Data_getError;
isTF.prototype.canUpdate = Data_canUpdate;
isTF.prototype.isValid = IsTF_isValid;
