
  function extractPath(path) {
    return path.substring(0, path.lastIndexOf("/"));
  }

	function handleEnter(formElement, currentFormElement) {
			
		if ($(currentFormElement).is('textarea')) return;
		
   	$(currentFormElement).keydown(function(e) {
   		if (e.which != 13) return true;
   		var result = formElement.hasRequiredContent(currentFormElement);
 			if (!result) {
 				$(currentFormElement).parent().addClass("validation-failed")
 				currentFormElement.focus();  				
   		}
   		return result;
    });
	}	

  $(document).ready(function(){
    validate(inputEmail);
    validate(inputText_InputFile_Textarea);
    validate(inputConfirmEmail);
    validate(captcha);
    validate(inputCheckbox);
    validate(dropDown);
    validate(list);
    attachCaptchaRenewListener();
    bindSubmitButton();
  });
  
  function bindSubmitButton() {
    $(".abstractForm").submit(function() {
      // $(this) repräsentiert das "jQuery-fied" Formular.

      var send = true;  
        
      $(this).find(".validation-failed, .validation-start").each(function() {
      
        send = false;

 			  $(this).addClass("validation-failed");
        showFaidingErrorMessage($(this).children(), "div[id|=advice]");
      });
      
      return send;
    });
  }
  	
  var inputText_InputFile_Textarea = {
    selector: "input.required[type=text], input.required[type=file], textarea.required",
    errorBoxId: "div[id|=advice-required]",
	
		handleEnter: true,

    hasRequiredContent: function (currentFormElement) {
    	value = $(currentFormElement).val();
      return jQuery.trim($(currentFormElement).val()) != "";
    }
  }
  
  var inputEmail = {
    selector: "input.reuired.validate-email, input.validate-email",
    errorBoxId: "div[id|=advice-validate-email]",
		handleEnter: true,
		
    hasRequiredContent: function (currentFormElement) {
    	var value = $(currentFormElement).val();
    	if (value.length == 0) return true;
      var pattern = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/g;
      return value.match(pattern);
    }
  }
  
  var inputConfirmEmail = {
    selector: "input.required.validate-confirm-email",
    errorBoxId: "div[id|=advice]",
    handleEnter: true,
                         
    hasRequiredContent: function (currentFormElement) {
      id = $(currentFormElement).attr("id");
      id = id.substring(0, id.indexOf("c"));
     
      return $("#"+id).val() == $(currentFormElement).val();
    }
  }

  var captcha = {
    selector: "input.validate-captcha",
    errorBoxId: "div[id|=advice-validate-captcha]",
		handleEnter: true,
		
    hasRequiredContent: function (currentFormElement) {
      var value = $(currentFormElement).val();

			if (value == '') return false;
			  
      var valid = false;
      var currentPath = extractPath(location.pathname);
      var diff = currentPath.replace(extractPath(weblicaScriptPath), "");
      if (diff == "/") diff = "";

      var urlToCaptchaScript = location.protocol + "//" + location.host + diff + "/_php/Captcha/validCaptcha.php";
    
      $.ajax({
        url: urlToCaptchaScript,
        async: false,
        type: "POST",
        global: false,
        data: "captcha="+value,
        success: function(data) {
          if(data == "true") valid = true;
        }
      });
      return valid;
    }
  }

  var inputCheckbox = {
    selector: "input.required[type=checkbox]",
    errorBoxId: "div[id|=advice-required]",

    hasRequiredContent: function (currentFormElement) {
      return $(currentFormElement).is(":checked");
    }
  }
  
  var dropDown = {
    selector: "select.required-drop-down",
    errorBoxId: "div[id|=advice-required-drop-down]",
  
    hasRequiredContent: function (currentFormElement) {
 			return currentFormElement.context.selectedIndex != 0;
    }
  }
  
  var list = {
    selector: "select.required",
    errorBoxId: "div[id|=advice-required]",
  
    hasRequiredContent: function (currentFormElement) {    	
      return $(currentFormElement).children("option:selected").size() > 0;
    }
  }
  
  /**
   * @param Instanz, die für ein Formular Element steht
   */
  function validate(formElement) {
    var errorBoxId = formElement.errorBoxId;
    
    $(formElement.selector).each(function() {
    		// Evtl. vorhandenen Default-Wert berücksichtigen
    		if(!formElement.hasRequiredContent($(this))) {
        	$(this).parent().addClass("validation-start");
      	}

				if (formElement.handleEnter) {
					handleEnter(formElement, $(this));
				}
        
        // Webkit bug: kein Focus durch Klick auf Checkbox, daher setzen wir den Fokus beim Klick
        if ($(this).hasClass("formTickBox")) {
            $(this).click( function() {
              $(this).focus();
          });
        }
    });

    
    /**
     * Verlassen des verlangten Eingabefelds
     */
    $(formElement.selector).blur(function() {
 		
 			// Re-Entrance-Check (2454)
 			if ($(this).hasClass("required-drop-down") && !$(this).hasClass("hasFocus")) {
 	 			return;
 			}
 			 
      $(this).removeClass("hasFocus");

      if(formElement.hasRequiredContent($(this))) {
      	removeErrorMessage($(this), errorBoxId);
      }
      else {
        showFaidingErrorMessage($(this), errorBoxId);
      }
    });
  
    /**
     * Betreten des verlangten Eingabefelds
     */
    $(formElement.selector).focus(function() {
      $(this).addClass("hasFocus");
      
      $(this).parent().removeClass("validation-start");
    
      // fehlerhafter Inhalt besteht und Feld als fehlerhaft markiert 
      if(!formElement.hasRequiredContent($(this)) && $(this).parent().hasClass("validation-failed")) {
        showErrorMessage($(this), errorBoxId);
      }
    });
  }
  
  /**
   * Zeigt Fehlermeldung an, die verschwindet.
   * @param Formular-Element als JQuery Objekt
   * @param Id der Fehlermeldung die ausgefahren werden soll
   */
  function showFaidingErrorMessage(formElement, errorBoxId){  
    showErrorMessage(formElement, errorBoxId);

    setTimeout(
      function() {
        if( !$(formElement).hasClass("hasFocus") ) {
          hideMessage(formElement, errorBoxId);
        }
      },
      "3000"
    );

  }
  
  /**
   * Zeigt die Fehlermeldung an.
   * @param Formular-Element als JQuery Objekt
   * @param Id der Fehlermeldung die ausgefahren werden soll
   */
  function showErrorMessage(formElement, errorBoxId){
    formElement.parent().addClass("validation-failed");
    formElement.parent().siblings(errorBoxId).slideDown("slow", function(){});
  }
  
  /**
   * Zieht Fehlermeldung komplett zurück.
   * @param Formular-Element als JQuery Objekt
   * @param Id der Fehlermeldung die entfernt werden soll
   */
  function removeErrorMessage(formElement, errorBoxId){
    formElement.parent().removeClass("validation-failed"); // Klasse entfernen um roten Rahmen zu entfernen
    hideMessage(formElement, errorBoxId);
  }
  
  /**
   * Zieht Fehlermeldung zurück.
   * @param Formular-Element als JQuery Objekt
   * @param Id der Fehlermeldung die entfernt werden soll
   */
  function hideMessage(formElement, errorBoxId) {
    formElement.parent().siblings(errorBoxId).slideUp("slow", function(){});
  }
  
  function refreshCaptcha() {
    var elems = $('img[class="captchaImg"]'); // Dieser String plus Img Tag muss gleich sein wie die Konstante aus der Klasse GenerateHtmlVisitor im Formular-Absatz
    var random = Math.round(Math.random() * 100000);
    for (var i = 0; i < elems.length; ++i) {
      var source = elems[i].src.split("?set=");
      elems[i].src = source[0] + "?set=" + random;
    }
  }

  function attachCaptchaRenewListener() {
    var links = $('a[name="captcha"]'); // Dieser String muss gleich sein wie die Konstante aus der Klasse GenerateHtmlVisitor im Formular-Absatz
    for(var i = 0; i < links.length; ++i){ 
      links[i].onclick = function(){
      refreshCaptcha();
      return false;
    }
  }
    
}
