Solveo.Validators = function(control) {
	this.control = control;
	if (this.control.validators) return; 
	
	// find parent row
	var parent = Solveo.Element.get(this.control);
	try {
		while (parent && !parent.hasClass('form-row')) {
			parent = parent.parent();
		}
		//if (!parent) return;		
	} catch (e) {
		parent = null;
	}
	if (!parent) return;
	
	// find parent form 
	var form = this.control;
	while (form && typeof(form.tagName) == 'string' && form.tagName != 'FORM') 
		form = form.parentNode;
	if (!form || form.tagName != 'FORM') return;
	

	this.validators = new Array;
	this.parent = parent;
	this.control.validators = this;
	this.errorIcon = Solveo.Element.get(control.id+'-error');
	
	this.form = form;
	if (!form.validators) form.validators = new Array;
	form.validators[form.validators.length] = this;
	
	// create hook
	if (this.control.type == 'radio' || this.control.type == 'checkbox')
		this.control.onclick = this.validate.createDelegate(this);
	else
		this.control.onchange = this.validate.createDelegate(this);
}

Solveo.Validators.prototype = {
	 errorMessage: 'Niepoprawna wartość pola'
	,trimValue: function(s) {
		var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
		return (m == null) ? '' : m[1];
	}
	,getValue: function() {
		var control = arguments[0] || this.control;
		if (control.type == 'checkbox') {
			return control.checked;
		}
		else if (typeof(control.value) == 'string') {
			return this.trimValue(control.value);
		}
		var i, val = '';
		for (i = 0; i < control.childNodes.length; i++) {
			val = this.trimValue(this.getValue(control.childNodes[i]));
			if (val != '') return val;
		}
		return '';
	}	
	,add: function(validator){
		this.validators[this.validators.length] = validator;
	}
	,isValid: function(leaveInvalidMsg) {
		var i, v = this.getValue();
		var result = {
			 isValid: true
			,msg: ''
		}
		
		for (i = 0; i < this.validators.length; i++) {
			this.validators[i].validate(v, result);
			if (!result.isValid) {
				
				if (this.parent) {
					this.errorIcon.dom.innerHTML = '';
					this.parent.removeClass('form-error');
					this.errorIcon.removeClass('form-error-active');
				}

				if (this.parent) {
					var msg = document.createElement('div');
					msg.className = 'form-error-icon';
					msg.innerHTML = (result.msg != '') ? result.msg : this.errorMessage;
					this.errorIcon.addClass('form-error-active');
					this.errorIcon.dom.appendChild(msg);
					this.parent.addClass('form-error');
				}
				else {
					var msg = (result.msg != '') ? result.msg : this.errorMessage;
					alert(msg);
				}
				return false;
			}
		}
		
		if (this.parent && !leaveInvalidMsg) {
			this.errorIcon.dom.innerHTML = '';
			this.parent.removeClass('form-error');
			this.errorIcon.removeClass('form-error-active');
		}
		
		return true;
	}
	,validate: function() {
		this.isValid();
	}
}

Solveo.Validators.validateForm = function(form) {
	var i, isValid = true;
	for (i = 0; i < form.validators.length; i++)
	{
		if (!form.validators[i].isValid(true)) isValid = false;
	}
	return isValid;
}

Solveo.Validator = function(control, config){
	this.control = typeof control == 'string' ? document.getElementById(control) : control;
	if (!this.control) return;
	
	Solveo.apply(this, config);
	this.hookupControl(this.control);
}

Solveo.Validator.prototype = {
		
	 hookupControl: function(control) {
		var c = control || this.control;
		if (typeof(c.tagName) != 'string') return;  
		
		if (c.tagName != 'INPUT' && c.tagName != 'TEXTAREA' && c.tagName != 'SELECT') {
			for (var i = 0; i < c.childNodes.length; i++) {
				this.hookupControl(c.childNodes[i]);
			}
		}
		else {
			if (!c.validators){
				new Solveo.Validators(c);
			}
			c.validators.add(this);
		}
	}
	,validate: function(value, args) {
		args.isValid = true;
	}
}

Solveo.Validator.NotEmpty = Solveo.extend(Solveo.Validator, {
	
	errorMessage: 'Pole wymagane'  
	
	,validate: function(value, args) {
		if (value == '') {
			args.isValid = false;
			args.msg = this.errorMessage;
		}
	}
});


Solveo.Validator.StringLength = Solveo.extend(Solveo.Validator, {
	
	 validate: function(value, args) {
		var len = value.length;
		if (this.min && len < this.min) {
			args.isValid = false;
			args.msg = 'Za mało znaków';
		}
		else if (this.max && len > this.max) {
			args.isValid = false;
			args.msg = 'Za dużo znaków';
		}
	}
});

Solveo.Validator.ValidLogin = Solveo.extend(Solveo.Validator, {
	
	errorMessage: "'%value%' jest niepoprawnym loginem. Podany login zawiera niedozwolone znaki."  
	,fistCharMessage: "'%value%' jest niepoprawnym loginem. Pierwszym znakiem loginu musi być litera."
	
	,validate: function(value, args) {
		if (!value.match(/^[a-z]/i)) {
			args.isValid = false;
			args.msg = this.fistCharMessage.replace(/%value%/, value);
		}
		else if (!value.match(/^[a-z][a-z0-9\-]*$/i)) {
			args.isValid = false;
			args.msg = this.errorMessage.replace(/%value%/, value);
		}
	}
});

Solveo.Validator.Email = Solveo.extend(Solveo.Validator, {
	 errorMessage: "'%value%' nie jest poprawnym adresem e-mail."  
	
	,validate: function(value, args) {
		var reg = /^[^\@]+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,6})$/;
		if (!value.match(reg)) {
			args.isValid = false;
			args.msg = this.errorMessage.replace(/%value%/, value);
		}
	}
});

Solveo.Validator.RequiredCheckBox = Solveo.extend(Solveo.Validator, {
	 errorMessage: "Musisz zaakceptować postanowienia regulaminu."  
	
	,validate: function(value, args) {
		if (!value) {
			args.isValid = false;
			args.msg = this.errorMessage;			
		}
	}
});