Event.observe(window, 'load', function() {
	
	if($('register_form')) {
		// focus first form element and reset form
		if(!$('errorneous'))
			Form.reset('register_form');
		else
			MAG.validateForm.apply($('register_form'));
			
		Form.focusFirstElement('register_form');
		
		// register onchange events for all input fields in the form
		var inputs = $A(Form.getInputs('register_form'));
		inputs.each(function(el) {
			Event.observe(el, 'change', MAG.validateField.bind(el, MAG.showValidationStatus));
		});
		
		Event.observe('register_form', 'submit', MAG.validateForm.bind($('register_form')));
	}
});

var MAG = Object.extend({}, MAG || {});

MAG.validateForm = function(event) {
	if(event)
		Event.stop(event);
	
	// run validations on each field
	var inputs = Form.getInputs(this);
	var hasErrors = false;
	for(var i=0; i<inputs.length; i++)
	{
		var result = MAG.validateField.apply(inputs[i], [MAG.showValidationStatus]);
		if(!result)
			hasErrors = true;
	}
	
	if(hasErrors)
	{
		// found some errors
		// show 'form not valid message'
		return false;
	}
	else
	{
		// no errors found
		// submit the form
		this.submit();
	}
	
	return false;
}

MAG.fieldStatus = {};

MAG.validateField = function(onValidated) {
	// get validators from element's className
	// should be prefixed with v-
	
	var validators = this.className.match(/\bv-[\w-]+\b/g);
	if(!validators)
		return true;
	
	for(i = 0; i < validators.length; i++) {
		var name = validators[i].substr(2);
		var parsedName = name.split('-');
		var validatorName = parsedName[0];
		var params = parsedName.slice(1);
		
		if(MAG.Validators[validatorName])
			var result = MAG.Validators[validatorName](this, params);
			
		// -1 means the result is delayed, used for ajax validation of fields, 
		// and so on
		if(!result || result == -1)
			break;
	}
	// get the locale from the className of the body
	var locale = $$('body')[0].className;
	var message = MAG.ValidationErrors[validatorName] ? MAG.ValidationErrors[validatorName][locale] : '';
	
	// execute onValidated handler
	if(onValidated)
		onValidated(this, result, message);
	
	return result;
}

MAG.showValidationStatus = function(el, status, message)
{
	$(el.parentNode).removeClassName('validation-ok');
	$(el.parentNode).removeClassName('validation-error');
	$(el.parentNode).removeClassName('validation-waiting');
	
	// assign a class to the parent <li> of the form
	if(status == true)
		$(el.parentNode).addClassName('validation-ok');
	else if(status == false)
		$(el.parentNode).addClassName('validation-error');
	else if(status == -1)
		$(el.parentNode).addClassName('validation-waiting');
	
	var messageElementId = el.id + '_message';
	
	// reset message field
	if($(messageElementId))
		$(messageElementId).update('');
	
	// show an error message if any
	if(typeof message != "undefined" && message != '' && status == false)
	{
		if(!$(messageElementId))
		{
			var html = '<span class="validation-message" id="'+messageElementId+'">'+message+'</span>';
			new Insertion.After(el, html);
		}
		else
		{
			$(messageElementId).update(message);
		}
	}
	
	MAG.fieldStatus[el.id] = status;
}

MAG.Validators = {
	/**
	 * BASIC VALIDATORS
	 */
	
	notempty: function(el)
	{
		return $F(el).match(/^\s*$/) ? false : true;
	},
	
	alnum: function(el)
	{
		return $F(el).match(/^[A-Za-zа-яА-Я0-9]+$/) ? true : false;
	},
	
	alpha: function(el)
	{
		return $F(el).match(/^[a-zA-Zа-яА-Я]+$/) ? true : false;
	},
	
	email: function(el)
	{
		var regex = /^[a-zA-Z][\w\.-_]*[a-zA-Z0-9_]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/;
		return $F(el).match(regex) ? true : false;
	},
	
	sameas: function(el, params)
	{
		// other element
		var other = $(params.shift());
		
		if(!other)
			return false;
			
		return $F(el) == $F(other);
	},
	
	/**
	 * CUSTOM VALIDATORS
	 */
	
	userExists: function(el)
	{
		var username = $F(el);
		
		// make an Ajax request to the server to check if the user exists
		var url = window.location.href.replace(/register/, 'checkuser');
		var params = 'username='+encodeURIComponent(username);
		
		new Ajax.Request(url, { method: 'post', parameters: params, onComplete: function(req, json) {
			MAG.showValidationStatus(el, json.result == "true" ? true : false, json.message || '');
		}});
		
		return -1;
	},
	
	emailExists: function(el)
	{
		var email = $F(el);
		
		// make an Ajax request to the server to check if the user exists
		var url = window.location.href.replace(/register/, 'checkmail');
		var params = 'email='+encodeURIComponent(email);
		
		new Ajax.Request(url, { method: 'post', parameters: params, onComplete: function(req, json) {
			MAG.showValidationStatus(el, json.result == "true" ? true : false, json.message || '');
		}});
		
		return -1;
	},
	
	recheck: function(el, params)
	{
		var other = $(params.shift());
		
		var result = $F(other) == $F(el);
		MAG.showValidationStatus(other, result);
		return true;
	}	
}

MAG.ValidationErrors = {
	'notempty': {
		'bg_BG': 'Това поле не може да бъде празно.',
		'en_US': 'This field cannot be left blank.'
	},
	'alnum': {
		'bg_BG': 'Това поле приема само цифри и букви.',
		'en_US': 'This field accepts only alphanumeric characters.'
	},
	'alpha': {
		'bg_BG': 'Това поле приема само букви.',
		'en_US': 'This field accepts only alphabetic characters.'
	},
	'email': {
		'bg_BG': 'Моля, въведете валиден e-mail адрес (напр. john@company.com).',
		'en_US': 'Please, enter a valid e-mail address (eg. john@company.com).'
	},
	'sameas': {
		'bg_BG': 'Написаното в двете полета не съвпада.',
		'en_US': 'The data you entered in the two fields doesn\'t match'
	}
}
