function ajax(options){
  options={
    method: options.method || "GET",
    type: options.type || "html",
    url: options.url || "",
    timeout:options.timeout || 5000,
    onComplete: options.onComplete || function(){},
    onError: options.onError || function(){ },
    onSuccess: options.onSuccess || function(){},
    data: options.data || ""
  };

  if( typeof XMLHttpRequest == "undefined" ){
    XMLHttpRequest = function(){
      return new ActiveXObject(navigator.userAgent.indexOf("MSIE 5") >=0 ? "Microsoft.XMLHTTP":"Msxml2.XMLHTTP");
    }
  }


  var xml = new XMLHttpRequest();
  xml.open( options.method, options.url, true );

  var timeoutLength=options.timeout;
  var requestDone=false;
  setTimeout( function(){ requestDone=true }, timeoutLength);

  xml.onreadystatechange = function() {
    if(xml.readyState==4 && !requestDone){
      if( httpSuccess(xml) ) options.onSuccess( httpData(xml,options.type) ); else options.onError();
      options.onComplete();
      xml=null;
    }
  };
  xml.send(null);

  function httpSuccess(r){
    try{
      return !r.status && location.protocol=="file:" || (r.status>199 && r.status<300) || r.status==304 || navigator.userAgent.indexOf("Safari")>=0 && typeof r.status=="undefined";
    } catch(e){}
    return false;
  }

  function httpData(r,type){
    var ct=r.getResponseHeader("content-type");
    var data= !type && ct && ct.indexOf("xml")>=0;
    data = (type == "xml" || data) ? r.responseXML:r.responseText;
    if(type=="script") eval.call(window,data);
    return data;
  }
}

function serialize(a){
  var s = [];
  if(a.constructor == Array){
    for(var i = 0; i < a.length; i++) s.push(a[i].name + "=" + encodeURIComponent(a[i].value) );
  } else {
    for (var j in a) s.push(j + "=" + encodeURIComponent(a[j]) );
  }
  return s.join("&");
}