/*****************************
/*
/* XMLHTTPRequest/AJAX Library
/* 2006, Akop Karapetyan
/*       www.akop.org
/*
/*****************************/

function _escape(str)
{
//  return escape(str);
  return encodeURIComponent(str);
}

function _unescape(str)
{
//  return unescape(str);
  return decodeURIComponent(str);
}

/*************
/* CONSTRUCTOR
/*************/

function AjaxRequest(target, query, method)
{
    if (window.ActiveXObject)
    {
        this.browser = "ie";
        this.xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest)
    {
        this.browser = "mozilla";
        this.xmlreq = new XMLHttpRequest();

        if (this.xmlreq.overrideMimeType) 
            this.xmlreq.overrideMimeType("text/xml");
    }
    else throw "XMLHttpRequest support not detected";

    if (target != null)
        this.target = target;

    if (query != null)
        this.query = query;

    if (method != null)
        this.method = method;
}

new AjaxRequest();

/*************
/* STATIC MEMBERS
/*************/

// Called when the state of the request changes

function onReadyStateChange(request)
{
    if (request.xmlreq.readyState == 4)
    {
        if (request.xmlreq.status != 200)
            throw request.xmlreq.statusText;

        request.parseXML();
        request.onReady(request);
    }
}

AjaxRequest.onReadyStateChange = onReadyStateChange;

/*************
/* FIELDS
/*************/

// Request URL. For GET requests, it may include the querystring portion ("?key=value&...")
// If the GET method is selected and the querystring portion is not included in the target URL,
// it will be set automatically. This makes it easier to switch between GET and POST requests

AjaxRequest.prototype.target = null;

// Submission method. GET or POST

AjaxRequest.prototype.method = "POST";

// Asynchronous request flag. True = asynchronous request

AjaxRequest.prototype.async = true;

// Any extra information to associate with the request. This information is not sent to the server,
// but will be available when onReady is called

AjaxRequest.prototype.userData = null;

// Response XMLDocument object. Not available until onReady is called

AjaxRequest.prototype.xml = null;

// Request query string to be sent to the server
// Note that "query" field takes precedence over the "params" field

AjaxRequest.prototype.query = null;

// In addition, instead of specifying a query string, you can specify individual name/value pairs
// (in form of obj.params[name]=value). These will be converted to a query string automatically.
// Note that "query" field takes precedence over the "params" field

AjaxRequest.prototype.params = new Array();

/*************
/* CALLBACKS 
/*************/

// This function receives "Ready" notifications,
// along with the original AjaxRequest object

function onReady(ajaxRequest)
{
}

AjaxRequest.prototype.onReady = onReady;

/*************
/* METHODS
/*************/

// Sends request to the server

function send()
{
    var req = this;
    var target = this.target;
    var query = this.getQueryString();

    if (this.method == "GET" && target.indexOf("?") < 0 && query.length > 0)
        target += "?" + query;

    this.xmlreq.open(this.method, target, this.async);
    this.xmlreq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    this.xmlreq.onreadystatechange = function() { AjaxRequest.onReadyStateChange(req); };

    this.xmlreq.send(this.method == "POST" ? query : null);
}

AjaxRequest.prototype.send = send;

// Returns the actual query string associated with the request

function getQueryString()
{
    if (this.query != null)
        return this.query;
    else
    {
        var query = "";

        for (key in this.params)
            query += _escape(key).replace(/\+/g, "%2b") 
                + "=" + _escape(this.params[key]).replace(/\+/g, "%2b") + "&";

        return query.replace(/&*$/g, "");
    }
}

AjaxRequest.prototype.getQueryString = getQueryString;

// Performs any necessary initialization of the XML response
// For IE, this means parsing the text version and creating an XML document

function parseXML()
{
    if (this.browser == "ie")
    {
        this.xml = new ActiveXObject("MSXML.DomDocument");
        this.xml.loadXML(this.xmlreq.responseText);
    }
    else if (this.browser == "mozilla")
    {
        this.xml = this.xmlreq.responseXML;
    }
}

AjaxRequest.prototype.parseXML = parseXML;

