/*
   Adds validation to forms
   
   Quite bare at the moment, add more validations as they crop up
*/
(function($){
   $.fn.formify = function (options) {
      // bind a handler to the form's submit event
      var me = this;
      $(this).submit(function() {
         return $(me).validateInputs();
      });
      
      // find labels, insert a * if the field is required
      $(this).find('.required').each(function(idx, e){
         var name = $(e).data('human-name') || $(e).attr('name');
         $(e).parents("tr").find("label:contains('" + name + "'), th:contains('" + name + "')").append('<span class="req"> *</span>');
      });
      
      // if we're a table, add some row classes
      $(this).find('tr').each(function(idx, e){
         if((idx + 1) % 2 == 0)
            $(e).addClass('even');
         else
            $(e).addClass('odd');
      });
   }
   $.fn.validateInputs = function (options) {
      var errors = [];
      var me = this;
      
      // start fresh
      $(this).find('.badNode').removeClass('badNode');
      
      // validations are done in order of importance
      // we will only notify them of 1 error per field
      
      var ignoreValidation = '.badNode, :hidden'; // Will ignore elements that are hidden, or have a class of "badNode"
      
      // required
      $(this).find('.required').not(ignoreValidation).each(function(idx, e){
         if($(e).val() == ''){
            var name = $(e).data('human-name') || $(e).attr('name');
            errors.push(name + ' is a required field.');
            $(e).addClass('badNode');
         }
      });
      
      // email
      $(this).find('.email').not(ignoreValidation).each(function(idx, e){
         if(!$(e).val().match(/(^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$)|(^$)/i)){
            var name = $(e).data('human-name') || $(e).attr('name');
            errors.push(name + ' must be a valid email address (joe.blogs@example.com).');
            $(e).addClass('badNode');
         }
      });
      
      // postcode
      $(this).find('.postcode').not(ignoreValidation).each(function(idx, e){
         if(!$(e).val().match(/(^\d\d\d\d$)|(^$)/)){
            var name = $(e).data('human-name') || $(e).attr('name');
            errors.push(name + ' must be an Australian postcode (1234).');
            $(e).addClass('badNode');
         }
      });
      
      // ozphone
      $(this).find('.ozphone').not(ignoreValidation).each(function(idx, e){
         if(!$(e).val().replace(/\s/g, '').match(/(^0([0-9]){9}$|^13[0-9]{4}$|^1[389]00[0-9]{6}$)|(^$)/)){
            var name = $(e).data('human-name') || $(e).attr('name');
            errors.push(name + ' must be an Australian phone number (01 2345 6789).');
            $(e).addClass('badNode');
         }
      });
      
      if($(this).find('.error').length == 0){
         $(this).children(':first').before('<div class="error"></div>');
      }
      $(this).find('.error').html('\
         <a name="error"></a>\
         <img src="/images/icons/error.gif" alt="error" />\
         <p class="first">The following problems were identified with your request:</p>\
         <ul>\
         ' + $.map(errors, function(e){ return '<li>' + e + '</li>' }).join('\n') + '\
         </ul>\
         <p>Please rectify these issues, and resubmit the form.</p>\
         <input type="button" id="errOK" value="OK" />').hide().find('input').click(function(){
         $(me).find('.error').hide();
      });
      
      if(!errors.length == 0){
         window.location.hash = '#error';
         $(this).find('.error').show();
         return false;
      }
      
      return true;
   }
})(jQuery);

