/*

The MIT License (MIT)

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.

*/

/*!
 * jQuery Form Plugin
 * version: 2.47 (04-SEP-2010)
 * @requires jQuery v1.3.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

;(function($) {

/*
  Usage Note:
  -----------
  Do not use both ajaxSubmit and ajaxForm on the same form.  These
  functions are intended to be exclusive.  Use ajaxSubmit if you want
  to bind your own submit handler to the form.  For example,

  $(document).ready(function() {
    $('#myForm').bind('submit', function() {
      $(this).ajaxSubmit({
        target: '#output'
      });
      return false; // <-- important!
    });
  });

  Use ajaxForm when you want the plugin to manage all the event binding
  for you.  For example,

  $(document).ready(function() {
    $('#myForm').ajaxForm({
      target: '#output'
    });
  });

  When using ajaxForm, the ajaxSubmit function will be invoked for you
  at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
  // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
  if (!this.length) {
    log('ajaxSubmit: skipping submit process - no element selected');
    return this;
  }

  if (typeof options == 'function') {
    options = { success: options };
  }

  var url = $.trim(this.attr('action'));
  if (url) {
    // clean url (don't include hash vaue)
    url = (url.match(/^([^#]+)/)||[])[1];
  }
  url = url || window.location.href || '';

  options = $.extend(true, {
    url:  url,
    type: this.attr('method') || 'GET',
    iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
  }, options);

  // hook for manipulating the form data before it is extracted;
  // convenient for use with rich editors like tinyMCE or FCKEditor
  var veto = {};
  this.trigger('form-pre-serialize', [this, options, veto]);
  if (veto.veto) {
    log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
    return this;
  }

  // provide opportunity to alter form data before it is serialized
  if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
    log('ajaxSubmit: submit aborted via beforeSerialize callback');
    return this;
  }

  var n,v,a = this.formToArray(options.semantic);
  if (options.data) {
    options.extraData = options.data;
    for (n in options.data) {
      if(options.data[n] instanceof Array) {
        for (var k in options.data[n]) {
          a.push( { name: n, value: options.data[n][k] } );
        }
      }
      else {
        v = options.data[n];
        v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
        a.push( { name: n, value: v } );
      }
    }
  }

  // give pre-submit callback an opportunity to abort the submit
  if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
    log('ajaxSubmit: submit aborted via beforeSubmit callback');
    return this;
  }

  // fire vetoable 'validate' event
  this.trigger('form-submit-validate', [a, this, options, veto]);
  if (veto.veto) {
    log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
    return this;
  }

  var q = $.param(a);

  if (options.type.toUpperCase() == 'GET') {
    options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
    options.data = null;  // data is null for 'get'
  }
  else {
    options.data = q; // data is the query string for 'post'
  }

  var $form = this, callbacks = [];
  if (options.resetForm) {
    callbacks.push(function() { $form.resetForm(); });
  }
  if (options.clearForm) {
    callbacks.push(function() { $form.clearForm(); });
  }

  // perform a load on the target only if dataType is not provided
  if (!options.dataType && options.target) {
    var oldSuccess = options.success || function(){};
    callbacks.push(function(data) {
      var fn = options.replaceTarget ? 'replaceWith' : 'html';
      $(options.target)[fn](data).each(oldSuccess, arguments);
    });
  }
  else if (options.success) {
    callbacks.push(options.success);
  }

  options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
    var context = options.context || options;   // jQuery 1.4+ supports scope context 
    for (var i=0, max=callbacks.length; i < max; i++) {
      callbacks[i].apply(context, [data, status, xhr || $form, $form]);
    }
  };

  // are there files to upload?
  var fileInputs = $('input:file', this).length > 0;
  var mp = 'multipart/form-data';
  var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);

  // options.iframe allows user to force iframe mode
  // 06-NOV-09: now defaulting to iframe mode if file input is detected
   if (options.iframe !== false && (fileInputs || options.iframe || multipart)) {
     // hack to fix Safari hang (thanks to Tim Molendijk for this)
     // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
     if (options.closeKeepAlive) {
       $.get(options.closeKeepAlive, fileUpload);
    }
     else {
       fileUpload();
    }
   }
   else {
     $.ajax(options);
   }

  // fire 'notify' event
  this.trigger('form-submit-notify', [this, options]);
  return this;


  // private function for handling file uploads (hat tip to YAHOO!)
  function fileUpload() {
    var form = $form[0];

    if ($(':input[name=submit],:input[id=submit]', form).length) {
      // if there is an input with a name or id of 'submit' then we won't be
      // able to invoke the submit fn on the form (at least not x-browser)
      alert('Error: Form elements must not have name or id of "submit".');
      return;
    }
    
    var s = $.extend(true, {}, $.ajaxSettings, options);
    s.context = s.context || s;
    var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
    window[fn] = function() {
      var f = $io.data('form-plugin-onload');
      if (f) {
        f();
        window[fn] = undefined;
        try { delete window[fn]; } catch(e){}
      }
    }
    var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />');
    var io = $io[0];

    $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

    var xhr = { // mock object
      aborted: 0,
      responseText: null,
      responseXML: null,
      status: 0,
      statusText: 'n/a',
      getAllResponseHeaders: function() {},
      getResponseHeader: function() {},
      setRequestHeader: function() {},
      abort: function() {
        this.aborted = 1;
        $io.attr('src', s.iframeSrc); // abort op in progress
      }
    };

    var g = s.global;
    // trigger ajax global events so that activity/block indicators work like normal
    if (g && ! $.active++) {
      $.event.trigger("ajaxStart");
    }
    if (g) {
      $.event.trigger("ajaxSend", [xhr, s]);
    }

    if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
      if (s.global) { 
        $.active--;
      }
      return;
    }
    if (xhr.aborted) {
      return;
    }

    var cbInvoked = false;
    var timedOut = 0;

    // add submitting element to data if we know it
    var sub = form.clk;
    if (sub) {
      var n = sub.name;
      if (n && !sub.disabled) {
        s.extraData = s.extraData || {};
        s.extraData[n] = sub.value;
        if (sub.type == "image") {
          s.extraData[n+'.x'] = form.clk_x;
          s.extraData[n+'.y'] = form.clk_y;
        }
      }
    }

    // take a breath so that pending repaints get some cpu time before the upload starts
    function doSubmit() {
      // make sure form attrs are set
      var t = $form.attr('target'), a = $form.attr('action');

      // update form attrs in IE friendly way
      form.setAttribute('target',id);
      if (form.getAttribute('method') != 'POST') {
        form.setAttribute('method', 'POST');
      }
      if (form.getAttribute('action') != s.url) {
        form.setAttribute('action', s.url);
      }

      // ie borks in some cases when setting encoding
      if (! s.skipEncodingOverride) {
        $form.attr({
          encoding: 'multipart/form-data',
          enctype:  'multipart/form-data'
        });
      }

      // support timout
      if (s.timeout) {
        setTimeout(function() { timedOut = true; cb(); }, s.timeout);
      }

      // add "extra" data to form if provided in options
      var extraInputs = [];
      try {
        if (s.extraData) {
          for (var n in s.extraData) {
            extraInputs.push(
              $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
                .appendTo(form)[0]);
          }
        }

        // add iframe to doc and submit the form
        $io.appendTo('body');
        $io.data('form-plugin-onload', cb);
        form.submit();
      }
      finally {
        // reset attrs and remove "extra" input elements
        form.setAttribute('action',a);
        if(t) {
          form.setAttribute('target', t);
        } else {
          $form.removeAttr('target');
        }
        $(extraInputs).remove();
      }
    }

    if (s.forceSync) {
      doSubmit();
    }
    else {
      setTimeout(doSubmit, 10); // this lets dom updates render
    }
  
    var data, doc, domCheckCount = 50;

    function cb() {
      if (cbInvoked) {
        return;
      }

      $io.removeData('form-plugin-onload');
      
      var ok = true;
      try {
        if (timedOut) {
          throw 'timeout';
        }
        // extract the server response from the iframe
        doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
        
        var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
        log('isXml='+isXml);
        if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
          if (--domCheckCount) {
            // in some browsers (Opera) the iframe DOM is not always traversable when
            // the onload callback fires, so we loop a bit to accommodate
            log('requeing onLoad callback, DOM not available');
            setTimeout(cb, 250);
            return;
          }
          // let this fall through because server response could be an empty document
          //log('Could not access iframe DOM after mutiple tries.');
          //throw 'DOMException: not available';
        }

        //log('response detected');
        cbInvoked = true;
        xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null; 
        xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
        xhr.getResponseHeader = function(header){
          var headers = {'content-type': s.dataType};
          return headers[header];
        };

        var scr = /(json|script)/.test(s.dataType);
        if (scr || s.textarea) {
          // see if user embedded response in textarea
          var ta = doc.getElementsByTagName('textarea')[0];
          if (ta) {
            xhr.responseText = ta.value;
          }
          else if (scr) {
            // account for browsers injecting pre around json response
            var pre = doc.getElementsByTagName('pre')[0];
            if (pre) {
              xhr.responseText = pre.innerHTML;
            }
          }        
        }
        else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
          xhr.responseXML = toXml(xhr.responseText);
        }
        data = $.httpData(xhr, s.dataType);
      }
      catch(e){
        log('error caught:',e);
        ok = false;
        xhr.error = e;
        $.handleError(s, xhr, 'error', e);
      }

      // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
      if (ok) {
        s.success.call(s.context, data, 'success', xhr);
        if (g) {
          $.event.trigger("ajaxSuccess", [xhr, s]);
        }
      }
      if (g) {
        $.event.trigger("ajaxComplete", [xhr, s]);
      }
      if (g && ! --$.active) {
        $.event.trigger("ajaxStop");
      }
      if (s.complete) {
        s.complete.call(s.context, xhr, ok ? 'success' : 'error');
      }

      // clean up
      setTimeout(function() {
        $io.removeData('form-plugin-onload');
        $io.remove();
        xhr.responseXML = null;
      }, 100);
    }

    function toXml(s, doc) {
      if (window.ActiveXObject) {
        doc = new ActiveXObject('Microsoft.XMLDOM');
        doc.async = 'false';
        doc.loadXML(s);
      }
      else {
        doc = (new DOMParser()).parseFromString(s, 'text/xml');
      }
      return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
    }
  }
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *  is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *  used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
  // in jQuery 1.3+ we can fix mistakes with the ready state
  if (this.length === 0) {
    var o = { s: this.selector, c: this.context };
    if (!$.isReady && o.s) {
      log('DOM not ready, queuing ajaxForm');
      $(function() {
        $(o.s,o.c).ajaxForm(options);
      });
      return this;
    }
    // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
    log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
    return this;
  }
  
  return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
      e.preventDefault();
      $(this).ajaxSubmit(options);
    }
  }).bind('click.form-plugin', function(e) {
    var target = e.target;
    var $el = $(target);
    if (!($el.is(":submit,input:image"))) {
      // is this a child element of the submit el?  (ex: a span within a button)
      var t = $el.closest(':submit');
      if (t.length == 0) {
        return;
      }
      target = t[0];
    }
    var form = this;
    form.clk = target;
    if (target.type == 'image') {
      if (e.offsetX != undefined) {
        form.clk_x = e.offsetX;
        form.clk_y = e.offsetY;
      } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
        var offset = $el.offset();
        form.clk_x = e.pageX - offset.left;
        form.clk_y = e.pageY - offset.top;
      } else {
        form.clk_x = e.pageX - target.offsetLeft;
        form.clk_y = e.pageY - target.offsetTop;
      }
    }
    // clear form vars
    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
  });
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
  return this.unbind('submit.form-plugin click.form-plugin');
};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
  var a = [];
  if (this.length === 0) {
    return a;
  }

  var form = this[0];
  var els = semantic ? form.getElementsByTagName('*') : form.elements;
  if (!els) {
    return a;
  }
  
  var i,j,n,v,el;
  for(i=0, max=els.length; i < max; i++) {
    el = els[i];
    n = el.name;
    if (!n) {
      continue;
    }

    if (semantic && form.clk && el.type == "image") {
      // handle image inputs on the fly when semantic == true
      if(!el.disabled && form.clk == el) {
        a.push({name: n, value: $(el).val()});
        a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
      }
      continue;
    }

    v = $.fieldValue(el, true);
    if (v && v.constructor == Array) {
      for(j=0, jmax=v.length; j < jmax; j++) {
        a.push({name: n, value: v[j]});
      }
    }
    else if (v !== null && typeof v != 'undefined') {
      a.push({name: n, value: v});
    }
  }

  if (!semantic && form.clk) {
    // input type=='image' are not found in elements array! handle it here
    var $input = $(form.clk), input = $input[0];
    n = input.name;
    if (n && !input.disabled && input.type == 'image') {
      a.push({name: n, value: $input.val()});
      a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
    }
  }
  return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
  //hand off to jQuery.param for proper encoding
  return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
  var a = [];
  this.each(function() {
    var n = this.name;
    if (!n) {
      return;
    }
    var v = $.fieldValue(this, successful);
    if (v && v.constructor == Array) {
      for (var i=0,max=v.length; i < max; i++) {
        a.push({name: n, value: v[i]});
      }
    }
    else if (v !== null && typeof v != 'undefined') {
      a.push({name: this.name, value: v});
    }
  });
  //hand off to jQuery.param for proper encoding
  return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *    <input name="A" type="text" />
 *    <input name="A" type="text" />
 *    <input name="B" type="checkbox" value="B1" />
 *    <input name="B" type="checkbox" value="B2"/>
 *    <input name="C" type="radio" value="C1" />
 *    <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *     array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
  for (var val=[], i=0, max=this.length; i < max; i++) {
    var el = this[i];
    var v = $.fieldValue(el, successful);
    if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
      continue;
    }
    v.constructor == Array ? $.merge(val, v) : val.push(v);
  }
  return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
  var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
  if (successful === undefined) {
    successful = true;
  }

  if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
    (t == 'checkbox' || t == 'radio') && !el.checked ||
    (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
    tag == 'select' && el.selectedIndex == -1)) {
      return null;
  }

  if (tag == 'select') {
    var index = el.selectedIndex;
    if (index < 0) {
      return null;
    }
    var a = [], ops = el.options;
    var one = (t == 'select-one');
    var max = (one ? index+1 : ops.length);
    for(var i=(one ? index : 0); i < max; i++) {
      var op = ops[i];
      if (op.selected) {
        var v = op.value;
        if (!v) { // extra pain for IE...
          v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
        }
        if (one) {
          return v;
        }
        a.push(v);
      }
    }
    return a;
  }
  return $(el).val();
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
  return this.each(function() {
    $('input,select,textarea', this).clearFields();
  });
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
  return this.each(function() {
    var t = this.type, tag = this.tagName.toLowerCase();
    if (t == 'text' || t == 'password' || tag == 'textarea') {
      this.value = '';
    }
    else if (t == 'checkbox' || t == 'radio') {
      this.checked = false;
    }
    else if (tag == 'select') {
      this.selectedIndex = -1;
    }
  });
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
  return this.each(function() {
    // guard against an input with the name of 'reset'
    // note that IE reports the reset function as an 'object'
    if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
      this.reset();
    }
  });
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
  if (b === undefined) {
    b = true;
  }
  return this.each(function() {
    this.disabled = !b;
  });
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
  if (select === undefined) {
    select = true;
  }
  return this.each(function() {
    var t = this.type;
    if (t == 'checkbox' || t == 'radio') {
      this.checked = select;
    }
    else if (this.tagName.toLowerCase() == 'option') {
      var $sel = $(this).parent('select');
      if (select && $sel[0] && $sel[0].type == 'select-one') {
        // deselect all other options
        $sel.find('option').selected(false);
      }
      this.selected = select;
    }
  });
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
  if ($.fn.ajaxSubmit.debug) {
    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
    if (window.console && window.console.log) {
      window.console.log(msg);
    }
    else if (window.opera && window.opera.postError) {
      window.opera.postError(msg);
    }
  }
};

})(jQuery);
