/**
 *	@arthor Vladimir Shushkov
 *	@use jQuery
 */

if (typeof console === 'undefined') {
	console = {}; console.log = console.error = console.debug = function(obj) {alert(obj);return true;};
}

if (typeof cm === 'undefined') {
	var cm = {};
}

cm.Validate = function(form, fields) {

	var validators = [];
	$.each(fields, function(i, data) {
		var field = $('#'+ data.id);
		var group = new cm.Validator(field);
		$.each(data.validate, function(i, validator) {
			if (!validator.opt) {
				validator.opt = {};
			}
			validator.opt.field = field;
			group.add(eval('new '+ validator.ns +'(validator.opt)'));
		});
		validators.push(group);
		field.blur(function() {
			group.validate();
		});
	});

	form.bind('submit', function(event) {
		var result = true;
		$.each(validators, function(i, validator) {
			var isValid = validator.validate();
			if (result) {
				validator.getField().focus();
			}
			if (!isValid) {
				result = false;
			}
		});
		if (!result) {
			event.preventDefault();
			$(this).addClass('f-with-error');
		} else {
			$(this).removeClass('f-with-error');
		}
	});
};

cm.Validator = function(field) {
	var options = {
		showMessage: function(message) {
			field.parents('.f-field').addClass('f-field-error')
				.append('<div class="error-box">'+ message +'</div>');
		},
		removeMessage: function() {
			field.parents('.f-field').removeClass('f-field-error')
				.children('.error-box').remove();
		}
	};

	var validators = [];

	this.add = function(validator) {
		validators.push(validator);
	}

	this.validate = function() {
		for (var i = 0, l = validators.length; i < l; i++) {
			var result = validators[i].validate(field.val());
			if (result.message || !result) {
				options.removeMessage();
				options.showMessage(result.message);
				return false;
			} else {
				options.removeMessage();
			}
		}
		return true;
	};

	this.getField = function() {
		return field;
	};

};

cm.Validator.NonEmpty = function(options){

	this.validate = function(value) {

		if (options && options.ifEmpty && options.ifEmpty.value) {
			return true;
		}

		if (options && options.ifEqual && options.ifEqual.element && options.ifEqual.compare) {
			if (options.ifEqual.element.value != options.ifEqual.compare) {
				return true;
			}
		}

		if (value.toString().length == 0) {
			return {
				message: 'поле должно быть заполнено'
			};
		}
		return true;
	};

};

cm.Validator.IsEmail = function() {

	this.validate = function(value) {

		if (value.toString().length == 0) {
			return true;
		}
		
		if (!(/^[A-Za-z0-9\.\-_]+@[A-Za-z0-9\.\-_]+\.[A-Za-z0-9]{2,5}$/.test(value))) {
			return {
				message: 'неверный формат эл. почты'
			}
		}
		return true;
	};

};

cm.Validator.IsNumber = function() {
	this.validate = function(value) {
		if (value.toString().length == 0) {
			return true;
		}
		if (!((typeof(value) === 'number' || (typeof(value) === 'string')) && !isNaN(value))) {
			return {
				message: 'значение не является числом'
			}
		}
		return true;
	};
};

cm.Validator.Min = function(options) {
	this.validate = function(value) {
		if (value.toString().length == 0) {
			return true;
		}
		var compare = parseFloat(options.compare) || 1;
		if (value < compare) {
			return {
				message: options.message || 'не менее ' + compare
			}
		}
		return true;
	};
};

cm.Validator.Max = function(options) {
	this.validate = function(value) {
		if (value.toString().length == 0) {
			return true;
		}
		var compare = parseFloat(options.compare) || 1;
		if (value > compare) {
			return {
				message: options.message || 'не более ' + compare
			}
		}
		return true;
	};
};

cm.Validator.RegExp = function(options) {

	this.validate = function(value) {

		if (value.toString().length == 0) {
			return true;
		}

		var regexp = new RegExp(options.pattern);

		if (!regexp.test(value)) {
			return {
				message: 'неверный формат'
			}
		}
		return true;
	};

};

cm.Validator.CaptchaVerify = function(options) {

	this.validate = function(value) {

		if (options.field.get(0).verified === true) {
			return true;
		}

		if (!value) {
			return false;
		}

		var url = (options.url || '') +'call~'+ options.tag +'?isValidCode='+ value;
		var img = options.field.parents('.f-control').find('img').get(0);

		$.ajax({ url: url, async: false, success: function(response) {
			if ((options.field.get(0).verified = (response == 'true')) === false) {
				img.src = img.src +'?'+ Math.random();
			}
		}});
		
		return options.field.get(0).verified;
	};
	
};

var initFormValidators = function(container) {
	$(container || document).find('form.f-form').each(function(i, form) {
		if (typeof form.onclick === 'function') {
			var data = form.onclick();
			form.onclick = null;
			new cm.Validate($(form), data.validators);
		}
	});
};

$(function() {
	initFormValidators();
});
