/**
 * JQuery Plugin for Form Handling. Useable for ZendFormwork and StandAlone
 *
 * @package       JavaScript
 * @subpackage    Form Handling
 * @author        Alex. Hannel <ahannel@syntaxxx.at>
 * @license       http://www.pixelpoems.com
 * @link          www.pixelpoems.com
 * @since         1.4
 * @version       $Revision: 12 $

 * @example       $(document).ready(function() {
 * @example          $('#myDiv').addValidators({target:'/myvarname/myvarval/'});
 * @example       }

 */

(function($) {
   /*
    * plugin internal properties - do not change!
    *
    * @param object Validator holds all together
    * @param object _forms keeps all form and field settings seperated by form id
    */
   $.fn.Validator = {};
   $.fn.Validator._forms = {};

   /*
    * plugin defaults
    *
    * @param string adds the string directly to the target string on the begin
    * @param string adds the string directly to the target string on the end
    * @param string target optional string, replaces target from form action
    * @param function errorHandler optional custom error handler
    * @param object errorFieldsMap contains fieldId errorFieldId where a specific error should be displayed
    * @param string errorContainer JQuery element selector
    * @param string errorContainerState hidden or blank
    * @param string errorPrefix prefix error element id
    * @param string containerId link var. name (content)
    * @param string containerParam link var. value (json)
    * @param object labels fieldId fieldText
    * @param object descriptions fieldId fieldpreFillText
    * @param bool urlNormalisation true|false converts ?foo=bar to /foo/bar/ if set true
    * @param bool validateEmptyFields true|false makes a ajax call even if a field where set to blank
    * @param bool true|false debug goes into window console
    */
   $.fn.Validator._defaults = {
      suffix: 'ajax/1',
      prefix: '',
      target: '',

      errorHandler: null,
      errorFieldsMap: null,
      errorContainer: null,
      errorContainerState: null,
      errorPrefix: 'err_',      

      containerId: '',
      containerParam: '',

      labels: null,
      descriptions: {},

      urlNormalisation: true,
      validateEmptyFields: false,

      doDebug: true
   };

   /*
    * addValidators - prepares form and fields
    *
    * @param object options see plugin defaults for overwrite options
    * @return bool true|false
    */
   $.fn.addValidators = function(options){
      // merge plain, defaults, custom options properties together
      with($.fn.Validator){
         var opts = $.extend({}, _defaults, options);
      }

      // iterate and reformat each matched element
      var elementNo = 0;

      return this.each(function() {
         elementNo = elementNo + 1;

         var $this = $(this);

         // build element specific options
         var o  = $.meta ? $.extend({}, opts, $this.data()) : opts;
         var formId = $this.attr('id');

         // if element id is missing, protocol and reject
         if(!formId){
            if(o.doDebug){
               debug('rejecting element #' + elementNo + ' (name: ' + $this.attr('name') + ')');
            }
            return false;
         }

         var debugPrefix = '#' + formId + ' - ';

         // get primary target
         o.url = (!$this.attr('action')) ? '' : $this.attr('action');

         if(o.doDebug){
            debug(debugPrefix+'ID: ' + formId);
            debug(debugPrefix+'Url Action: ' + o.url);
            debug(debugPrefix+'Url Prefix: ' + o.prefix);
            debug(debugPrefix+'Url Target: ' + o.target);
            debug(debugPrefix+'Url Suffix: ' + o.suffix);
            debug(debugPrefix+'Url Normalisation: ' + o.urlNormalisation);
         }

         //var baseUrl = {};

         var msg = '/test/1/';
         var response = $.fn.Validator.parseUrl(msg);
         debug('Response #1: ' + response);

         var msg = '/test/1/abc/d';
         var response = $.fn.Validator.parseUrl(msg);
         debug('Response #2: ' + response);

         var msg = '&test=1&testx=b';
         var response = $.fn.Validator.parseUrl(msg);
         debug('Response #3: ' + response);

         var msg = '?test=1&testx=b';
         var response = $.fn.Validator.parseUrl(msg);
         debug('Response #4: ' + response);


         return;

         /*
         <script type="text/javascript">
         Aussage = "Der Mensch ist des Menschen sein Feind";
         Ergebnis = Aussage.match(/\bMensch\b|\bMenschen\b/g);
         if (Ergebnis)
           for (var i = 0; i < Ergebnis.length; ++i)
             alert("Test 2: Fund " + i + " - " + Ergebnis[i]);
         </script>
         */

         /*
         if(o.target != '?'){
            o.url = (o.url.substr(-1,1) != '/') ? o.url + '/' : o.url;
         }

         if(typeof(o.url) != 'undefined' && o.url){
            if(o.target == '?'){
               o.url = o.url + o.target;
            }else if(o.target){
               o.url = (o.target.substr(-1,1) != '/') ? o.url + o.target + '/' : o.url + o.target;
            }
         }
         */

         with($.fn.Validator){
            if(typeof(o.errorContainer) != null){
               if(typeof(forms[id]._containerFields) == 'undefined'){
                  forms[id] = $.extend(forms[id], {'_containerFields' : []});
                  if(o.doDebug) debug(forms[id]._containerFields);
               }

               if(typeof(o.errorContainerState) != 'undefined'
                  && o.errorContainerState == 'hidden' && !o._init){                  
                  $(o.errorContainer).hide();
               }
            }

            o._init = true;

            forms[id] = o;

            if(o.doDebug){
               debug('Form ID: ' + id);
               for(var field in forms[id]){
                  debug('setting: ' + field + ' | ' + forms[id][field]);
               }
            }
         }

         // $('#' + id + ' input[id][class!=btn][type!=hidden], #' + id + ' textarea[id]').each(function(){
         $('#' + id + ' input[id][type!=submit][type!=button][type!=hidden], #' + id + ' textarea[id]').each(function(){
            with($(this)){
               $.fn.Validator._forms[id].descriptions[attr('id')] = val();
               css('color', '#7c797b');
               css('font-weight', 'normal');
            }

            $(this).focus(function(){
               with($(this)){
                  css('color', '#000000');
                  css('font-weight', 'bold');
                  if($.fn.Validator._forms[id].descriptions[attr('id')] == val()){
                     val('');
                  }
               }
            });

            $(this).blur(function(){
               with($(this)){
                  if(val() == ''){
                     css('color', '#7c797b');
                     css('font-weight', 'normal');
                     val($.fn.Validator._forms[id].descriptions[attr('id')]);
                  }
               }
            });

            $(this).change(function(){
               with($(this)){
                  //if(val() != ''){
                     doValidate(attr('id'));
                  //}
               }
            });
         });

         $(this).submit(function(){
            try{
               for(var field in $.fn.Validator._forms[id].descriptions){
                  with($("input[id="+field+']')){
                     if($.fn.Validator._forms[id].descriptions[field] == val()){
                        val('');
                     }
                  }
               }

               $.fn.doValidate(id);
            }

            catch(e){
               debug(e);
            }

            return false;
         });
      });
   };

/* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */
/* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */
/* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */
/* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */
/* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */
/* ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- */

   $.fn.doValidate = function(id){
      var formId  = $('#'+id).parents().find('form').attr('id');
      formId = (typeof(formId) == 'undefined') ? id : formId;

      with($.fn.Validator._forms[formId]){
         var formUrl = (suffix) ? url + suffix : url;

         // detect custom error container
         if(errorContainer && formId != id){
            $('#' + errorPrefix + id).remove();
         }

         if(id == formId){
            containerParam = (containerParam) ? containerParam : '';
            containerId = (containerId) ? containerId : '';

            if(containerParam && containerId){
               formUrl += '&' + containerParam + '=' + containerId + '';
            }
         }
      }

      var formData = $('#'+id).serialize();

      if($.fn.Validator._forms[formId].doDebug){
         debug('id: ' + id + ' | formId: ' + formId + ' | formData: ' + formData + ' | formUrl: ' + formUrl);
      }

      $.post(formUrl,formData,function(response){
         var status = false;

         try{
            with($.fn.Validator._forms[formId]){
               // detect custom error container
               if(typeof(errorContainer) == null || !errorContainer){
                  $('#'+id).parent().find('.errors').remove();

               }else{
                  /*
                  if(typeof(_containerFields) != 'undefined'){
                     _containerFields.push.apply(_containerFields, [id]);
                     debug(_containerFields);
                  }
                  */

                  /*
                   // GOOD PART
                  if(typeof(errorContainerState) != 'undefined'
                     && errorContainerState == 'hidden'){

                     var n = $(errorContainer + ' span').length;
                     debug('Previouse Errors: ' + n);

                     if(n){
                        $(errorContainer).hide();
                        debug("hidding errorContainer");
                     }else{
                        debug("NOT hidding errorContainer");
                     }
                  }
                  */
               }

               if(doDebug){
                  debug('Response: '+response+' (' + typeof(response) + ')');
               }

               if(typeof(response) != 'object'){
                  status = false;

               }else if(typeof(response.length) != 'undefined' && response.length == 0){
                  status = true;

               }else{
                  var count = 0;
                  for (k in response) if (response.hasOwnProperty(k)) count++;

                  if(doDebug){
                     debug('Response Amount: ' + count);
                  }

                  if(count == 1 && typeof(response[containerId]) == 'string'){
                     $('#' + containerId).html(response[containerId]);
                     return;
                  }

                  if(doDebug){
                     for(var tidx in response){
                        debug('tidx: ' + tidx + ' = ' + response[tidx]);
                     }
                  }

                  for(var tidx in response){
                     // detect own error container
                     if(errorContainer){
                        $('#' + errorPrefix + tidx).remove();
                     }

                     if(!$('#'+tidx).val()
                        && typeof(descriptions[tidx] != 'undefined'
                        && descriptions[tidx])){
                           $('#'+tidx).val(descriptions[tidx]);
                     }

                     if(typeof(tidx) != 'object'){
                        // tab detect
                        if(typeof(response[tidx]) == 'object'){
                           var error = response[tidx];
                        }else{
                           var error = response;
                        }

                        // detect custom error handler
                        if(typeof(errorHandler) == 'function'){
                           var html = errorHandler(error,$.fn.Validator._forms[formId],formId);

                        }else{
                           var html = '';

                           if(typeof(error) == 'object'){
                              for(var errIdx in error){
                                 // detect custom error handler
                                 if(typeof(errorHandler) == 'function'){
                                    html += errorHandler(error,$.fn.Validator._forms[formId],formId);
                                 }else{
                                    html += $.fn.Validator.getErrorHTML(error,formId);
                                 }
                              }

                              $('#' + tidx).parent().append(html);
                              html = null;

                           }else{
                              html = $.fn.Validator.getErrorHTML(error,formId);
                           }
                        }

                     }else{
                        for(var eidx in response[tidx]){
                           // tab detect
                           var error = (typeof(response[tidx][eidx]) == 'object') ? response[tidx][eidx] : response[tidx];

                           // detect custom error handler
                           if(typeof(errorHandler) == 'function'){
                              var html = errorHandler(error,$.fn.Validator._forms[formId],formId);

                           }else{
                              var html = $.fn.Validator.getErrorHTML(error, formId);
                           }
                        }
                     }

                     if(html && typeof(errorContainer) == 'string' && errorContainer){
                        $(errorContainer).append(html);
                     }else{
                        $('#'+id).parent().append(html);
                     }
                  }
               }

               if(errorContainer){
                  var n = $(errorContainer + ' *[id^='+errorPrefix+']').length;
                  debug('Previouse Errors: ' + n);

                  if(!n){
                     $(errorContainer).hide();
                     debug("hidding errorContainer");
                  }else{
                     debug("NOT hidding errorContainer");
                  }

                  /*
                   // GOOD PART
                  if(typeof(errorContainerState) != 'undefined'
                     && errorContainerState == 'hidden'){

                     var n = $(errorContainer + ' span').length;
                     debug('Previouse Errors: ' + n);

                     if(n){
                        $(errorContainer).hide();
                        debug("hidding errorContainer");
                     }else{
                        debug("NOT hidding errorContainer");
                     }
                  }
                  */
               }
            }

            // debug('id: ' + id + ' | formId: ' + formId + ' | status: ' + status);

            if(id == formId && status){
               with($('#'+formId)){
                  unbind('submit');
                  attr('action', $.fn.Validator._forms[formId].url+'/json/content/');
                  submit();
               }
            }
         }
         catch(e){
            debug(e);
         }
      }
      ,'json');
   };

   $.fn.Validator.getErrorHTML = function(errArray,formId){
      if($.fn.Validator._forms[formId].doDebug){
         for(var field in errArray){
            debug('Field: ' + field + ' | Value: ' + errArray[field]);
         }
      }

      var oBegin = '<ul class="errors">';
      var oEnd   = '</ul>';
      var o      = '';

      $.each(errArray,function(field,errRow){
         o += oBegin + '<li>'+ errRow +'</li>' + oEnd;
      });

      return o;
   };

   $.fn.Validator.parseUrl = function(url, type){
      if(typeof(url) != "string" || !url) return false;
      //if(typeof(type) != "boolean") return false;

      // 

      // normalizing url or not?
      //if(type){

      debug('Url: ' + url);

      var regex = /[\?|\&|\/]*(.?[\=|\/]+)[\=|\/]+(.?[\&|\/]*)/gi;
      var regex = /[\?|\&|\/]{0,1}(.+?[\=|\/]+)/gi;
      var regex = /[\?|\&|\/]{0,1}(.+?[\=|\/]+)[\=|\/]+(.+?[\&|\/]*)/gi;
      var regex = /[\?|\&|\/]{0,1}([a-z0-9\_\-]+)/gi;
      var regex = /[\?|\&|\/]{0,1}([a-z0-9\_\-]+)/gi;

      debug('Regex: ' + regex);

      //result = regex.exec(url);
      result = url.match(regex);
      debug('Result: ' + result + ' (' + result.length + ')');
      // RegExp

      //for(var i = 0; i < RegExp.length; i++){
      for(var i = 0; i < result.length; i++){
         debug('Result #' + i + ': ' + result[i]);

         //debug('Result #' + i + ': ' + RegExp.$i);
      }
   
      /*
      <script type="text/javascript">
      Aussage = "Der Mensch ist des Menschen sein Feind";
      Ergebnis = Aussage.match(/\bMensch\b|\bMenschen\b/g);
      if (Ergebnis)
        for (var i = 0; i < Ergebnis.length; ++i)
          alert("Test 2: Fund " + i + " - " + Ergebnis[i]);
      </script>
      */
   };

   $.fn.Validator._detectUrlType = function(url){

      //
   }

//
// end of closure
//
})(jQuery);


if(typeof(debug) == 'undefined'){
   function debug(msg) {
      if(window.console != undefined 
         && window.console.log != undefined)
         window.console.log(msg);
   }
}
