/**
 * AjaxHandlerObject.class.js file
 *
 * Instantiable version of AjaxHandler
 *
 * @author Aaron <aaron@doc-net.com>
 * @copyright Doctor Net Ltd &copy; 2008
 * @package SprintToolv3.default
 */
/**
 * AjaxHandlerObject class/constructor
 *
 */
function AjaxHandlerObject() {
   this.str_url = '';
   this.arr_data = new Array();
   this.str_custom_xml = false;
   this.bol_async = false;
}
AjaxHandlerObject.prototype = {
   /**
    * Set the URL to POST to
    *
    * @param String str_url
    */
   set_url: function(str_url) {
      this.str_url = str_url;
   },
   /**
    * Add some data
    *
    * @param String str_field Field name
    * @param Mix mix_val Field value
    */
   add_data: function(str_field, mix_val) {
      // See if we need to encode it first
      if (String(mix_val).match(/[^a-zA-Z0-9\.\-_]/) && !String(mix_val).match(/%[A-Z0-9]{2}/)) {
         mix_val = encodeURIComponent(mix_val);
      }
      this.arr_data[str_field] = mix_val;
   },
   /**
    * Set all the data at once
    *
    * @param Array arr_data
    */
   set_data: function(arr_data) {
      this.arr_data = arr_data;
   },
   /**
    * Set the custom XML
    *
    * To be used instead of add_data to specify
    * bespoke XML
    *
    * @param String str_xml
    */
   set_custom_xml: function(str_xml) {
      this.str_custom_xml = str_xml;
   },
   /**
    * Build up the XML document to send over AJAX
    *
    * @return String
    */
   build_xml: function() {
      // Allow use of custom XML if set
      if (this.str_custom_xml) {
         return this.str_custom_xml;
      }
      var str_xml = '<'+'?xml version="1.0"?><root><fields>';
      for (str_field in this.arr_data) {
         // Ignore functions in Array
         if ((typeof this.arr_data[str_field]) != 'function') {
            str_xml += '<'+str_field+'><![CDATA['+this.arr_data[str_field]+']]></'+str_field+'>';
         }
      }
      str_xml += '</fields></root>';
      return str_xml;
   },
   /**
    * Set up a "busy" icon before dispatching the AjaxRequest
    *
    * Refer to do_dispatch() for parameters
    */
   dispatch: function(fnc_success, fnc_failure) {
      $('#busy-wait-icon').show();
      if (AjaxHandler.bol_busy) {
         var int_timeout = 1000;
      } else {
         var int_timeout = 1;
      }
      // Need to keep hold of 'this'
      var obj_THIS = this;
      setTimeout(function() {obj_THIS.do_dispatch(fnc_success, fnc_failure)}, int_timeout);
   },
   /**
    * Perform the AJAX request. On success, call a callback, as identified by the parameters. Pass
    * in the response object from the ajax call as a parameter to the callback.
    *
    * @param BaseIO|Function if mix is a function, call it. If it's an IO, call a method on it
    * @param String|null if passed "mix" is treated as a BaseIO, and this param indicates what method to call on "mix".
    */
   do_dispatch: function(fnc_success, fnc_failure) {
      AjaxHandler.bol_busy = true;
      var obj_THIS = this;
      $.ajax({
         async: obj_THIS.bol_async,
         type: "POST",
         url: obj_THIS.str_url,
         data: 'str_xml='+escape(obj_THIS.build_xml()),
         // If the AJAX call completed successfully
         success: function(obj_response) {
            AjaxHandler.bol_busy = false;
            // if the server-side script returned success
            if($('response', obj_response).attr('success') == 'true') {
               // If we've passed in an anonymous function into do_dispatch(), call it,
               // passing in the response object as a parameter.
               if (fnc_success) {
                  fnc_success(obj_response);
               }
            } else if($('response', obj_response).attr('success') == 'logged_out') {
               // user has been logged out, so tell them this is the case, wait for them to hit OK and then forward to the login screen
               alert('You have been logged out, possibly due to a period of inactivity.  Please click OK to be forwarded to the login screen.');
               window.location = '/auth/login';
            // server-side didn't return success
            } else {
               // If we've passed in an anonymous function into do_dispatch(), call it,
               // passing in the response object as a parameter.
               if (fnc_failure) {
                  fnc_failure(obj_response);
               } else {
                  obj_THIS.ajax_failure($('message', obj_response).text());
               }
            }
            $('#busy-wait-icon').hide();
         },
         // AJAX call didn't complete successfully
         error: function(obj_xmlhttp, str, exc) {
            AjaxHandler.bol_busy = false;
            $('#busy-wait-icon').hide();
            // If the request was interrupted by page navigation there will be no response
            if (obj_xmlhttp.responseText) {
               obj_THIS.ajax_failure('Sorry, there was a problem\n\n(Error code: AJAX-002)');
            }
         }
      });
   },
   /**
    * Alert user that the AJAX request failed
    *
    * @param String str_msg (Optional) Error message to display
    */
   ajax_failure: function(str_msg) {
      if (!str_msg) {
         str_msg = 'Sorry, there was a problem';
      }
      alert(str_msg);
   }
};
