/**
* JS Form-Validator.
* Handles empty values or given regEx
* @author Alex <schulte@wysiwyg.de>
* @since 20.08.2008
* @version 0.1a
* tested in FF 3, IE7, Win Safari 3
*
* e.g.
*
* var formChecker = new FormValidator($('register'), {
*			errorClass: 'error'
*		});
*/
var FormValidator = new Class({
	getOptions: function(){
		return {
			errorClass: 'error',		// CSS-Class Name on Error
			requiredClass: 'required',	// CSS-Class for required fields
			keyEvent: 'keyup',			// Key-Event to handle User-Input
			checkOnStart: true,			// check the form onDomReady
			keywords: false,			// add CSS-Keywords for validation (Not implementet yet) 
			regex: false 				// add regex for added keywords (Not implementet yet)
		};
	},
	initialize: function(form, options) {
		// Break if Form isn't present
		if (!$chk(form)) return;
		this.setOptions(this.getOptions(), options);
		
		this.form = form;
		this.elements = $$(form.getElements('.' + this.options.requiredClass));
		this.errors = false;
		
		this.keywords = ['date-y', 'date-m', 'date-d', 'date-y-m-d', 'date-d.m.y', 'email', 'numeric', 'string'];
		this.checkRegEx = [	/[19|20][0-9]{3}/, // Year
							/0[1-9]|(1?[1-2]){2}|10/, // Month
							/0[1-9]|[1-2][0-9]|3[0-1]/, // Day
							/([19|20][0-9]{3})-(0[1-9]|(1?[1-2]){2}|10)-(0[1-9]|[1-2][0-9]|3[0-1])/, // Date Y-m-d
							/(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|(1?[1-2]){2}|10)\.([19|20][0-9]{3})/, // Date d.m.Y
							/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})$/, // E-Mail
							/^[0-9]*$/, // numeric
							/^[^\d(#+,@|)]*$/, // string
						  ];
		
		this.validateForm(false);
	},
	validateForm: function(autoTrigger) {
		this.elements.each(function(element,index) {
			
			value = element.get('value');
			if (element.get('type') == 'checkbox' || element.get('type') == 'radio') {
				value = element.getProperty('checked') == true;
			}
			
			if (this.options.checkOnStart || autoTrigger) {

				if (!value) {
					element.addClass(this.options.errorClass);
					this.errors = true;
				}
				else {
					element.removeClass(this.options.errorClass);
				}

				if ( element.get('type') == 'checkbox' && element.getProperty('checked') == false ) {
					element.getParent().addClass(this.options.errorClass);
				}
			}

			if (element.get('type') == 'checkbox' || element.get('type') == 'radio') {
				element.addEvent('click', function(e){
					element.getParent().addClass(this.options.errorClass);
					if (element.getProperty('checked') == true) {
						element.getParent().removeClass(this.options.errorClass);
					}
				}.bind(this));
			};
			
			if (this.options.keyEvent) {
				element.addEvent(this.options.keyEvent, function(e){

					elemClass = element.get('class').replace(/error/, '').replace(/required/, '');
					pieces = elemClass.split(' ');
					
					pieces.each(function(cssClass){
						if ( this.keywords.contains(cssClass) ) {
							i = this.keywords.indexOf(cssClass);
							regex = this.checkRegEx[i];
							
							if( regex && (regex.test(element.get('value')) == true) ) {
								element.removeClass(this.options.errorClass);
							}
							else if( regex && (regex.test(element.get('value')) == false) ) {
								element.addClass(this.options.errorClass);
							}
							
							if(element.get('value') == '') {
								element.addClass(this.options.errorClass);
							}
							
							if ( element.get('type') == 'checkbox' && element.getProperty('checked') == false ) {
								element.getParent().addClass(this.options.errorClass);
							}
						}
					}.bind(this));
	
					if ( this.hasErrors() ) {
						if ($('submit')) {
							$('submit').addProperty('onClick', 'return false;');
						}

						this.form.addEvent('submit', function(e){
							new Event(e).stop();
						});
					}
				}.bind(this));
			}
			
		}.bind(this));
	},
	hasErrors: function() {
		errors = $$(this.form.getElements('.' + this.options.errorClass));
		
		return errors.length > 0;
	},
	getErrors: function() {
		errors = $$(this.form.getElements('.' + this.options.errorClass));
		
		return errors;
	}
});

FormValidator.implement(new Options);
FormValidator.implement(new Events);