/**
 * Formulier validatie
 *
 * @author    Elze Kool <info@kooldevelopment.nl>
 * @copyright (c) 2011, Kool software en webdevelopment
 *
 * http://www.kooldevelopment.nl
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 **/

(function($) {

    $.fn.valideer = function(opt) {  
  
        var defaults = {          
        
            // Attribuut voor validatie
            regexAttr: 'data-validate',  
            
            // Functie die aangeroepen word bij het versturen van een formulier met fouten
            // return false om versturen te stoppen
            errorFn : function() { return false; },
            
			// Functie die aangeroepen wordt bij het versturen van een formulier zonder fouten
			// return false om versturen te stoppen
			succesFn : function() { return true; },
			
            // Classe die wordt toegevoegd aan invalide velden
            invalidCls : 'valideer_invalid',

			// Classe die wordt toegevoegd aan valide velden
            validCls : 'valideer_valid',

			// Functie die wordt aangeroepen wanneer een veld als invalide wordt gemarkeerd
			// return false om veld niet als invalide te markeren
			invalidFn : function(element) { return true; },

			// Functie die wordt aangeroepen wanneer een veld als valide wordt gemarkeerd
			// return false om veld niet als valide te markeren
			validFn : function(element) { return true; }
            
        };  
                
        var options = $.extend(defaults, opt);  
      
        return this.each(function() {  
    
            var form = $(this);
            var fields = form.find('input['+options.regexAttr+'], textarea['+options.regexAttr+'], select['+options.regexAttr+']');          

			// Functie om veldwaarde op te halen
			var fFieldGetValue = function(fld) {

				// Kijk if radio
				if (fld.is('input[type="radio"]')) {
					var name = fld.attr('name');
					var selected = form.find('input[type="radio"][name="'+name+'"]:checked');
					if (selected.length > 0) {
						return selected.val();
					} else {
						return '';
					}

				} else {
					return fld.val();
				}

			};
			
            // Callback voor veld validatie
            var fFieldValidate = function() {
				var fld = $(this);
                var regex = new RegExp(fld.attr(options.regexAttr));
                var val = fFieldGetValue(fld);
                if (regex.test(val)) {
					if (options.validFn(fld)) {
						fld.removeClass(options.invalidCls)
						fld.addClass(options.validCls);
					}
                } else {
					if (options.invalidFn(fld)) {
						fld.removeClass(options.validCls)
						fld.addClass(options.invalidCls);
					}
                }
            };
            
            // Callback voor form validatie
            var fFormValidate = function(ev) {
            
                // Valideer formulier velden
                fields.each(fFieldValidate);
                
                if ($(this).find('input.'+options.invalidCls+', textarea.'+options.invalidCls+',select.'+options.invalidCls).length > 0) {
                
                    if (options.errorFn()) {
                        return true;
                    } else {
                        ev.preventDefault();
                        return false;
                    }
                }
                
				if (options.succesFn()) {
					return true;
				} else {
					ev.preventDefault();
					return false;
				}
         
            };
            
            
            // Bind event handlers aan fields en form
            fields
				.bind('blur', fFieldValidate)
				.bind('change', fFieldValidate)
				.bind('keypress', function() {
                    // Alleen bij keypress wanneer formulier verkeerd is
					if ($(this).hasClass(options.invalidCls)) {
						fFieldValidate.apply(this);
					}
				})
				.bind('click', function() {
                    // Alleen bij click wanneer formulier verkeerd is
					if ($(this).hasClass(options.invalidCls)) {
						fFieldValidate.apply(this);
					}
				});
			form.bind('submit', fFormValidate);
            
            
        });

    }
      
})(jQuery);
