var ValidatorFactory = {
	validators: {},
	messages: {
		required: "${field.title} can not be blank."
	},
	_paramStringRegexp: /\$\{(.*?)\}/,
	getMessage: function(container, key, field, params, special) {
		var m = container.messages ? container.messages[key] : null;
		if (!m) {
			return this.messages[key] ? this.getMessage(this, key, field, params, special) : null;
		}
		if (typeof(m) == "string") {
			while (this._paramStringRegexp.test(m)) {
				m = RegExp.leftContext + "\" + " + RegExp.$1 + " + \"" + RegExp.rightContext;
			}
			eval("m = function(field, params, special) {return \"" + m + "\"}");
			container.messages[key] = m;
		}
		return m(field, params, special);
	},
	register: function(validator) {
		this.validators[validator.name] = validator;
	},
	validate: function(field, type, params) {
		//alert(field.name + " - " + field.value + " - " + type + " - " + params.required);
		if (params.depends) {
			if (typeof(params.depends) == "string") {
				var d = params.depends;
				while (this._paramStringRegexp.test(d)) {
					d = RegExp.leftContext + "field.form.fields[\"" + RegExp.$1 + "\"].getValue()" + RegExp.rightContext;
				}
				eval("params.depends = function(field) {return " + d + "}");
			}
			if (!params.depends(field)) {
				return null;
			}
		}
		var validator = this.validators[type];
		if (StringUtils.isEmpty(field.value)) {
			if (params.required) {
				return this.getMessage(this, "required", field);
			} else if (!validator || !validator.checkEmptyNonRequired) {
				return null;
			}
		}
		return (validator && validator.validate) ? validator.validate(field, params) : null;
	}
};

ValidatorFactory.register({
	name: "Complex",
	checkEmptyNonRequired: true,
	validate: function(field, params) {
		if (params.allOf) {
			for (var i = 0; i < params.allOf.length; i++) {
				var m = ValidatorFactory.validate(field, params.allOf[i].type, params.allOf[i].params);
				if (m) {
					return m;
				}
			}
		}
		if (params.anyOf) {
			var message = null;
			for (var i = 0; i < params.anyOf.length; i++) {
				var m = ValidatorFactory.validate(field, params.anyOf[i].type, params.anyOf[i].params);
				if (!m) {
					return m;
				} else if (!message) {
					message = m;
				}
			}
			return message;
		}
	}
});

ValidatorFactory.register({
	name: "Text",
	messages: {
		Text$min: "${field.title} can not be less than ${params.min} chars.",
		Text$max: "${field.title} can not be more than ${params.max} chars.",
		Text$except: "${field.title} should not contain char '${special}'.",
		Text$regexp: "${field.title} should match regular expression ${params.regexp}."
	},
	validate: function(field, params) {
		if (params.min && field.value.length < params.min) {
			return ValidatorFactory.getMessage(this, "Text$min", field, params);
		}
		if (params.max && field.value.length > params.max) {
			return ValidatorFactory.getMessage(this, "Text$max", field, params);
		}
		if (params.except) {
			for (var i = 0; i < params.except.length; i++) {
				var c = params.except.charAt(i);
				if (field.value.indexOf(c) > 0) {
					return ValidatorFactory.getMessage(this, "Text$except", field, params, c);
				}
			}
		}
		if (params.regexp && !params.regexp.test(field.value)) {
			return ValidatorFactory.getMessage(this, "Text$regexp", field, params);
		}
	}
});

ValidatorFactory.register({
	name: "Int",
	messages: {
		Int: "${field.title} should be a valid integer number.",
		Int$min: "${field.title} can not be less than ${params.min}.",
		Int$max: "${field.title} can not be more than ${params.max}."
	},
	_intRegexp: /^-?\d+$/,
	validate: function(field, params) {
		if (!this._intRegexp.test(field.value)) {
			return ValidatorFactory.getMessage(this, "Int", field);
		}
		field.value = new Number(field.value);
		if (params.min && field.value < params.min) {
			return ValidatorFactory.getMessage(this, "Int$min", field, params);
		}
		if (params.max && field.value > params.max) {
			return ValidatorFactory.getMessage(this, "Int$max", field, params);
		}
		//field.formattedValue = field.value.toString();
	}
});

ValidatorFactory.register({
	name: "Email",
	messages: {
		Email: "${field.title} should contain a correct email address."
	},
	_emailRegexp: /^\w+([-+\.]\w+)*@\w+([-\.]\w+)*\.\w+$/,
	validate: function(field, params) {
		if (!this._emailRegexp.test(field.value)) {
			return ValidatorFactory.getMessage(this, "Email", field);
		}
	}
});
/*
ValidatorFactory.register({
	name: "Enum",
	messages: {
		Enum: "${field.title} contains incorrect value."
	},
	validate: function(field, params) {
		for (var i = 0; i < params.values.length; i++) {
			if (params.values[i] == field.value) {
				return null;
			}
		}
		return ValidatorFactory.getMessage(this, "Enum", field);
	}
});
*/


