(function($ty) {
	$ = jQuery = $ty;
	$ty.fn.mytyForms = [];
	$ty.fn.mytyForm = function( options ) {
		 return this.each(function(index,el) {
			var element = $ty(el); // einzelnes jQuery Element
			var validator = new $ty.mytyFormValidator( options, element );
			element.submit( function( event, val ) {
				if(validator.executeValidator !== false){
					validator.submit();
					return false;
				}else{
					validator.executeValidator = false;
					return true;
				}
			});
			$ty.fn.mytyForms.push(validator);
		});
	};
	$ty.mytyFormValidator = function( options, form ) {
		this.options = $ty.extend({},$ty.mytyFormValidator.defaultOptions, options );
		this.form = form;
		this.nrInvalid = 0;
		this.formmanagerFormId = $ty('input[name|=mytyFormID]',this.form).val();
		this.bindEvents();
		this.executeValidator = true;
	};
	$ty.extend($ty.mytyFormValidator, {
		defaultOptions : {backendForm:false,result:false,getId:function(){return (this.result !== false ? this.result.id : false);},sendByAjax:false,onSubmit:function(){return true;},onSuccess:function(){return true;},onError:function(){return true;},onLoadedFormValues:function(){return true;}},
		options : {},
		ajaxValidationInProgress : false,
		ajaxURL : myty.basePath + '/modules/formmanager/ajax.php',
		cssErrorClass : 'mytyFormError',
		cssSuccessClass : 'mytyFormSuccess',
		lastName: '',
		lastValues: [],
		lastCapcheValue:false,
		validator : false,
		form : false,
		formElement : false,
		prototype: {
			bindEvents: function() {
				$ty('textarea,input,select',this.form).bind("change", function(e){
					$ty.mytyFormValidator.setFormElement(this);
					$ty.mytyFormValidator.lastName = false;
					$ty.mytyFormValidator.checkFormElement();
				});
				$ty('textarea,input',this.form).bind("blur", function(e){
					$ty.mytyFormValidator.setFormElement(this);
					$ty.mytyFormValidator.lastName = false;
					$ty.mytyFormValidator.checkFormElement();
				});
				$ty('input.mytyFormPasswordSecond',this.form).bind("keyup", function(e){
					$ty.mytyFormValidator.setFormElement(this);
					$ty.mytyFormValidator.lastName = false;
					$ty.mytyFormValidator.checkDoublePasswordElement(false,true);
				});
				$ty('input.mytyFormCaptcha',this.form).bind("keyup", function(e){
					$ty(this).removeClass( $ty.mytyFormValidator.cssErrorClass );
				});
			},
			submit: function() {
				this.checkForm();
				this.onCheckEnd();
				return false;
			},
			checkForm : function() {
				this.nrInvalid = 0;
				$ty('.mytyFormSuccessBox, .mytyFormErrorBox',this.form).hide();
				$ty.mytyFormValidator.setActiveValidator(this);

				$ty('textarea,input,select',this.form).each(function() {
					$ty.mytyFormValidator.setFormElement(this);
					$ty.mytyFormValidator.checkFormElement();
				});
			},
			onCheckEnd : function(){
				$ty.mytyFormValidator.ajaxValidationInProgress = false;

				if($ty.mytyFormValidator.ajaxValidationInProgress === true){
					var validator = this;
					this.executeValidator = true;
					$ty.mytyFormValidator.ajaxValidationEndCallback = function(){
						validator.onCheckEnd();
					}
					return false;
				} else if(this.nrInvalid <= 0){
					
					if( this.options.onSubmit() !== false){
						//Formular absenden
						if(this.options.sendByAjax == true){
							this.sendFormByAjax();
							return false;
						}else{
							this.executeValidator = false;
							this.form.submit();
						}
					}

				}else{
					$ty('.mytyFormErrorBox',this.form).show();
					this.options.onError();
					this.executeValidator = true;
					return false;
				}
			},
			//Formulardaten für eine Datei laden
			loadFormValuesForFileId : function(fileId) {
				/* Enterprise-Feature 
				var parentObj = this;
				$ty.getJSON($ty.mytyFormValidator.ajaxURL, {'action':'getFormValuesForFileId','mytyFormID':this.formmanagerFormId,'tyFiles_id':fileId}, function(data){
					parentObj.options.onLoadedFormValues(data);
					parentObj.setFormValues(data);
				});*/
			},
			setFormValues : function(data) {
				$ty.mytyFormValidator.setActiveValidator(this);
				this.resetFormValues();
				
				$ty('.'+$ty.mytyFormValidator.cssErrorClass).removeClass($ty.mytyFormValidator.cssErrorClass);
				$ty('.'+$ty.mytyFormValidator.cssSuccessClass).removeClass($ty.mytyFormValidator.cssSuccessClass);
				
				$ty(data).each(function() {
					var value = this.value;
					$ty('textarea[name|='+this.name+'],input[name|='+this.name+'],select[name|='+this.name+']',this.form).each(function() {
						$ty.mytyFormValidator.setFormElement(this);
						$ty.mytyFormValidator.setValue(value);
					});
				});
			},
			resetFormValues : function() {
				$ty('.'+$ty.mytyFormValidator.cssErrorClass).removeClass($ty.mytyFormValidator.cssErrorClass);
				$ty('.'+$ty.mytyFormValidator.cssSuccessClass).removeClass($ty.mytyFormValidator.cssSuccessClass);
				$ty.mytyFormValidator.setActiveValidator(this);
				$ty('textarea,input,select',this.form).each(function() {
					$ty.mytyFormValidator.setFormElement(this);
					$ty.mytyFormValidator.resetValue();
				});
			},
			sendFormByAjax : function(){
				var validator = this;
				$ty.getJSON($ty.mytyFormValidator.ajaxURL,$ty(this.form).serialize(),
					function(data){
						validator.options.result = data;
						if(data.success !== true){
							$ty('.mytyFormErrorBox',validator.form).show();
							$ty.each(data.errorFields, function(index, value) {
								var el = $ty("[name='"+value+"']",validator.form);
								$ty.mytyFormValidator.markError(el);
							});
							validator.options.onError();
						}else{
							$ty('.mytyFormSuccessBox',validator.form).show();
							validator.options.onSuccess();
						}
					}
				);
			}
		},
		setActiveValidator : function(validator) { this.validator = validator; this.form = validator.form;},
		setFormElement : function(element) {this.formElement = element;},
		checkFormElement : function() {
			var check = true;
			var optional = true;
			var obj = $ty(this.formElement);
			if(this.formElement.type !='hidden'){
				if(obj.hasClass('mytyFormCaptcha') ){
					if(obj.hasClass(this.cssErrorClass)){
						$ty.mytyFormValidator.markError(this.formElement);
					}else{
                        $ty.mytyFormValidator.checkCaptcha();
					}
				}else if(obj.hasClass('mytyFormPasswordFirst') ){
					$ty.mytyFormValidator.checkDoublePasswordElement(true,false);
				}else if(obj.hasClass('mytyFormPasswordSecond') ){
					$ty.mytyFormValidator.checkDoublePasswordElement(false,false);
				}else{
					
					if(obj.hasClass("mytyFormRequired")){
						optional = false;
						check = $ty.mytyFormValidator.required();
					}
					if(check == true && obj.hasClass("mytyFormEMail")){
						check = optional || $ty.mytyFormValidator.checkEmail();
					}
					if(check == false){
						$ty.mytyFormValidator.markError(this.formElement);
					}else{
						$ty.mytyFormValidator.markSuccess(this.formElement);
					}
				}
			}
			//Richtext
			else if( obj.next('#tyep'+this.formElement.name).length == 1 && obj.parent().hasClass("mytyFormRequired") ){
				try{ fnSave('text'); }catch(e){}
				if(obj.next().text().trim() == '' ){
					$ty.mytyFormValidator.markError(this.formElement);
				}else{
					$ty.mytyFormValidator.markSuccess(this.formElement);
				}
			}
		},
		required: function() {
			var value = this.getValue();
			var result = false;
			var l = value.length
			if(l > 0){
				for (var i=0;i<l;i++){
					var val = $ty.trim(value[i]);
					if(val.length > 0 && val != 0){
						result = true;
						break;
					}
				}
			}
			return result;
		},
		checkEmail: function() {
			var value = this.getValue();
			return  /^[\w.+-]{2,64}\@[\w.-]{2,255}\.[a-z]{2,6}$/i.test(value[0]);
		},
		checkCaptcha: function(){
			var value = this.getValue();
			var el = this.formElement;
			if($ty.trim(value[0]).length == 0 ){
				$ty.mytyFormValidator.markError(el);
			}
			else if(this.lastCapcheValue !== value[0]){
				$ty.mytyFormValidator.onAjaxValidationStart();
				var validator = this.validator;
				$ty.getJSON(this.ajaxURL, {'action':'checkCaptcha','value':value[0]}, function(check){
					$ty.mytyFormValidator.setActiveValidator(validator);
					if(check == false){
						$ty.mytyFormValidator.markError(el);
					}else{
						$ty.mytyFormValidator.markSuccess(el);
					}
					$ty.mytyFormValidator.onAjaxValidationEnd();
				});
			}
			this.lastCapcheValue = value[0];
		},
		checkDoublePasswordElement : function(first,onkeyup){
			var check = true;
			var obj = $ty(this.formElement);
			var id = (first == true ? obj.attr('id')+'_pwVal' : obj.attr('id').replace(/_pwVal/g,'') );
			var secondElement = document.getElementById(id);
			var pwValObj = $ty(secondElement);

			var val1 = pwValObj.val();
			var val2 = obj.val();
			var length1 = $ty.trim(val1).length;
			var length2 = $ty.trim(val2).length;

			if( (first == true && length1 == 0) || (first == false && onkeyup == true && length2 < length1 && val1.substr(0,length2) == val2 )  ){
				$ty.mytyFormValidator.removeMarker(this.formElement);
				$ty.mytyFormValidator.removeMarker(secondElement);
				return;
			}else if(val1 !== val2 || length1 == 0 || length2 == 0){
				check = false
			};

			if(check == false){
				$ty.mytyFormValidator.markError(this.formElement);
				$ty.mytyFormValidator.markError(secondElement);
			}else{
				$ty.mytyFormValidator.markSuccess(this.formElement);
				$ty.mytyFormValidator.markSuccess(secondElement);
			}
		},
		getValue: function() {
			var values = new Array();
			switch(this.formElement.type) {
				case 'submit':break;
				case 'button':break;
				case 'select-one':
					var selected = $ty("option:selected", this.formElement);
					if(selected.length > 0) values.push(selected.val());
					break;
				case 'select-multiple':
					var selected = $ty("option:selected", this.formElement);
					if(selected.length > 0){
						values = $ty(this.formElement).val();
					}
					break;
				case 'radio':
				case 'checkbox':
					if(this.lastName != this.formElement.name){
						$ty("input:[name='"+this.formElement.name+"']:checked",this.form).each(function() {
							values.push(this.value);
						});
						this.lastValues = values;
					}else{
						values = this.lastValues;
					}
					this.lastName = this.formElement.name;
					break;
				case 'file':
					var val = $ty(this.formElement).val();
					if(val ==''){
						var val = $ty('#'+$ty(this.formElement).attr('id')+'_storedId').val();
						if(val != 'undefined' && val > 0){
							values.push(val);
						}
					}else{
						values.push(val);
					}
					break;
				default: /* 'text','textarea':*/
					if($ty(this.formElement).hasClass('form-valueselect')){
						//Value-Select-Werte -> ignorieren
					}else{
						values.push($ty(this.formElement).val());
					}
				break;
			}
			return values;
		},
		resetValue : function() {
			switch(this.formElement.type) {
				case 'submit':break;
				case 'button':break;
				case 'hidden':
					//hidden-Felder nicht zurücksetzen außer bei Richtext
					if($ty('#tyep'+this.formElement.name).length == 1){
						$ty('#tyep'+this.formElement.name).html('<p></p>');
						$ty(this.formElement).val('');
					}
					break;
				case 'radio':
				case 'checkbox':
					$ty(this.formElement).attr('checked',false);
					break;
				case 'file': /*keinen Werte setzen*/
					break;
				default:
					if($ty(this.formElement).hasClass('form-valueselect')){
						//Value-Select-Werte -> ignorieren
					}else{
						$ty(this.formElement).val('');
					}
					break;
			}
		},
		setValue  : function(value) {
			if(typeof value == 'string'){
				var newValue = $ty('<div/>').html(value).text();
			}else{
				var newValue = [];
				$ty(value).each(function(i,val) {
					newValue.push($ty('<div/>').html(val).text());
				});
			}
			switch(this.formElement.type) {
				case 'submit':break;
				case 'button':break;
				case 'hidden':
					//hidden-Felder werden nich veraendern außer bei Richtext
					if($ty('#tyep'+this.formElement.name).length == 1){
						$ty('#tyep'+this.formElement.name).html(value);
						$ty(this.formElement).val(newValue);
					}
					break;
				case 'radio':
					$ty(this.formElement).attr('checked', ($ty(this.formElement).val() == newValue ? 'checked' : false ));
					break;
				case 'checkbox':
					var obj = $ty(this.formElement);
					obj.attr('checked',false);
					$ty(newValue).each(function(index,val) {
						if(obj.val() == val){obj.attr('checked','checked');}
					});
					break;
				case 'file':
				case 'password': /*keinen Werte setzen*/
					break;
				default:
					if($ty(this.formElement).hasClass('form-valueselect')){
						//Value-Select-Werte -> ignorieren
					}else if( $ty(this.formElement).hasClass('mytyFormCaptcha')){
						$ty(this.formElement).val('');
					}else{
						$ty(this.formElement).val(newValue);
					}
					break;
			}
		},
		removeMarker  : function(element){
			var obj = $ty(element);
			if(this.validator !== false && this.validator.nrInvalid > 0){
				this.validator.nrInvalid--;
			}
			switch(element.type) {
				case 'submit':break;
				case 'button':break;
				case 'hidden':
					//Richtext
					if(obj.next('#tyep'+this.formElement.name).length == 1){
						obj.parent().parent('.mytyFormBox').removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').hide();
						obj.next().removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass );
					}
					break;
				case 'radio':
				case 'checkbox':
					obj.parent('.mytyFormBox').removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass);
					obj.parent().parent('.mytyFormField').removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').hide();
					obj.removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass );
					break;
				default:
					if(obj.hasClass('form-valueselect')){
						//Value-Select-Werte -> ignorieren
					}if(!obj.parent().hasClass('mytyFormBox')){
						obj.parent().parent('.mytyFormBox').removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').hide();
						obj.removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass );
					}else{
						obj.parent('.mytyFormBox').removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').hide();
						obj.removeClass(this.cssSuccessClass).removeClass(this.cssErrorClass );
					}
					break;
			}
		},
		markError : function(element){
			var obj = $ty(element);
			if(this.validator !== false  ){
				this.validator.nrInvalid++;
			}
			switch(element.type) {
				case 'submit':break;
				case 'button':break;
				case 'hidden':
					//Richtext
					if(obj.next('#tyep'+this.formElement.name).length == 1){
						obj.parent('.mytyFormBox').removeClass(this.cssSuccessClass).addClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').show();
						obj.next().removeClass(this.cssSuccessClass).addClass(this.cssErrorClass );
					}
					break;
				case 'radio':
				case 'checkbox':
					obj.parent('.mytyFormBox').removeClass(this.cssSuccessClass).addClass(this.cssErrorClass);
					obj.parent().parent('.mytyFormField').removeClass(this.cssSuccessClass).addClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').show();
					obj.removeClass(this.cssSuccessClass).addClass(this.cssErrorClass );
					break;
				default:
					if(obj.hasClass('form-valueselect')){
						//Value-Select-Werte -> ignorieren
					}if(!obj.parent().hasClass('mytyFormBox')){
						obj.parent().parent('.mytyFormBox').removeClass(this.cssSuccessClass).addClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').show();
						obj.removeClass(this.cssSuccessClass).addClass(this.cssErrorClass );
					}else{
						obj.parent('.mytyFormBox').removeClass(this.cssSuccessClass).addClass(this.cssErrorClass).children('.mytyFormElementErrorMsg').show();
						obj.removeClass(this.cssSuccessClass).addClass(this.cssErrorClass );
					}
					break;
			}
		},
		markSuccess : function(element){
			var obj = $ty(element);
			switch(element.type) {
				case 'submit':break;
				case 'button':break;
				case 'hidden':
					//Richtext
					if(obj.next('#tyep'+this.formElement.name).length == 1){
						obj.parent('.mytyFormBox').removeClass(this.cssErrorClass).addClass(this.cssSuccessClass ).children('.mytyFormElementErrorMsg').hide();
						obj.next().removeClass(this.cssErrorClass).addClass(this.cssSuccessClass);
					}
					break;
				case 'radio':
				case 'checkbox':
					obj.parent('.mytyFormBox').removeClass(this.cssErrorClass).addClass(this.cssSuccessClass );
					obj.parent().parent('.mytyFormField').removeClass(this.cssErrorClass).addClass(this.cssSuccessClass ).children('.mytyFormElementErrorMsg').hide();
					obj.removeClass(this.cssErrorClass).addClass(this.cssSuccessClass);
					break;
				default:
					if(obj.hasClass('form-valueselect')){
						//Value-Select-Werte -> ignorieren
					}else if(!obj.parent().hasClass('mytyFormBox')){
						obj.parent().parent('.mytyFormBox').removeClass(this.cssErrorClass).addClass(this.cssSuccessClass ).children('.mytyFormElementErrorMsg').hide();
						obj.removeClass(this.cssErrorClass).addClass(this.cssSuccessClass);
					}else{
						obj.parent('.mytyFormBox').removeClass(this.cssErrorClass).addClass(this.cssSuccessClass ).children('.mytyFormElementErrorMsg').hide();
						obj.removeClass(this.cssErrorClass).addClass(this.cssSuccessClass);
					}
					break;
			}
		},
		onAjaxValidationStart : function (){
			$ty.mytyFormValidator.ajaxValidationInProgress = true;
			this.ajaxValidationEndCallback = function (){};
		},
		onAjaxValidationEnd : function (){
			$ty.mytyFormValidator.ajaxValidationInProgress = false;
			$ty.mytyFormValidator.ajaxValidationEndCallback();
		},
		ajaxValidationEndCallback : function (){}
	});
})($ty);
