function Request(function_name, opt_argv) 
{

  if (!opt_argv)
    opt_argv = new Array();
 
  // Find if the last arg is a callback function; save it
  var callback = null;
  var len = opt_argv.length;
  if (len > 0 && typeof opt_argv[len-1] == 'function') {
    callback = opt_argv[len-1];
    opt_argv.length--;
  }
  var async = (callback != null);
 
  // Build an Array of parameters, w/ function_name being the first parameter
  var params = new Array(function_name);
  for (var i = 0; i < opt_argv.length; i++) {
    params.push(opt_argv[i]);
  }
  var body = JSON.stringify(params);
 
  // Create an XMLHttpRequest 'POST' request w/ an optional callback handler 
      var req;
      if (window.XMLHttpRequest) { //Mozilla
          req = new XMLHttpRequest();
      }
      else { //IE
        req = new ActiveXObject("Microsoft.XMLHTTP"); //
      } 
  req.open('POST', '/rpc', async);
 
  req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  req.setRequestHeader("Content-length", body.length);
  req.setRequestHeader("Connection", "close");

  if (async) {
    req.onreadystatechange = function() {
      if(req.readyState == 4 && req.status == 200) {
        var response = null;
        try {
         response = JSON.parse(req.responseText);
        } catch (e) {
         response = req.responseText;
        }
        callback(response);
      }
    }
  }  	
 
  // Make the actual request
  req.send(body);
}

function Request_Get(function_name, opt_argv) {

      if (!opt_argv)
        opt_argv = new Array();
     
      // Find if the last arg is a callback function; save it
      var callback = null;
      var len = opt_argv.length;
      if (len > 0 && typeof opt_argv[len-1] == 'function') {
        callback = opt_argv[len-1];
        opt_argv.length--;
      }
      var async = (callback != null);
     
      // Encode the arguments in to a URI
      var query = 'action=' + encodeURIComponent(function_name);
      for (var i = 0; i < opt_argv.length; i++) {
        var key = 'arg' + i;
        var val = JSON.stringify(opt_argv[i]);
        query += '&' + key + '=' + encodeURIComponent(val);
      }
      query += '&time=' + new Date().getTime(); // IE cache workaround

      // Create an XMLHttpRequest 'GET' request w/ an optional callback handler 
      var req;
      if (window.XMLHttpRequest) { //Mozilla
          req = new XMLHttpRequest();
      }
      else { //IE
        req = new ActiveXObject("Microsoft.XMLHTTP"); //
      } 
      
      req.open('GET', '/rpc?' + query, async);
     
      if (async) {
        req.onreadystatechange = function() {
          if(req.readyState == 4 && req.status == 200) {
            var response = null;
            try {
             response = JSON.parse(req.responseText);
            } catch (e) {
             response = req.responseText;
            }
            callback(response);
          }
        }
      }
     
      // Make the actual request
      req.send(null);
    }


function InstallFunction(obj, name) 
{
  obj[name] = function() { Request(name, arguments); }
}

function InstallFunction_Get(obj, name) 
{
  obj[name] = function() { Request_Get(name, arguments); }
}

var server = {};
InstallFunction_Get(server, 'GetLevel');
InstallFunction(server, 'GetLevelHTML');
InstallFunction(server, 'AddLevel');
InstallFunction_Get(server, 'RemoveLevel');
InstallFunction_Get(server, 'MoveLevelUp');
InstallFunction_Get(server, 'MoveLevelDown');
InstallFunction_Get(server, 'GetLowestLevelResponse');
