var HTTP = {};

HTTP._factories = [
  function() { return new XMLHttpRequest(); },
  function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
  function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
];

HTTP._factory = null;

HTTP.newRequest = function() {
  if (HTTP._factory != null) return HTTP._factory();
  
  for (var i=0; i < HTTP._factories.length; i++) {
    try {
      var factory = HTTP._factories[i];
      var request = factory();
      if (request != null) {
        HTTP._factory = factory;
        return request;
      }
    } catch(e) {
      continue;
    }
  }
  HTTP._factory = function() {
    throw new Error("XMLHttpRequest not supported");
  }
  HTTP._factory();
}

HTTP.getFormValues = function(formname) {
  var values = Array()
  var form = document.getElementById(formname)
  for (var i=0; i<form.elements.length; i++) {
    values[form.elements[i].name] = form.elements[i].value;
  }
  values['sendform'] = 1;
  return values;
}

HTTP.encodeFormData = function(data) {
  var pairs = [];
  var regexp = /%20/g;
  
  for (var name in data) {
    var value = data[name].toString();
    var pair = encodeURIComponent(name).replace(regexp,"+") + "=" + encodeURIComponent(value).replace(regexp, "+");
    pairs.push(pair);
  }
  return pairs.join("&");
}

HTTP._getResponse = function(request) {
  switch(request.getResponseHeader("Content-Type")) {
    case "text/xml":
      return request.responseXML;
    
    case "text/json":
    case "text/javascript":
    case "application/javascript":
    case "application/x-javascript":
      return eval('(' + request.responseText + ')');
    
    default:
      return request.responseText;
    
  }
}

HTTP.get = function(url, callback, options) {
  var request = HTTP.newRequest();
  var n = 0;
  var timer;
  
  if (options.timeout) {
    timer = setTimeout(function() {
      request.abort();
      if (options.timeoutHandler) {
        options.timeoutHandler(url);
      }
    },
    options.timeout);
  }
  
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      if (timer) {
        clearTimeout(timer);
      }
      if (request.status == 200) {
        callback(HTTP._getResponse(request));
      } else {
        if (options.errorHandler) {
          options.errorHandler(request.status, request.statusText);
        } else {
          callback(null);
        }
      }
    } else if (options.progressHandler) {
      options.progressHandler(++n);
    }
  }
  
  var target = url;
  if (options.parameters) {
    target += "?" + HTTP.encodeFormData(options.parameters);
  }
  request.open("GET", target, true);
  request.send(null);
}

HTTP.post = function(url, values, callback, errorHandler) {
  var request = HTTP.newRequest();
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      if (request.status == 200) {
        
        callback(HTTP._getResponse(request));
      } else {
        if (errorHandler) {
          errorHandler(request.status, request.statusText);
        } else {
          callback(null);
        }
      }
    }
  }
  request.open("POST", url, true);
  request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  request.send(HTTP.encodeFormData(values));
}