
function Ajax(doneHandler, failHandler, eval_res)
{
  newAjax = this;
  this.onDone = doneHandler;
  this.onFail = failHandler;
  this.transport = this.getTransport();
  this.transport.onreadystatechange = ajaxTrampoline(this);
  this.eval_res = eval_res;
}

Ajax.prototype.get = function (uri, query, force_sync)
{
  // Firefox doesn't call onDone and onFail handlers if you force_sync
  force_sync = force_sync || false;
  if( typeof query != 'string' )
    query = ajaxArrayToQueryString(query);
  fullURI = uri+(query ? ('?'+query) : '');
  
  this.transport.open('GET', fullURI, !force_sync );
  // Set header so the called script knows that it's an XMLHttpRequest
	this.transport.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  this.transport.send('');
}

Ajax.prototype.post = function (uri, data, force_sync)
{
  force_sync = force_sync || false;
  if( typeof data != 'string' )
    data = ajaxArrayToQueryString(data);
  var post_form_id=ge('post_form_id');
  if (post_form_id)
    data+='&post_form_id='+post_form_id.value;
  this.transport.open('POST', uri, !force_sync);
  this.transport.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  // Set header so the called script knows that it's an XMLHttpRequest
	this.transport.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  this.transport.send(data);
}

Ajax.prototype.stateDispatch = function ()
{
  if( this.transport.readyState == 1 && this.showLoad )
    ajaxShowLoadIndicator();
  
  if( this.transport.readyState == 4 ) {
    if( this.showLoad )
      ajaxHideLoadIndicator();
    if( this.transport.status >= 200 &&
        this.transport.status < 300) {
		if(this.eval_res) this.parseResponse();
		if( this.onDone ) this.onDone(this, this.transport.responseText);
    } else {
		if( this.onFail ) this.onFail(this, this.transport.responseText);
    }
  }
}

Ajax.prototype.getTransport = function ()
{
  var ajax = null;
  
  try { ajax = new XMLHttpRequest(); }
  catch(e) { ajax = null; }
  
  try { if(!ajax) ajax = new ActiveXObject("Msxml2.XMLHTTP"); }
  catch(e) { ajax = null; }
  
  try { if(!ajax) ajax = new ActiveXObject("Microsoft.XMLHTTP"); }
  catch(e) { ajax = null; }
  
  return ajax;
}

Ajax.prototype.collect = function (arr, func)
{
  var n = [];
  for(var i = 0; i < arr.length; i++) {
    var v = func(arr[i]);
    if (v != null) n.push(v);
  }
  return n;
}

Ajax.prototype.serialize = function (form)
{
  var result = new Array();
  var g = function(n) {
    return form.getElementsByTagName(n)
  };
  var nv = function(e){
    if (e.name) result[e.name] = e.value;
  };
  this.collect(g('input'), function(i) {
    if ((i.type != 'radio' && i.type != 'checkbox') || i.checked) return nv(i);
  });
  this.collect(g('select'), nv);
  this.collect(g('textarea'), nv);
  return result;
}

function ajaxTrampoline(ajaxObject)
{
  return function () { ajaxObject.stateDispatch(); };
}

function ajaxArrayToQueryString(queryArray)
{
  var sep = '';
  var query = "";
  
  for( var key in queryArray ) {
    query = query +
      sep +
      encodeURIComponent(key) +
      '=' +
      encodeURIComponent(queryArray[key]);
    sep = '&';
  }
  return query;
}

var ajaxLoadIndicatorRefCount = 0;

function ajaxShowLoadIndicator()
{
  indicatorDiv = ge('ajaxLoadIndicator');
  if( !indicatorDiv ) {
    indicatorDiv = document.createElement("div");
    indicatorDiv.id = 'ajaxLoadIndicator';
    indicatorDiv.innerHTML = 'Loading';
    indicatorDiv.className = 'ajaxLoadIndicator';
    document.body.appendChild(indicatorDiv);
  }
  
  indicatorDiv.style.top = (5 + pageScrollY()) + 'px';
  indicatorDiv.style.left = (5 + pageScrollX()) + 'px';
  indicatorDiv.style.display = 'block';
  ajaxLoadIndicatorRefCount++;
}

function ajaxHideLoadIndicator()
{
  ajaxLoadIndicatorRefCount--;
  if( ajaxLoadIndicatorRefCount == 0 )
    ge('ajaxLoadIndicator').style.display = '';
}

Ajax.prototype.parseResponse = function()
{
	if(!this.transport || !this.transport.responseText)return;
    var response = this.transport.responseText.replace(/^[\s\n]+/g, '');

    if(response.substr(0,10)=="<noscript>")
    {
		try{
			var arr = response.substr(10).split("</noscript>");
			eval(arr[0]);
			this.transport.responseText = arr[1];
		}catch(e){
		}
    }else{}
}

