var g_trans_id = 0;

/* To do: change callback so that some 'standard' callback gets called,
    THEN that callback calls the desired callback
 */
function do_ajax(backend_php, callback, command, payload)
{
   g_trans_id++;
//   dBug("** sending (" + g_trans_id + ") " + command);
   var xml = "<\?xml version=\"1.0\"\?>";
   xml += _tag(K.TAG_REQUEST);
   if (command != null) {
      xml += _tag_(K.TAG_CMD, command);
   }
   xml += _tag_(K.TAG_TRANS_ID, (g_trans_id));
   xml += payload;
   xml += tag_(K.TAG_REQUEST);

   var el = document.getElementById("dump_xml_checkbox");

   if (el && el.value == "off") {
      alert(xml);
      return;
   }
   xml = "xml=" + urlencode(xml);

   var request = false;
   try {
      request = new XMLHttpRequest();
   } catch (trymicrosoft) {
      try {
         request = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (othermicrosoft) {
         try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (failed) {
            request = false;
         }
      }
   }

   if (!request)
   {  return null;
   }

   request.open("POST", backend_php, true);
   request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

   request.onreadystatechange = function() {
      if (this.readyState == 4) 
      {  
         if (this.status == 200) 
         {  
            var retval = new Object();
            var d = this.responseXML;

            if (!d)
            {  alert("no response XML!");
               return;
            }

            retval.doc = d;
            retval.raw = this.responseText;
            var node = d.getElementsByTagName(K.TAG_TRANS_ID)[0];
            if (node) {  
               retval.trans_id = node.childNodes[0].nodeValue;
            } 

            if (K.TEST_SERVER) {
               node = d.getElementsByTagName(K.TAG_DEBUG)[0];
               if (node) {
                  entries = d.getElementsByTagName(K.TAG_DEBUG_LINE);
                  for (i = 0; i < entries.length; i++) {
                     dBug(entries[i].childNodes[0].nodeValue);
                  }
               }
            }

            node = d.getElementsByTagName(K.TAG_RESPONSE_STATUS)[0];
            if (!node ||  node.childNodes[0].nodeValue != K.TAG_SUCCESS) {
               msg = "XML Communications error";
      // only show the details of the error when in debug mode.
      //  the server should also be respecting this setting
               if (K.TEST_SERVER)
               {  msg += ": ";
                  node = d.getElementsByTagName(K.TAG_RESPONSE_ERROR)[0];
                  if (node)
                  {  msg += node.childNodes[0].nodeValue;
                  }
                  else
                  {  err = '???';
                  }
               }
               alert(msg);
               return;
            }
// ?? TODO - revisit
            node = d.getElementsByTagName('ResponseError')[0];
            if (node)
            {  retval.command_error = node.childNodes[0].nodeValue;
            }
            else
            {  retval.command_error = '';
            }

            node= d.getElementsByTagName('Command');
            if (node && node[0] && node[0].childNodes[0])
            {  retval.command = node[0].childNodes[0].nodeValue;
            }
            else
            {  retval.command = '';
            }

            node = d.getElementsByTagName(K.TAG_RESPONSE_RESULT)[0];
            if (node &&  node.childNodes[0].nodeValue == K.TAG_SUCCESS)
            {  retval.command_ok = true;
            }
            else
            {  retval.command_ok  = false;
               var msg = "Error: ";
               node = d.getElementsByTagName(K.TAG_RESPONSE_ERROR)[0];
               if (node)
               {  msg += node.childNodes[0].nodeValue;
               }
               alert(msg);
            }

            if (retval.command_ok && retval.response_ok)
            {  retval.is_ok = true;
            }
            else
            {  retval.is_ok = false;
            }

//            dBug("-------->> process (" + retval.trans_id + ") START  ==");
            callback(retval);
//            dBug("<<-------- process (" + retval.trans_id + ")  END   ==");
         }
      }
   }

//   r.requester.setRequestHeader("Content-Length", xml.length);
   request.send(xml);
//   dBug("-- sending (" + g_trans_id + ") " + command + ": DONE  --");

//   g_trans_id++;
//   g_send_guard = 0;

}


function make_new_ajax_request(backend_php, callback)
{
   retval = new Object();

   var request = false;
   try {
      request = new XMLHttpRequest();
   } catch (trymicrosoft) {
      try {
         request = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (othermicrosoft) {
         try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (failed) {
            request = false;
         }
      }
   }

   if (!request)
   {  return null;
   }

   retval.requester = request;
   retval.backend_php = backend_php;
   retval.callback = callback;

	return retval; //returns null if no ajax support
}

function _tag(str) {  return "<" + str + ">"; }
function tag_(str) {  return "</" + str + ">"; }
function _tag_(str, payload) {  
   return "<" + str + ">" + xml_escape(payload) + "</" + str + ">"; 
}

var g_send_guard = 0;

function send_ajax_request(r, command, payload)
{
   if (g_last_trans_process != null)
   {
      if (g_last_trans_process + 1 < g_trans_id) {
         return;
      }

   }

//   if (g_send_guard) { dBug("******** HWAASDA *********"); return; }
//   else g_send_guard = 1;

//   dBug("** sending (" + g_trans_id + ") " + command + ": START **");
   var xml = "<\?xml version=\"1.0\"\?>";
   xml += _tag(K.TAG_REQUEST);
   xml += _tag_(K.TAG_CMD, command);
   xml += _tag_(K.TAG_TRANS_ID, (g_trans_id));
   xml += payload;
   xml += tag_(K.TAG_REQUEST);
   xml = "xml=" + urlencode(xml);


   r.requester.open("POST", r.backend_php, true);
   r.requester.onreadystatechange = r.callback;
   r.requester.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//   r.requester.setRequestHeader("Content-Length", xml.length);
   r.requester.send(xml);
//   dBug("-- sending (" + g_trans_id + ") " + command + ": DONE  --");

   g_trans_id++;
   g_send_guard = 0;
}

// this should be impl as an object!

function process_ajax_response(r_in)
{  var r = r_in.requester;
   if (r.readyState == 4) 
   {
      if (r.status == 200) 
      {
         var retval = new Object();
//         retval.raw = r.responseText;

         var d = r.responseXML;

         if (!d)
         {  dBug("no response XML!");
            return null;
         }
         retval.doc = d;

         var node = d.getElementsByTagName(K.TAG_TRANS_ID)[0];
         if (node)
         {  retval.trans_id = node.childNodes[0].nodeValue;
            dBug("== process (" + retval.trans_id + ")  ==");
         } 

         node = d.getElementsByTagName('Debug')[0];
         if (node)
         {
            var entries = d.getElementsByTagName('DebugLine');
            for (i = 0; i < entries.length; i++)
            {
               dBug(entries[i].childNodes[0].nodeValue);
            }
         }

         node = d.getElementsByTagName(K.TAG_RESPONSE_STATUS)[0];
         if (!node ||  node.childNodes[0].nodeValue != K.TAG_SUCCESS)
         {
            var msg = "XML Communications error";
   // only show the details of the error when in debug mode.
   //  the server should also be respecting this setting
            if (K.TEST_SERVER)
            {  msg += ": ";
               node = d.getElementsByTagName(K.TAG_RESPONSE_ERROR)[0];
               if (node)
               {  msg += node.childNodes[0].nodeValue;
               }
               else
               {  err = '???';
               }
            }
            dBug(msg);
            return null;
         }

         node = d.getElementsByTagName('ResponseError')[0];
         if (node)
         {  retval.command_error = node.childNodes[0].nodeValue;
         }
         else
         {  retval.command_error = '';
         }

         node= d.getElementsByTagName('Command')[0];
         if (node)
         {  retval.command = node.childNodes[0].nodeValue;
         }
         else
         {  retval.command = '';
         }

         node = d.getElementsByTagName('Result')[0];
         if (node &&  node.childNodes[0].nodeValue == K.TAG_SUCCESS)
         {  retval.command_ok = true;
         }
         else
         {  retval.command_ok  = false;
         }

         if (retval.command_ok && retval.response_ok)
         {  retval.is_ok = true;
         }
         else
         {  retval.is_ok = false;
         }
         return retval;
      }
   }
   return null;
}

//function get_ajax

function node_val(n)
{  if (n.firstChild && n.firstChild.nodeValue)
   {  return n.firstChild.nodeValue;
   }
   return "";
}

function get_xml_value_null(d, tagname)
{  if (!d)
   {  return null;
   }
   var s = d.getElementsByTagName(tagname)
   if (!s)
   {  return null
   }
   node = s[0];
   if (!node)
   {  return null;
   }
   if (!node.childNodes[0])
   {  return null;
   }
   return node.childNodes[0].nodeValue;
}

function get_xml_value(d, tagname)
{  
   if (!d)
   {  return null;
   }
   var s = d.getElementsByTagName(tagname)
   if (!s)
   {  return null
   }
   node = s[0];
   if (!node)
   {  return '';
   }
   if (!node.childNodes[0])
   {  return '';
   }
   return node.childNodes[0].nodeValue;
}


