jsPackage("epoint.ow.forms")

epoint.ow.forms.ValidatorJs = {
	
	formatMessage : function (fieldValue, message, messageArgsArray) {
		var formatedMessage = message.replace('{1}', fieldValue);

		for (var i = 0; i < messageArgsArray.length; i++) {
			formatedMessage = formatedMessage.replace('{' + (i+10) + '}', messageArgsArray[i]);
		}
		return formatedMessage;
	},
	
	validatorResult : function(/*String*/ messageKey, /*array of String*/ messageParametersArray) {
		return {
			key : messageKey,
			messageParameters : messageParametersArray
		};
	},
	
	runValidator : function(/*String*/ validatorId, form, field, /*array*/ parameterArray) {
		return this.validators[validatorId].apply(this, [form, field].concat(parameterArray));
	},
	
	validators : {
		"pl.epoint.ow.forms.validators.IntegerValidator" : function (form, field, minValue, maxValue) {
				var result = this.runValidator("pl.epoint.ow.forms.validators.BigIntegerValidator", form, field, [minValue, maxValue]);
				if (result != null) {
					result.key = epoint.ow.Utils.replaceString(result.key, "BigIntegerValidator", "IntegerValidator");
				}
				return result;
		},
			
		"pl.epoint.ow.forms.validators.ConstantValueValidator" : function (form, field, constantValue) {
				var fieldValue = epoint.ow.Utils.trim(field.value);
				if (fieldValue != constantValue) {
					return this.validatorResult('ConstantValueValidator', [constantValue]);
				}
				
				return null;
		},
		
		"pl.epoint.ow.forms.validators.DecimalValidator" : function (form, field, minValue, maxValue, scale, precision, separator) {
				var fieldValue = epoint.ow.Utils.trimZeros(field.value);
				
				if (separator != ".") {
					fieldValue = epoint.ow.Utils.replaceString(fieldValue, separator, ".");
				}
				if (fieldValue.match(new RegExp('^(-?)(\\d+)(\\.?)(\\d*)$')) == null) {
					return this.validatorResult('DecimalValidator', [(precision - scale), scale]); 
				}
				
				var intPart = RegExp.$2;
				var dot = RegExp.$3;
				var fraq = RegExp.$4;
				
				if (intPart.length > (precision - scale)) {
					return this.validatorResult('DecimalValidator.PRECISION', [(precision - scale), scale]);
				}
				if (dot != "" && fraq.length > scale) {
					return this.validatorResult('DecimalValidator.SCALE', [(precision - scale), scale]);
				}
				
				if ((maxValue != null) && (epoint.ow.Utils.compare(fieldValue, maxValue) == 1)) {
					return this.validatorResult('DecimalValidator.MAX', [(precision - scale), scale, maxValue]);
				}
				if ((minValue != null) && (epoint.ow.Utils.compare(fieldValue, minValue) == -1)) {
					return this.validatorResult('DecimalValidator.MIN', [(precision - scale), scale, minValue]);
				}
				
				return null;
		},
			
		"pl.epoint.ow.forms.validators.AtMostOneValueValidator" : function (form, field) {
				var fieldValues = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
				if (fieldValues.length > 1) {
					return this.validatorResult('AtMostOneValueValidator', []);
				}
				
				return null;
		},
			
		"pl.epoint.ow.forms.validators.SingleValuePatternValidator" : function (form, field, pattern, separator) {
				var valueArray;
				if (separator != null) {
					valueArray = field.value.split(separator);
				} else {
					valueArray = new Array();
					valueArray[0] = field.value;
				}
					
				var re = new RegExp(pattern);
				
				for(var i = 0; i < valueArray.length; i++) {
					var value = epoint.ow.Utils.trim(valueArray[i]);
					
					if (!re.test(value)) {
						return this.validatorResult('SingleValuePatternValidator', [pattern, value]);
					}
				}
				
				return null;
		},
			
		"pl.epoint.ow.forms.validators.EmailValidator" : function (form, field, pattern, separator) {
				var result = this.runValidator("pl.epoint.ow.forms.validators.SingleValuePatternValidator", form, field, [pattern, separator]);
				if (result != null) {
					result.key = "EmailValidator";
				}
				return result;
		},
			
		"pl.epoint.ow.forms.validators.BigIntegerValidator" : function (form, field, minValue, maxValue) {
				var fieldValue = epoint.ow.Utils.trimZeros(field.value);
				
				var re = new RegExp('^(-?)(\\d+)$');
				if (!re.test(fieldValue)) {
					return this.validatorResult('BigIntegerValidator', []);
				}
				
				if ((minValue != null) && (epoint.ow.Utils.compare(fieldValue, minValue) == -1)) {
					return this.validatorResult('BigIntegerValidator.MIN', [minValue]);
				}
				if ((maxValue != null) && (epoint.ow.Utils.compare(fieldValue, maxValue) == 1)) {
					return this.validatorResult('BigIntegerValidator.MAX', [maxValue]);
				}
				
				return null;
		},
		
		"pl.epoint.ow.forms.validators.FilledFieldsCountValidator" : function (form, field, fieldNames, minCount, maxCount) {
				var setFieldsCount = 0;
				for(var i = 0; i < fieldNames.length; i++) {
					var values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), fieldNames[i]);
					
					if (values.length > 0) {
						setFieldsCount++;
					}
				}
				
				if (minCount != null && setFieldsCount < minCount) {
					return this.validatorResult('FilledFieldsCountValidator.MIN', [minCount]);
				}
				
				if (maxCount != null && setFieldsCount > maxCount) {
					return this.validatorResult('FilledFieldsCountValidator.MAX', [maxCount]);
				}
				
				return null;
		},
		
		"pl.epoint.ow.forms.validators.ValuesInAllowedSetValidator" : function (form, field, allowedValuesArray) {
			var values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
			
			var badValuesArray = new Array();
			
			for (var i = 0; i < values.length; i++) {
				if (epoint.ow.Utils.arraySearch(allowedValuesArray, values[i]) == -1) {
					badValuesArray[badValuesArray.length] = values[i];
				}
			}
			
			if (badValuesArray.length > 0) {
				return this.validatorResult('ValuesInAllowedSetValidator', [badValuesArray.toString(), allowedValuesArray.toString()]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.ValueRequiredValidator" : function (form, field) {
			var values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
			if (values.length == 0) {
				return this.validatorResult('ValueRequiredValidator', []);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.SingleValueLengthValidator" : function (form, field, minLength, maxLength) {
			var fieldLength = field.value.length;
			
			if (minLength != null && fieldLength < minLength) {
				return this.validatorResult('SingleValueLengthValidator.MIN', [minLength]);
			}
			
			if (maxLength != null && fieldLength > maxLength) {
				return this.validatorResult('SingleValueLengthValidator.MAX', [maxLength]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.PeselValidator" : function (form, field) {
			var WEIGHTS = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
			var fieldValue = field.value;
			
			if (fieldValue.length != 11) {
				return this.validatorResult('PeselValidator', []);
			}
		        
			var sum = 0;
			for(var i = 0; i < 10; i++) {
				var c = fieldValue.charAt(i);
				if (c < '0' || c > '9') {
					return this.validatorResult('PeselValidator', []);
				}
				
				sum += (c - '0') * WEIGHTS[i];
			}
			sum = (10 - (sum % 10)) % 10;
			if (sum != (fieldValue.charAt(10) - '0')) {
				return this.validatorResult('PeselValidator', []);
			}
			
			var year = parseInt(fieldValue.substring(0, 2), 10);
			var month = parseInt(fieldValue.substring(2, 4), 10);
			var day = parseInt(fieldValue.substring(4, 6), 10);
			
			if (month >= 0 && month < 20) {
				month -= 0;
				year += 1900;
			} else if (month >= 20 && month < 40) {
				month -= 20;
				year += 2000;
			} else if (month >= 40 && month < 60) {
				month -= 40;
				year += 2100;
			} else if (month >= 60 && month < 80) {
				month -= 60;
				year += 2200;
			} else if (month >= 80 && month < 100) {
				month -= 80;
				year += 1800;
			} else {
				return this.validatorResult('PeselValidator', []);
			}
			
			var date = new Date(year, month -1, day);
			if ((date.getFullYear() != year) || (date.getMonth() != (month - 1)) || (date.getDate() != day)) {
				return this.validatorResult('PeselValidator', []);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.PasswordValidator" : function (form, field, minLength, minNumberCount, minBigLetterCount, minSmallLetterCount) {
			var numberCount = 0;
			var bigLetterCount = 0;
			var smallLetterCount = 0;

			for (var i = 0; i < field.value.length; i++) {
				var c = field.value.charAt(i);
				
				if(c>='a' && c<='z') {
					smallLetterCount++;
				} else if(c>='A' && c<='Z') {
					bigLetterCount++;
				} else if(c>='0' && c<='9') {
					numberCount++;
				}
			}
			
		    if (field.value.length < minLength || numberCount < minNumberCount || bigLetterCount < minBigLetterCount || smallLetterCount < minSmallLetterCount) {
		    	return this.validatorResult('PasswordValidator', [minLength + "", minNumberCount + "", minBigLetterCount + "", minSmallLetterCount + ""]);
			}

			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.NipValidator" : function (form, field) {
			var WEIGHTS = [6, 5, 7, 2, 3, 4, 5, 6, 7];
			var fieldValue = field.value;
			
			var re1 = new RegExp('^\\d{3}-\\d{3}-\\d{2}-\\d{2}$');
			var re2 = new RegExp('^\\d{3}-\\d{2}-\\d{2}-\\d{3}$');
			var re3 = new RegExp('^\\d{10}$');
			if (!re1.test(fieldValue) && !re2.test(fieldValue) && !re3.test(fieldValue)) {
				return this.validatorResult('NipValidator', []);
			}
			
			var nip = fieldValue.replace(/-/g, "");
		        
			if (nip.length != 10) {
				return this.validatorResult('NipValidator', []);
			}
		        
			var sum = 0;
			for (var i = 0; i < 9; i++) {
				var c = nip.charAt(i);
				if (c < '0' || c > '9') {
					return this.validatorResult('NipValidator', []);
				}
				sum += (c - '0') * WEIGHTS[i];
			}
			sum = (sum % 11) % 10;
			if (sum != nip.charAt(9) - '0') {
				return this.validatorResult('NipValidator', []);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.ValuesNotInRestrictedSetValidator" : function (form, field, restrictedValuesArray) {
			var values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
			
			for (var i = 0; i < values.length; i++) {
				for (var j = 0; j < restrictedValuesArray.length; j++) {
					if (values[i].indexOf(restrictedValuesArray[j]) != -1) {
						return this.validatorResult('ValuesNotInRestrictedSetValidator', [restrictedValuesArray.toString()]);
					}
				}
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.HtmlTagsValidator" : function (form, field, restrictedValuesArray) {
			var result = this.runValidator("pl.epoint.ow.forms.validators.ValuesNotInRestrictedSetValidator", form, field, [restrictedValuesArray]);
			if (result != null) {
				result.key = "HtmlTagsValidator";
			}
			return result;
		},
		
		"pl.epoint.ow.forms.validators.FileExtensionValidator" : function (form, field, allowedExtensionArray) {
			var extensionIndex = field.value.lastIndexOf('.');
			var extension = "";

			if (extensionIndex > 0) {
				extension = field.value.substring(extensionIndex + 1);
			} 

			for (var i = 0; i < allowedExtensionArray.length; i++) {
				if (allowedExtensionArray[i].toUpperCase() == extension.toUpperCase()) {
					return null;
				}
			}

			return this.validatorResult('FileExtensionValidator', [allowedExtensionArray.toString()]);
		},
		
		"pl.epoint.ow.forms.validators.FieldNotEmptyIfValidator" : function (form, field, fieldIfName, reverse, fieldIfValues) {
			var currentFieldIfValues = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), fieldIfName);
			
			var valuesMatch = epoint.ow.Utils.arrayEquals(fieldIfValues, currentFieldIfValues);
			var fieldValues = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
			
			if ((!reverse == valuesMatch) && (fieldValues.length == 0)) {
				var result = this.runValidator("pl.epoint.ow.forms.validators.ValueRequiredValidator", form, field, []);
				if (result != null) {
					result.key = "FieldNotEmptyIfValidator";
				}
				return result;
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.TwoFieldIdentityValidator" : function (form, field, field2Name, field2Label) {
			var field1Values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
			var field2Values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field2Name);
			
			if(!epoint.ow.Utils.arrayEquals(field1Values, field2Values)) {
				return this.validatorResult('TwoFieldIdentityValidator', [field2Label]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.FieldOptionChoiceValidator" : function (form, field, minCount, maxCount) {
			var values = epoint.ow.Utils.getFieldValues(form.getAttribute('name'), field.getAttribute('name'));
			
			var valuesCount = values.length;
			
			if ((minCount != null) && (valuesCount < minCount)) {
				return this.validatorResult('FieldOptionChoiceValidator.MIN', [minCount + ""]);
			}
			
			if ((maxCount != null) && (valuesCount > maxCount)) {
				return this.validatorResult('FieldOptionChoiceValidator.MAX', [maxCount + ""]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.DateValidator" : function (form, field, dateFormat) {
			var date = epoint.ow.Utils.parseDate(field.value, dateFormat);
			
			if (date == null) {
				return this.validatorResult('DateValidator', [dateFormat]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.DateDifferenceValidator" : function (form, field, secondDateFieldName, secondDateFieldLabel, minString, maxString, dateFormat) {
			var date1String = field.value;
			var date2String = epoint.ow.Utils.getFieldValue(form.getAttribute('name'), secondDateFieldName);
			
			if (date2String == null) {
				date2String = "";
			}
			
			if ((date1String.length == 0) && (date2String.length == 0)) {
				return null;
			}
			
			var date1 = epoint.ow.Utils.parseDate(date1String, dateFormat);
			var date2 = epoint.ow.Utils.parseDate(date2String, dateFormat);
			
			if (date1 == null ) {
				return this.validatorResult('DateDifferenceValidator', [secondDateFieldLabel, dateFormat]);
			}
			
			if (date2 == null) {
				return this.validatorResult('DateDifferenceValidator', [secondDateFieldLabel, dateFormat]);
			}
			
			var dateDiff = Math.abs(date2.getTime() - date1.getTime()) + "";
			
			if ((minString != null) && (epoint.ow.Utils.compare(dateDiff, minString) == -1)) {
				return this.validatorResult('DateDifferenceValidator.MIN', [secondDateFieldLabel, minString]);
			}
			
			if ((maxString != null) && (epoint.ow.Utils.compare(dateDiff, maxString) == 1)) {
				return this.validatorResult('DateDifferenceValidator.MAX', [secondDateFieldLabel, maxString]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.DateInFutureValidator" : function (form, field, dateFormat) {
			var date = epoint.ow.Utils.parseDate(field.value, dateFormat);
			
			if ((date == null) || (date.getTime() <= new Date().getTime())) {
				return this.validatorResult('DateInFutureValidator', [dateFormat]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.DateValueValidator" : function (form, field, dateFormat, secondDateString, comparatorString) {
			var date1 = epoint.ow.Utils.parseDate(field.value, dateFormat);
			var date2 = epoint.ow.Utils.parseDate(secondDateString, dateFormat);
			
			if (date1 == null) {
				return this.validatorResult('DateValueValidator', [dateFormat, secondDateString, comparatorString]);
			}
			
			var dateDiff = date1.getTime() - date2.getTime();
			
			if ((comparatorString == ">") && (dateDiff <= 0)) {
				return this.validatorResult('DateValueValidator', [dateFormat, secondDateString, comparatorString]);
			}
			if ((comparatorString == ">=") && (dateDiff < 0)) {
				return this.validatorResult('DateValueValidator', [dateFormat, secondDateString, comparatorString]);
			}
			if ((comparatorString == "<=") && (dateDiff > 0)) {
				return this.validatorResult('DateValueValidator', [dateFormat, secondDateString, comparatorString]);
			}
			if ((comparatorString == "<") && (dateDiff >= 0)) {
				return this.validatorResult('DateValueValidator', [dateFormat, secondDateString, comparatorString]);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.MultifieldDateValidator" : function (form, field, fieldNames, fieldValueSeparator, dateFormat) {
			var multiValue = epoint.ow.Utils.getSingleValueMultifieldValue(form.getAttribute('name'), fieldNames, fieldValueSeparator);
			var date = epoint.ow.Utils.parseDate(multiValue, dateFormat);
			
			if (date == null) {
				return this.validatorResult('MultifieldDateValidator', []);
			}
			
			return null;
		},
		
		"pl.epoint.ow.forms.validators.MultifieldDateInFutureValidator" : function (form, field, fieldNames, fieldValueSeparator, dateFormat) {
			var multiValue = epoint.ow.Utils.getSingleValueMultifieldValue(form.getAttribute('name'), fieldNames, fieldValueSeparator);
			var date = epoint.ow.Utils.parseDate(multiValue, dateFormat);
			
			if ((date == null) || (date.getTime() <= new Date().getTime())) {
				return this.validatorResult('MultifieldDateInFutureValidator', []);
			}
			
			return null;
		},
		
		"pl.epoint.aol.war.common.forms.validators.OrderedDatesValidator" : function (form, field, dateFormat, secondDateName) {
			var field2 = form[secondDateName];
			
			if (field.value == '' || field2.value == '') {
				return null;
			}
	        var date1 = epoint.ow.Utils.parseDate(field.value, dateFormat);
	        var date2 = epoint.ow.Utils.parseDate(field2.value, dateFormat);
			
	        if (date2 == null || date1 < date2) {
		        return null;
	        } else {
	        	return this.validatorResult('OrderedDatesValidator', []);
	        }
		}

	},
	
	formValidatorConfigs : {},
	
	addValidator : function(validatorId, validatorFn) {
		this.validators[validatorId] = validatorFn;
	},
	
	addValidatorConfig : function(formName, config) {
		this.formValidatorConfigs[formName] = config;
	},
	
	getFieldValidators : function(formName, fieldName) {
		var formConfig = this.formValidatorConfigs[formName];
		if (formConfig == null) {
			return new Array();
		}
		var fieldConfig = formConfig[fieldName];
		if (fieldConfig == null) {
			return new Array();
		}
		return fieldConfig;
	},

	validateForm : function(formName) {
		var form = document.forms[formName];
		
		for (var i = 0; i < form.elements.length; i++) {
			var field = form.elements[i];
			if (field.disabled) {
				continue;
			}
			
			var fieldValidatorConfigList = this.getFieldValidators(formName, field.getAttribute('name'));
			for(var j = 0; j < fieldValidatorConfigList.length; j++) {
				var validatorId = fieldValidatorConfigList[j][0];
				var runIfNoValue = fieldValidatorConfigList[j][1];
				var messageKeys = fieldValidatorConfigList[j][2];
				var parameters = fieldValidatorConfigList[j][3];
				var fieldValue = epoint.ow.Utils.getFieldValue(form.getAttribute('name'), field.getAttribute('name'));
			
				if (fieldValue == null) {
					if (runIfNoValue == false) {
						continue;
					}
				}
				
				var result = this.runValidator(validatorId, form, field, parameters);
				if (result != null) {
					var msg = messageKeys[result.key];
					if (msg == null) {
						msg = result.key;
					} else {
						msg = this.formatMessage(fieldValue, msg, result.messageParameters);
					}
					
					alert(msg);
					field.focus();
					return false;
				}
			}
			
		}
		
		return true;
	},
	
	submitForm : function (formName, action, jsValidation) {
		if (jsValidation == null || jsValidation == true) {
			if (this.validateForm(formName) == false) {
				return false;
			}
		}
		
		var form = document.forms[formName];
		if (action != null && action != "") {
			form.action = action;
		}
		form.submit();
	}
}

