var RequiredFieldValidator = new Class({
	Implements: [Options, Events],
	
	options: {
		'classStateUnchecked':  'stateUnchecked',
		'classStateOK':         'stateOK',
		'classStateError':      'stateError',
		'classStateUnmarked':   'stateUnmarked',
		'classStatusFlag':      'statusFlag',
		'classErrorBox':        'errorBox',
		'classErrorMessage':    'error',
		'errorMessage':         'This information is required',
		'parentElement':        'li',
		'allowEmpty':		false
	},
	
	initialize: function(el, options) {
		this.el = $(el);
		this.setOptions(options);
		this.setupComponent();
	},
	
	setupComponent: function() {
		this.flag = this.el.getParent(this.options.parentElement).getElement('.' + this.options.classStatusFlag);
		
		this.el.addEvent('focus', function() {
			this.setCheckClass(this.options.classStateUnchecked);
		}.bind(this));
			
		this.el.addEvent('blur', function() {
			var value = this.el.get('value');
			
			if (!this.options.allowEmpty && (typeof(value) == "undefined" || value == 0 || value.length == 0)) {
				this.setCheckClass(this.options.classStateError);
				this.setErrorMessage(this.options.errorMessage);
			} else {
				this.validate(value);
			}
		}.bind(this));

		if (this.el.value != 0 && this.el.value.length > 0) {
			this.validate(this.el.value);
		}
	},
	
	setCheckClass: function(newClass) {	
		this.flag.removeClass(this.options.classStateUnchecked);
		this.flag.removeClass(this.options.classStateOK);
		this.flag.removeClass(this.options.classStateError);
		
		switch (newClass) {
			case this.options.classStateUnchecked: 
				this.flag.addClass(this.options.classStateUnchecked);
			break;

			case this.options.classStateError:
				this.el.addClass(this.options.classErrorBox);
				this.flag.addClass(this.options.classStateError);
			break;

			case this.options.classStateOK:
				this.flag.addClass(this.options.classStateOK);

			case this.options.classStateUnmarked:
			default:
				this.el.removeClass(this.options.classErrorBox);
				this.deleteErrorMessage();
			break;
		}
	},

	setErrorMessage: function(msg) {
		var errorElName = this.el.get('id') + 'ErrorMessage';
		var errorEl = $(errorElName);
		
		if ($defined(errorEl)) errorEl.destroy();
		
		new Element('span', { 'id': errorElName, 'html': msg, 'class': this.options.classErrorMessage }).inject(this.el.getParent('li'), 'top');
	},
	
	deleteErrorMessage: function() {
		var errMsg = $(this.el.get('id') + 'ErrorMessage');
		if ($defined(errMsg)) errMsg.destroy();
	},
	
	validate: function(value) {
		this.setCheckClass('stateOK');
	}
})

var RequiredFieldEmailValidator = new Class({
	Extends: RequiredFieldValidator,
	
	validate: function(value) {
		if (value.match(/^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i)) {
			this.setCheckClass('stateOK');
		} else {
			this.setCheckClass('stateError');
			this.setErrorMessage(this.options.errorMessage);
		}
	}
});

var RequiredFieldPasswordValidator = new Class({
	Extends: RequiredFieldValidator,
	
	validate: function(value) {
		if (value.length == 0) {
			this.setCheckClass('stateUnmarked');
		}
		else if (value.length >= this.options.minLength) {
			this.setCheckClass('stateOK');
		} else {
			this.setCheckClass('stateError');
			this.setErrorMessage(this.options.errorMessage);
		}
	}
});

var RequiredFieldMatchValidator = new Class({
	Extends: RequiredFieldValidator,
	
	validate: function(value) {
		var compare = $(this.options.matchAgainst);
		
		if (compare && compare.value.length > 0) {
			if (value == compare.value) {
				this.setCheckClass('stateOK');
			} else {
				this.setCheckClass('stateError');
				this.setErrorMessage(this.options.errorMessage);
			}
		} else {
			this.setCheckClass('stateUnmarked');
		}
	}
});