// FISFormValidator Version 0.91
// FISolution 
// 8. Januar 2010 20:16:56
// Uses mootools-1.2.4.js
// and mootools-1.2.4.2.more.js
 
var setValidationError = function(upload_id, valid_id) {
	$$('form').each(function(form) {
		if(form.uploadId && form.uploadId == upload_id) {
			for(var h = 0; h < form.FISFV.fields.length; h++) {
				var field = form.FISFV.fields[h];
				for(var i = 0; i < field.validations.length; i++) {
					for(var j = 0; j < field.validations[i].length; j++) {
						if(field.validations[i][j].id == valid_id) {
							field.validations[i][j].showError(false);
							return;
						}
					}
				}
			}
			return;
		}
	});
}
var resetErrorMessages = function(upload_id) {
	$$('form').each(function(form) {
		if(form.uploadId && form.uploadId == upload_id) {
			var errorField = $(form.id + '_errorfield');
			if(!errorField) return;
			var ul = errorField.getChildren('ul')[0];
			ul.getChildren().each(function(c) { c.dispose(); });
			errorField.setStyle('display', 'none');			
		}
	});
}

var setErrorMessage = function(upload_id, message) {
	$$('form').each(function(form) {
		if(form.uploadId && form.uploadId == upload_id) {
			var errorField = $(form.id + '_errorfield');
			if(!errorField) alert(message);
			errorField.setStyle('display', 'block');
			var ul = errorField.getChildren('ul')[0];
			new Element('li').set('html', message).inject(ul);
		}
		return;
	});
}


var FISFV = new Class({
	// Optionen Implementieren
	Implements : [Options],
	
	// Default Optionen setzen
	options : {
		
	},
	form: null,
	fields: null,
	validations: null,
	
	validate: function() {
		var status = true;
		for(var i = 0; i < this.fields.length; i++) {
			status = this.fields[i].validate() && status;
		}
		return status;
	},
	
	setValidateAndCheckCheckBox: function(checkbox, inv) {
		if(!checkbox.addcheck) {
			checkbox.addcheck = true; 
			checkbox.addEvent('click', function() { 
				this.validate();
			}.bind(this));
		};
		if(!inv) return checkbox.checked;
		return !checkbox.checked;
	},
	
	setValidateAndCheckRadio: function(radio, inv) {
		if(!radio.addcheck) {
			radio.addcheck = true; 
			radio.addEvent('click', function() { 
				this.validate();
			}.bind(this));
		};
		if(!inv) return radio.checked;
		return !radio.checked;
	},
	
	setValidateAndCheckSelectBox: function(select, value, inv) {
		if(!select.addcheck) {
			select.addcheck = true; 
			select.addEvent('change', function() { 
				this.validate();
			}.bind(this));
		};
		if(value == "true") {
			if(!inv) return select.get('value') > 0;
			return select.get('value') == 0;
		}
		else {
			return select.get('value') == value;
		}
	},
	
	// init
	initialize: function(formId, options) {
		// optionen übernehmen
		this.setOptions(options);
		
		this.fields = new Array();
		this.validations = new Array();
		
		this.form = $(formId);
		this.form.FISFV = this;
		this.form.addEvent('submit', function(e) {
			if(!this.validate()) {
				new Event(e).stop();
			}
		}.bind(this));
	},
	registerField: function(id) {
		var field = $(id);
		field.validations = new Array();
		field.addValidations = function(validationsArray) {
			field.validations[field.validations.length] = validationsArray;
			
			var required = false;
			for(var i = 0; i < field.validations.length; i++) {
				var required_inner = true;
				for(var j = 0; j < field.validations[i].length; j++) {
					if(field.validations[i][j].expects == 'null') {
						required_inner = false;
						break;
					}
				}
				required = required || required_inner;
			}
			
			var className = field.className;
			if(required && !className.match(/FV_validation_required/)) {
				field.className = className + " FV_validation_required ";
			}
			else if(!required && className.match(/FV_validation_required/)) {
				field.className = className.replace(/FV_validation_required/, '');
			}			
		}
		field.validate = function() {
			if(!field.setEvents) {
				var tag = field.tagName.toString().toLowerCase().trim();
				if(tag == 'input' && (field.type == 'radio' || field.type == 'checkbox')) {
					field.addEvent('click', function() { field.validate(); });
					field.addEvent('change', function() { field.validate(); });		
				}
				else {
					field.addEvent('keyup', function() { field.validate(); });
					field.addEvent('change', function() { field.validate(); });	
				}
				field.setEvents = true;
			}
			var err_i = -1;
			var err_j = -1;
			for(var i = 0; i < field.validations.length; i++) {
				// DIESE HIER ALLE "UND"-VERKNÜPFT
				var or_res = (field.validations[i].length == 0);
				var tmp_err_j = -1;
				var skip = false;
				for(var j = 0; j < field.validations[i].length; j++) {
					// DIE HIER ALLE "ODER"-VERKNÜPFT
					var tmp_res = field.validations[i][j].validate(field);
					if(tmp_res == 'skip') {
						skip = true;
						break;
					}
						
					if(tmp_res) {
						or_res = or_res || tmp_res;
					}
					else if(tmp_err_j == -1) {
						tmp_err_j = j;
					}
				}
				if(skip) {
					continue;
				}
				if(err_i == -1 && !or_res && tmp_err_j != -1) {
					err_i = i;
					err_j = tmp_err_j;
				}
			}
			for(var i = 0; i < field.validations.length; i++) {
				for(var j = 0; j < field.validations[i].length; j++) {
					field.validations[i][j].showError(true);
				}
			}
			if(err_i > -1) {
				field.validations[err_i][err_j].showError(false);
			}
			return err_i == -1;
			
		}.bind(this);
		
		field.errorDiv = false;
		field.pendingErrors = new Array();
		field.setMessage = function(validation, valid) {
			if(valid) {
				if(this.errorDiv && this.errorDiv.validatorId == validation.id) {
					this.errorDiv.dispose();
					this.errorDiv = false;
					
					if(this.pendingErrors.length > 0) {
						var tmp = this.pendingErrors;
						var err = this.pendingErrors[0];
						this.pendingErrors = new Array();
						for(var i = 1; i < tmp.length; i++) {
							this.pendingErrors[i - 1] = tmp[i];
						}
						this.setMessage(err, false);
					}
				}
				return;
			}
			if(!this.errorDiv) {
				var behind = field;
				var tag = field.tagName.toString().toLowerCase().trim();
				if(tag == 'input' && (field.type == 'checkbox' || field.type == 'radio')) {
					$$('label').each(function(label) {
						if(label.getAttribute('for') == field.id) {
							behind = label;
						}
					});
				}
				
				var parentObject = $(document.body);
				var tmp = behind;
				while((tmp = tmp.getParent()) != null) {
					var stylePosition = tmp.getStyle('position');
					if(stylePosition == 'relative' || stylePosition == 'absolute') {
						parentObject = tmp;
						break;
					}
				}
				
				var pos = behind.getPosition(parentObject);
				this.errorDiv = new Element('div', {
					'class': 'FV_error_display_top',
					'styles': {
						position: 'absolute',
						left: pos.x + behind.offsetWidth + 5,
						top: pos.y
					}
				});
				this.errorDiv.validatorId = validation.id;
				var inner = new Element('div' , {
					'class': 'FV_error_display',
					'styles': {
						overflow: 'hidden'
					}
				});
				inner.set('html', validation.errorMsg).inject(this.errorDiv);
				this.errorDiv.injectAfter(behind);
				return;
			}
			else if(this.errorDiv.validatorId != validation.id) {
				for(var i = 0; i < this.pendingErrors.length; i++) {
					if(this.pendingErrors[i] == validation) {
						return;
					}
				}
				this.pendingErrors[this.pendingErrors.length] = validation;			
			}
			
		}
		this.fields[this.fields.length] = field;
	},
	addValidation: function(id, validationArray) {
		var field = $(id);
		field.addValidations(validationArray);
	}
});

var fieldNulls = new Array();
var fieldIds = new Array();

var FISFValidation = new Class({
	id: 0,
	errorMsg: null, 
	expects: null,
	option: null,
	field: null,
	options: {},
	initialize: function(id, field_id, expects, option, errorMsg, options) {
		this.field = $(field_id);
		
		this.field = $(field_id);
		this.id = id;
		this.expects = expects;
		this.option = option;
		this.options = options;
		this.errorMsg = errorMsg;
		if(this.errorMsg.trim() == '') this.errorMsg = 'expects ' + expects;
		this.displayAt = this.options.displayAt;
		
		if(expects == 'zip') {
			if($(option)) {
				var setZipLength = function() {
					var state = $(option).get('value');
					var maxLength = 5;
					if(false) maxLength = 5;
					else if(state == "A") maxLength = 4;
					else if(state == "B") maxLength = 4;
					else if(state == "CH") maxLength = 4;
					else if(state == "CZ") maxLength = 5;
					else if(state == "D") maxLength = 5;
					else if(state == "DK") maxLength = 4;
					else if(state == "F") maxLength = 5;
					else if(state == "I") maxLength = 5;
					else if(state == "GB") maxLength = 8;
					else if(state == "L") maxLength = 4;
					else if(state == "NL") maxLength = 7;
					else if(state == "PL") maxLength = 6;
					else if(state == "SK") maxLength = 5;
					else if(state == "SRB") maxLength = 5;
					this.field.maxLength = maxLength;
					this.field.value = this.field.value.substr(0, maxLength);					
				}.bind(this);
				$(option).addEvent('change', function() {
					setZipLength();
				});
				setZipLength();
			}
			else {
				this.field.maxLength = 5;
			}
		}
		
	},
	showError: function(valid) {
		var obj = this.options.displayAt ? this.options.displayAt : this.field;
		obj.setMessage(this, valid);
	},
	validate: function() {
		
		if(this.options.condition) {
			if(!this.options.condition()) {
				return 'skip';
			}
		}
	
		var field = this.field;
		var tag = field.tagName.toString().toLowerCase().trim();
		var value = field.get('value').toString().trim();
		if(tag == 'input' && field.type == 'file') {
			value = field.value.trim();
		}
		if(tag == 'input' && field.type == 'checkbox') {
			if(this.expects != 'checked') {
				return false;	
			}
			else {
				return field.checked;
			}
		}
		else if(tag == 'input' && field.type == 'radio') {
			value = field.value.trim();
			if(this.expects == 'value' && value == this.option) {
				return field.checked;
			}
			else {
				return false;
			}		
		}
		
		switch(this.expects) {
			case 'url':
				return value.test(/^((https?|ftp):\/\/|www\.)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i);
			case 'email':
				return value.test(/^.+@.*\.[a-z]{2,6}$/i);
			
			case 'integer':
				return value.test(/^\d+$/);
			case 'float':
				return value.test(/^(-?)\d+(\.\d+)?$/);
			case 'germanfloat':
				return value.test(/^(-?)\d+((\.|,)\d+)?$/);
			
			case 'notnull':
				return value.test(/./);
			case 'null':
				return value.test(/^$/);
			
			case 'preg':
				return value.test(this.option);
			
			case 'zip':
				var state = $(this.option);
				if(state) state = state.get('value');
				
				if(!state || state == 'D' || state == 'CZ' || state == 'F' || state == 'SK' || state == 'I') {
					return value.test(/^\d{5}$/);
				}
				else if(state == 'A' || state == 'B' || state == 'CH' || state == 'DK' || state == 'L') {
					return value.test(/^\d{4}$/);
				}
				else if(state == 'PL') {
					return value.test(/^\d{2}\-\d{3}$/);
				}
				else if(state == 'NL') {
					return value.test(/^\d{4} [A-Z]{2}$/g);
				}
				else if(state == 'GB') {
					return value.test(/^[A-Z](\d|\d{2}|\d[A-Z]|[A-Z]\d{1,2}|[A-Z]\d[A-Z]) \d[A-Z]{2}$/g);
				}
				else {
					return true;
				}
				
			case 'same':
				var other = $(this.option);
				if(!other) return true;
				if(other.validate && !other.validate()) return true;
				var otherValue = other.get('value').toString().trim();
				return (value == otherValue);
			
			case 'greater':
				if(!value.test(/^(-?)\d+(\.\d+)?$/)) return false;
				return (parseFloat(value) > this.option);
			case 'greater_equal':
				if(!value.test(/^(-?)\d+(\.\d+)?$/)) return false;
				return (parseFloat(value) >= this.option);
			case 'smaller':
				if(!value.test(/^(-?)\d+(\.\d+)?$/)) return false;
				return (parseFloat(value) < this.option);
			case 'smaller_equal':
				if(!value.test(/^(-?)\d+(\.\d+)?$/)) return false;
				return (parseFloat(value) < this.option);
			case 'minlength':
				return (value.length >= this.option);
			case 'maxlength':
				return (value.length <= this.option);
			case 'value':
				return (value == this.option);
			
			case 'file':
				return value.test(/./);
			case 'image':
				return value.test(/\.(jpe?g|png|gif)$/i);
			case 'pdf':
				return value.test(/\.(pdf)$/i);
			case 'filesizemax':
				return true;
			
			case 'germantime':
				return value.match(/^([01]?\d|2[0-4]):[0-5]\d$/);
				
			case 'germandate':
				return checkgermandate(value);
			
			case 'germandateandtime':
				var t = value.split(/\s+/);
				if(!checkgermandate(t[0])) {
					return false;
				}
				if(!t[1] || !checkgermantime(t[1])) {
					return false;
				}
				return true;
			
			case 'germandateandmaybetime':
				var t = value.split(/\s+/);
				if(!checkgermandate(t[0])) {
					return false;
				}
				if(!t[1]) {
					return true;
				}
				if(!checkgermantime(t[1])) {
					return false;
				}
				return true;
				
			case 'function': 
				if(this.option) {
					return this.option(value, this);	
				}
				alert("FNF");
				return false;
		}
		return false;
	}
});

function checkgermantime(value) {
	var s = value.split(/:/);
	if(s.length != 2) return false;
	var h = s[0];
	var i = s[1];
	if(!h.test(/^\d+$/)) return false;
	if(!i.test(/^\d+$/)) return false;
	if(h > 23) {
		return false;
	}
	if(i > 60) {
		return false;
	}
	return true;
}

function checkgermandate(value) {
	var s = value.split(/\./);
	if(s.length != 3) return false;
	var d = s[0];
	var m = s[1];
	var y = s[2];
	if(!d.test(/^\d+$/)) return false;
	if(!m.test(/^\d+$/)) return false;
	if(!y.test(/^\d+$/)) return false;
	if(y < 100 && y > 70) {
		y = parseInt(y) + 1900;
	}
	if(y < 100) {
		y = parseInt(y) + 2000;
	}
	if(y < 1000) return false;
	var date = new Date();
	date.setFullYear(y);
	date.setMonth(m-1);
	date.setDate(d);
	var d2 = parseInt(date.getDate());
	var m2 = parseInt(date.getMonth() + 1);
	var y2 = parseInt(date.getYear());
	if(y2 < 200) y2 += 1900;
	return (d2 == d && m2 == m && y2 == y);
}
