// FISFormValidator Version 1.6
// FISolution
// 25. November 2011 13:54:52
// 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,
	submitted: false,
	
	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, value, type, inv) {
		if(!checkbox.addcheck) {
			checkbox.addcheck = true; 
			checkbox.addEvent('click', function() { 
				this.validate();
			}.bind(this));
		};
		if(checkbox.checked) {
			if(type == 'regexp') {
				stat = checkbox.get('value').test(value);
			}
			else if(value != null) {
				stat = (checkbox.get('value') == value);
			}
		}
		else {
			stat = false;
		}
		if(inv) stat = !stat;
		return stat;
	},
	
	setValidateAndCheckRadio: function(radio, type, inv) {
		if(!radio.addcheck) {
			radio.addcheck = true; 
			radio.addEvent('click', function() { 
				this.validate();
			}.bind(this));
		};
		var stat = (radio.checked == true);
		if(inv) return !stat;
		return stat;
	},
	
	setValidateAndCheckSelect: function(select, value, type, inv) {
		if(!select.addcheck) {
			select.addcheck = true; 
			select.addEvent('change', function() { 
				this.validate();
			}.bind(this));
		};
		if(type == 'regexp') {
			var stat = select.get('value').test(value);
		}
		else if(value != null) {
			var stat = (select.get('value') == value);			
		}
		if(inv) return !stat;
		return stat;
	},
	
	setValidateAndCheckInput: function(input, value, type, inv) {
		if(!input.addcheck) {
			input.addcheck = true; 
			input.addEvent('keyup', function() { 
				this.validate();
			}.bind(this));
		};
		if(type == 'regexp') {
			var stat = input.get('value').trim().test(value);
		}
		else if(value != null) {
			var stat = (input.get('value').trim() == value);			
		}
		if(inv) return !stat;
		return stat;
	},
	
	setValidateAndCheck: function(field, value, type, inv) {
		if(field.get('tag') == 'input' && field.getAttribute('type') == 'checkbox') {
			return this.setValidateAndCheckCheckBox(field, value, type, inv);
		} 
		if(field.get('tag') == 'input' && field.getAttribute('type') == 'radio') {
			return this.setValidateAndCheckRadio(field, type, inv);
		}
		if(field.get('tag') == 'select') {
			return this.setValidateAndCheckSelect(field, value, type, inv);
		} 
		if(field.get('tag') == 'input') {
			return this.setValidateAndCheckInput(field, value, type, inv);
		}
		return true;
	},
	
	// 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) {
			this.submitted = true;
			if(!this.validate()) {
				new Event(e).stop();
			}
		}.bind(this));
		
		this.form.addEvent('check', function(e) {
			this.checkConditions();
		}.bind(this));
	},
	
	condFields: new Array(),
	checkConditions: function() {
		this.condFields.each(function(field) {
			for(var i = 0; i < field.validations.length; i++) {
				for(var j = 0; j < field.validations[i].length; j++) {
					var condition = field.validations[i][j].options.condition;
					if(condition) {
						field.validate();
					}
				}
			}
		});	
	},
	checkConditionsBound: null,
	addConditioned: function(field) {
		this.condFields.push(field);		
	},
	setConditionEvents: function() {
		this.checkConditionsBound = this.checkConditions.bind(this);
		if(this.condFields.length == 0) {
			return;
		}
		this.fields.each(function(field) {
			if(field.get('tag') == 'input' && (field.getAttribute('type') == 'checkbox' || field.getAttribute('type') == 'radio')) {
				field.addEvent('click', this.checkConditionsBound);
			} 
			else if(field.get('tag') == 'select') {
				field.addEvent('change', this.checkConditionsBound);
			} 
			else if(field.get('tag') == 'input') {
				field.addEvent('keyup', this.checkConditionsBound);
			}
		}.bind(this));
	},
	registerField: function(id) {
		var field = $(id);
		if(!field) return;
		field.validations = new Array();
		field.addValidations = function(validationsArray) {
			field.validations[field.validations.length] = validationsArray;
			
			var conditioned = false;
			var required = false;
			for(var i = 0; i < field.validations.length; i++) {
				var required_inner = true;
				var cond_inner = false;
				for(var j = 0; j < field.validations[i].length; j++) {
					if(field.validations[i][j].expects == 'null') {
						required_inner = false;
						break;
					}
					cond_inner = cond_inner || (field.validations[i][j].options.condition != null);						
				}
				required = required || required_inner;
				conditioned = conditioned || cond_inner;
			}
			if(required) {
				field.addClass("FV_validation_required");
			}
			else {
				field.removeClass("FV_validation_required");
			}
			if(conditioned) {
				this.addConditioned(field);
			}				
		}.bind(this);
		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 validations = 0;
			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;
				}
				validations++;
			}
			if(this.submitted) {
				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);
				}
			}
			
			if(validations > 0) {
				field.addClass("FV_validation_required");
			}
			else {
				field.removeClass("FV_validation_required");
			}
			
			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 = 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;
			}
		}
		if(this.options.condition) {
			this.options.condition();
		}
		
	},
	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 == 'radio' && this.expects == 'notnull') {
			if(field.get('value') == 0 || field.get('value') == '') {
				var valid = false;
				field.getParent('form').getElements('input').each(function(input) {
					if(input != field && input.get('name') == field.get('name')) {
						if(input.checked) valid = true;
						if(!input.addThisValidation) {
							input.addThisValidation = 1;
							input.addEvent('change', function() {
								field.fireEvent('change');
							});
						}
					}
				});
				return valid;
			}
			return true;
		}
		
		if(tag == 'input' && field.type == 'checkbox' && this.expects == 'anychecked') {
			var fieldname = field.get('name').replace(/_FVautoArr_\d+/, '');
			var inputs = new Array();
			field.getParent('form').getElements('input').each(function(input) {
				if(!input.get('name')) return;
				var inputname = input.get('name').replace(/_FVautoArr_\d+/, '');
				if(fieldname == inputname) {
					inputs[inputs.length] = input;
				}
			});
			if(!inputs[0]) return true;
			if(field != inputs[0]) return true;
			
			var valid = false;
			inputs.each(function(input) {
				if(input.checked) valid = true;				
			});
			return valid;
		}
		
		if(tag == 'input' && field.type == 'checkbox' && this.expects == 'checked') {
			return field.checked;
		}
		
		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-z0-9]+[-_\.a-z0-9]*@[a-z0-9]+([-_\.]?[a-z0-9])+\.[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 'phone':
				return value.test(/^(\+\d\d|0)[0-9\-\/ ]{8,}$/i);
			
			case 'mobile':
				return value.test(/^(\+\d\d|0)[0-9\-\/ ]{8,}$/i);
			
			case 'zip':
				var state = $(this.option);
				if(!state) {
					return value.test(/^\d{5}$/);
				}
				else if(!state.onchangesetlength) {
					var zipfield = this.field;
					state.onchangesetlength = function() {
						var stateval = state.get('value');
						if(stateval == 'DE' || stateval == 'CZ' || stateval == 'FR' || stateval == 'SK' || stateval == 'IT') {
							length = 5;
						}
						else if(stateval == 'AT' || stateval == 'BE' || stateval == 'CH' || stateval == 'DK' || stateval == 'LU') {
							length = 4;
						}
						else if(stateval == 'PL') {
							length = 6;
						}
						else if(stateval == 'NL') {
							length = 7;
						}
						else {
							length = 10;
						}
						zipfield.setAttribute('maxlength', length);
						zipfield.set('value', zipfield.get('value').substr(0, length));
					}
					state.addEvent('change', state.onchangesetlength);
					state.onchangesetlength();
				}
				
				var stateval = state.get('value');
				if(stateval == 'DE' || stateval == 'CZ' || stateval == 'FR' || stateval == 'SK' || stateval == 'IT') {
					return value.test(/^\d{5}$/);
				}
				else if(stateval == 'AT' || stateval == 'BE' || stateval == 'CH' || stateval == 'DK' || stateval == 'LU') {
					return value.test(/^\d{4}$/);
				}
				else if(stateval == 'PL') {
					return value.test(/^\d{2}\-\d{3}$/);
				}
				else if(stateval == 'NL') {
					return value.test(/^\d{4} [A-Z]{2}$/g);
				}
				else if(stateval == '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 'mp3':
				return value.test(/\.(mp3)$/i);
			case 'filesizemax':
				return true;
			
			case 'germantime':
				return value.match(/^([01]?\d|2[0-4]):[0-5]\d$/);
				
			case 'germandate':
				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;
				d = d * 1;
				m = m * 1;
				y = y * 1;
				var date = new Date(y,m-1,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);
			
			case 'function': 
				if(this.option) {
					return this.option(value, this);	
				}
				alert("FNF");
				return false;		
		}
		return false;
	}
});
