var phpRequestSentCount = 0;

function phpRequest(objfn, fn, cls, location)
  {

  var xmlResponder;

  var parent = this;

  try
    {
    xmlResponder = new XMLHttpRequest ();
    }catch (dumb_browser_exception)
    {
    try
      {
      xmlResponder = new ActiveXObject ("Microsoft.XMLHTTP");
      }catch (yet_another_deal_with_ie_exception)
      {
      try
        {
        xmlResponder = new ActiveXObject ("Msxml2.XMLHTTP");
        } catch (give_up_now_exception)
        {
        alert('XML HTTP Request is not supported by your browser!');
        return;
        }
      }
    }

  if (typeof  xmlResponder.overrideMimeType != 'undefined')
    {
    xmlResponder.overrideMimeType("text/xml");
    }

  this.method = 'POST';

  this.setMethod = function(value)
    {
    this.method = value.toUpperCase();
    }

  this.setErrorHandler = function(fn)
    {
    this.errorHandler = fn;
    }

  this.handler = function()
    {
    if (xmlResponder.readyState != 4) { return; };

    phpRequestSentCount--;

    if (phpRequestSentCount == 0)
      {
      ttManager.clear();
      }

    if (xmlResponder.status != 200 && xmlResponder.status != 404)
      {
      if (parent.errorHandler == null)
        {
        alert(location + '\n' + xmlResponder.status + ': Unable to retrieve XML response document.');
        }else
        {
        parent.errorHandler.run(-1, xmlResponder.status);
        }
      return;
      }

    if (xmlResponder.status == 404)
      {
      return;
      }



    var errorNodes = xmlResponder.responseXML.getElementsByTagName('error');

    if (errorNodes.length != 0)
      {
      errorNodes = errorNodes[0].childNodes[0];
      var result = XMLtoVar(errorNodes);
      if (parent.errorHandler == null)
        {
        alert(result['message']);
        }else
        {
        parent.errorHandler.run(result['type'], result['message']);
        }
      return;
      }

    var result = null;

    try
      {
      var root = xmlResponder.responseXML.getElementsByTagName('result');
      root = root[0].childNodes[0];
      result = XMLtoVar(root);
      }catch(e)
      {
      if (document.location.hostname == "alpha.www.cs.rutgers.edu")
        {
        // alert("Unable to parse:\n"+xmlResponder.responseText);
        }
      }

    if (objfn != null)
      {
      objfn.run(result);
      }

    }

  this.run = function()
    {
    var args = new Array();
    for (var i = 0; i < arguments.length; i++)
      {
      args[i] = arguments[i];
      }

    var toSendHeaders = "cls="+escape(cls)+"&fn="+escape(fn);
    var postData = toSendHeaders + varToPostExport(args);

    xmlResponder.onreadystatechange = this.handler;
    if (this.method == 'GET')
      {
      xmlResponder.open (this.method, location+"?"+postData, true);
      }else
      {
      xmlResponder.open (this.method, location, true);
      }

    xmlResponder.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');


    if (this.method == 'POST')
      {
      xmlResponder.send (postData);
      }else
      {
      xmlResponder.send (null);
      }

    phpRequestSentCount++;
    ttManager.set('Processing. Please Wait...');
    }


  }



function XMLtoVar(node)
  {
  if (node == null)
    {
    return null;
    }

  var type = node.getAttribute('type');

  if (type == "string")
    {
    if (node.childNodes.length == 1)
      {
       return node.childNodes[0].nodeValue;
      }else
      {
      var ret = "";
      for(var i = 0; i < node.childNodes.length; i++)
        {
        ret = ret + node.childNodes[i].nodeValue;
        }
      return ret;
      }
    }else if (type == "array")
    {
    var result = new Array();

    for(var i = 0; i < node.childNodes.length; i++)
      {
      result[node.childNodes[i].getAttribute('key')] = XMLtoVar(node.childNodes[i].childNodes[0]);
      }

    return result;
    }

  }

function varToPostExport(variable, base)
  {
  if (variable == null) {return "";}

  if (base == null)
    {
    base = "input";
    }

  if (!(typeof variable == 'object'))
    {
    return "&"+base+"="+escape(variable);
    }else
    {
    var toReturn = '';
    for (i in variable)
      {
      toReturn = toReturn + varToPostExport(variable[i], base+"["+i+"]");
      }
    return toReturn;
    }
  }
