dojo.require("dojo.validate");
dojo.require("dojo.validate.check");
dojo.require("dojo.validate.datetime");
dojo.require("dojo.validate.de");
dojo.require("dojo.validate.jp");
dojo.require("dojo.validate.us");
dojo.require("dojo.validate.web");

var validationError = false;

//Validate Initiali
function validateInit() {
	validationError = false;
}

//Return the Validation Result
function validationResult() {
	return validationError;
}

//isChecked
function isChecked (obj) {
	return (obj!=null && obj.checked);
}

//Return true if the obj is null, undefined or empty
function isObjEmpty (obj) {
	return (obj==null || obj==undefined || !obj.value);
}

//Show Error Message
function showErrorMessage (fieldId, errMessageId) {
	//Show error message
	var objErr = dojo.byId(errMessageId);
	if (objErr)
		objErr.style.display="block";
	
	//Change label color/class
	var label = dojo.byId(fieldId+'_Label');
	if (label!=null)
		dojo.html.addClass (label, 'alert');		
	
	//Change input field color/class
	var input = dojo.byId(fieldId);
	if (input!=null)
		dojo.html.addClass (input, 'inputAlert');	
		
	//Set error	
	validationError = true;
}

//Hide Error Message
function hideErrorMessage (fieldId, errMessageId, errRequiredMsgId) {
	//Hide error message
	var objErr = dojo.byId(errMessageId);
	if (objErr)
		objErr.style.display="none";

	if (errMessageId != errRequiredMsgId) {
		//Hide required error message
		var objReqErr = dojo.byId(errRequiredMsgId);
		if (objReqErr)
			objReqErr.style.display="none";
	}
	
	//Restore label color/class
	var label = dojo.byId(fieldId+'_Label');
	if (label!=null)
		dojo.html.removeClass (label, 'alert');		

	//Restore input field color/class
	var input = dojo.byId(fieldId);
	if (input!=null)
		dojo.html.removeClass (input, 'inputAlert');		
}

//Validate checkbox
function validateCheckBox (fieldId, errMessageId, conditionalError) {
	if( conditionalError ) {
		showErrorMessage (fieldId, errMessageId);
		return false;
	}else{
		hideErrorMessage (fieldId, errMessageId);
		return true;
	}
}

//Validate Required Field
function validateRequiredField (fieldId, errMessageId, errRequiredMsgId) {	
	obj = dojo.byId(fieldId);
	if ( obj==null || (obj!=null && !obj.value) ) {
		showErrorMessage (fieldId, errMessageId);
		return false;
	}else{
		hideErrorMessage (fieldId, errMessageId, errRequiredMsgId);
		return true;
	}
}

//Validate Field with a specific conditional error
function validateField(fieldId, errMessageId, required, errRequiredMsgId, conditionalError) {
	obj = dojo.byId(fieldId);
	
	if ( required && isObjEmpty(obj)) {
		//Show error message indicating a required field
		showErrorMessage (fieldId, errRequiredMsgId);
		return false;
	} else if ( required && conditionalError) {
		//Hide posible previuos error message
		hideErrorMessage (fieldId, errMessageId, errRequiredMsgId);
		
		//Show error message
		showErrorMessage (fieldId, errMessageId);
		return false;
	} else if ( !required && ( !isObjEmpty(obj) && conditionalError) ) {
		//Show error message for an optional field
		showErrorMessage (fieldId, errMessageId);
		return false;
	} else {
		hideErrorMessage (fieldId, errMessageId, errRequiredMsgId);
		return true;
	}
}

//Validate Email Address
function validateEmailAddress (fieldId, errMessageId, required, errRequiredMsgId) {
	obj = dojo.byId(fieldId);
	
	var conditionalError = ( isObjEmpty(obj) || !dojo.validate.isEmailAddress(obj.value));
	
	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError );
}

//Validate Phone Number
function validatePhoneNumber (fieldId, errMessageId, required, errRequiredMsgId) {	
	obj = dojo.byId(fieldId);

	var conditionalError = ( isObjEmpty(obj) || !dojo.validate.us.isPhoneNumber(obj.value));

	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError );
}

//Validate Zip
function validateZip (fieldId, errMessageId, required, errRequiredMsgId) {	
	obj = dojo.byId(fieldId);

	var conditionalError = ( isObjEmpty(obj) || !dojo.validate.us.isZipCode(obj.value));

	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError );
}

//Validate Date
function validateDate (fieldId, errMessageId, required, errRequiredMsgId) {	
	obj = dojo.byId(fieldId);

	var conditionalError = ( isObjEmpty(obj) || !dojo.validate.isValidDate(obj.value));

	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError );
}

//Validate Max Characteres
function validateMaxCharacters (fieldId,errMessageId, required, errRequiredMsgId, maxCharacters) {
	obj = dojo.byId(fieldId);

	var conditionalError = ( isObjEmpty(obj) || obj.value.length > maxCharacters );

	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError );
}

//Validate User Id Field
function validateUserIdField (fieldId, errMessageId, errRequiredMsgId) {	
	obj = dojo.byId(fieldId);
	if ( obj==null || (obj!=null && !obj.value) || (obj!=null && obj.value.length < 6)) {
		showErrorMessage (fieldId, errMessageId);
		return false;
	}else{
		hideErrorMessage (fieldId, errMessageId, errRequiredMsgId);
		return true;
	}
}

/* 
 Validate password
 More Info: http://blog.stevenlevithan.com/archives/javascript-password-validator
 
	// default options (allows any password)
	var o = {
		lower:    0,
		upper:    0,
		alpha:    0, // lower + upper
		numeric:  0,
		special:  0,
		length:   [0, Infinity],
		custom:   [ ],
		badWords: [],
		badSequenceLength: 0,
		noQwertySequences: false,
		noSequential:      false
	};
 
	Use Example :
	var passed = validatePassword(password, {
		length:   [8, Infinity],
		lower:    1,
		upper:    1,
		alpha:    1, 
		numeric:  1,
		special:  1,
		badWords: ["password", "steven", "levithan"],
		badSequenceLength: 4
	});

 */
function validatePasswordField (fieldId, errMessageId, required, errRequiredMsgId, options ) {	
	obj = dojo.byId(fieldId);
	var conditionalError = ( isObjEmpty(obj) || !validatePassword (obj.value, options) );

	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError );
}

//Validate password match
function validatePasswordMatch (fieldId1, fieldId2, required, errRequiredMsgId) {
		 
	var obj1 = dojo.byId(fieldId1);
	var obj2 = dojo.byId(fieldId2);
	var conditionalError = ( isObjEmpty(obj1)  || isObjEmpty(obj1)  || obj1.value!=obj2.value );
	if (!required)
		required = !(isObjEmpty(obj1) && isObjEmpty(obj1)); //if one on the password field has a value, the validation is required

	return validateField (fieldId2, errRequiredMsgId, required, errRequiredMsgId, conditionalError );
}
//Validate two fields
function validateFieldsMatch (fieldId1, fieldId2, required, errRequiredMsgId) {
		 
	var obj1 = dojo.byId(fieldId1);
	var obj2 = dojo.byId(fieldId2);
	var conditionalError = ( isObjEmpty(obj1)  || isObjEmpty(obj1)  || obj1.value!=obj2.value );
	if (!required)
		required = !(isObjEmpty(obj1) && isObjEmpty(obj1)); //if one of the field has a value, the validation is required

	return validateField (fieldId2, errRequiredMsgId, required, errRequiredMsgId, conditionalError );
}


/* 
 Validate password
 More Info: http://blog.stevenlevithan.com/archives/javascript-password-validator
 
	Use Example :
	var passed = validatePassword(password, {
		length:   [8, Infinity],
		lower:    1,
		upper:    1,
		numeric:  1,
		special:  1,
		badWords: ["password", "steven", "levithan"],
		badSequenceLength: 4
	});
 */
function validatePassword (pw, options) {
	// default options (allows any password)
	var o = {
		lower:    0,
		upper:    0,
		alpha:    0, /* lower + upper */
		numeric:  0,
		special:  0,
		length:   [0, Infinity],
		custom:   [ /* regexes and/or functions */ ],
		badWords: [],
		badSequenceLength: 0,
		noQwertySequences: false,
		noSequential:      false
	};

	for (var property in options)
		o[property] = options[property];

	var	re = {
			lower:   /[a-z]/g,
			upper:   /[A-Z]/g,
			alpha:   /[A-Z]/gi,
			numeric: /[0-9]/g,
			special: /[\W_]/g
		},
		rule, i;

	// enforce min/max length
	if (pw.length < o.length[0] || pw.length > o.length[1])
		return false;

	// enforce lower/upper/alpha/numeric/special rules
	for (rule in re) {
		if ((pw.match(re[rule]) || []).length < o[rule])
			return false;
	}

	// enforce word ban (case insensitive)
	for (i = 0; i < o.badWords.length; i++) {
		if (pw.toLowerCase().indexOf(o.badWords[i].toLowerCase()) > -1)
			return false;
	}

	// enforce the no sequential, identical characters rule
	if (o.noSequential && /([\S\s])\1/.test(pw))
		return false;

	// enforce alphanumeric/qwerty sequence ban rules
	if (o.badSequenceLength) {
		var	lower   = "abcdefghijklmnopqrstuvwxyz",
			upper   = lower.toUpperCase(),
			numbers = "0123456789",
			qwerty  = "qwertyuiopasdfghjklzxcvbnm",
			start   = o.badSequenceLength - 1,
			seq     = "_" + pw.slice(0, start);
		for (i = start; i < pw.length; i++) {
			seq = seq.slice(1) + pw.charAt(i);
			if (
				lower.indexOf(seq)   > -1 ||
				upper.indexOf(seq)   > -1 ||
				numbers.indexOf(seq) > -1 ||
				(o.noQwertySequences && qwerty.indexOf(seq) > -1)
			) {
				return false;
			}
		}
	}

	// enforce custom regex/function rules
	for (i = 0; i < o.custom.length; i++) {
		rule = o.custom[i];
		if (rule instanceof RegExp) {
			if (!rule.test(pw))
				return false;
		} else if (rule instanceof Function) {
			if (!rule(pw))
				return false;
		}
	}

	// great success!
	return true;
}

// This function detects a PO box in an address form. It is no longer used but may be useful at a future time.
function validateAddress(fieldId, errMessageId, required, errRequiredMsgId) {	
	obj = dojo.byId(fieldId);

	// Regular expression to check for a P.O. Box address
	var re = /p{1,1}(.| ){0,}o{1,1}(.| ){0,}(box){0,}/i;
		
	var conditionalError = ( isObjEmpty(obj) || re.test(obj.value) );
	conditionalError = false;

	return validateField (fieldId, errMessageId, required, errRequiredMsgId, conditionalError);
}
