// Powered by: Dm. Grigorjev
//   http://weblancer.net/users/dimgel
//   http://dimgel.ru

if (window.ActiveXObject && !window.XMLHttpRequest) {
    window.XMLHttpRequest = function() {
        var progIds = new Array("Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP");
        for (i in progIds) {
            try {
                return new ActiveXObject(progIds[i]);
            }
            catch(ex) {
            }
        }
        return null;
    };
}

if (!window.dimgel) { window.dimgel = {}; };

window.dimgel.ajax = {

// PUBLIC:

    request: function(url, post, callback, tag, timeout, loopdelay) {
        if (!window.XMLHttpRequest) {
            callback(null, tag, -1, 'Not supported by browser.', null);
            return null;
        }
        var id = ++this._lastid;
        var r = {id: id, url: url, post: post, callback: callback, tag: tag, timeout: (timeout ? timeout : 30), loopdelay: loopdelay, xhr: null, refresh: false};
        this._requests.push(r);
        this._exec(r);
        return id;
    },
    
    changeurl: function(id, url, post) {
        var i = this._findidindex(id);
        if (i < 0) {
            return;
        }
        var r = this._requests[i];
        r.url = url;
        r.post = post;
    },
    
    refresh: function(id, force) {
        var i = this._findidindex(id);
        if (i < 0) {
            return;
        }
        var r = this._requests[i];
        if (force || r.laststate < 0) {
            this._cleanup(r);
            this._exec(r);
        }
        else {
            r.refresh = true;
        }
    },
    
    remove: function(id) {
        var i = this._findidindex(id);
        if (i < 0) {
            return;
        }
        var r = this._requests[i];
        this._requests.splice(i, 1);
        this._cleanup(r, true);
    },
    
// PRIVATE:
    
    _lastid: 0,
    _requests: new Array(),
    
    _findidindex: function(id) {
        for (var i = 0;  i < this._requests.length;  i++) {
            if (this._requests[i].id == id) {
                return i;
            }
        }
        return -1;
    },
    
    _exec: function(r) {
        var id = r.id;
        r.xhr = new XMLHttpRequest();
        r.xhr.onreadystatechange = function() { window.dimgel.ajax._onreadystatechange(id); };
        r.xhr.open(r.post ? "POST" : "GET", r.url, true);
        r.laststate = 0;
        r.timeoutid = setTimeout("window.dimgel.ajax._ontimeout(" + id + ")", r.timeout * 1000)
        r.xhr.send(r.post);
    },
    
    _cleanup: function(r, abort) {
        var ls = r.laststate;
        r.laststate = -1;
        if (r.timeoutid) {
            clearTimeout(r.timeoutid);
            r.timeoutid = null;
        }
        if (ls >= 0) {
            delete r.xhr['onreadystatechange'];
            if (abort && r.xhr.abort) {
                r.xhr.abort();
            }
            delete r['xhr'];
        }
    },

    _onreadystatechange: function(id) {
        var i = this._findidindex(id);
        if (i < 0) {
            return;
        }
        var r = this._requests[i];
        if (!r.xhr) {
            return;
        }
        var readyState = r.xhr.readyState;
        if (r.laststate < 0) {
            return;
        }
        r.laststate = r.xhr.readyState;
        if (r.xhr.readyState != 4) {
            return;
        }
        var status = r.xhr.status;
        var responseText = r.xhr.responseText;
        var responseXML = r.xhr.responseXML;
        this._cleanup(r);
        if (r.refresh) {
            r.refresh = false;
            window.dimgel.ajax.refresh(id, true);
        }
        else if (r.loopdelay > 0) {
            r.timeoutid = setTimeout("window.dimgel.ajax.refresh(" + r.id + ", false)", r.loopdelay * 1000);
        }
        else {
            this._requests.splice(i, 1);
        }
        r.callback(id, r.tag, status, responseText, responseXML);
    },
    
    _ontimeout: function(id) {
        var i = this._findidindex(id);
        if (i < 0) {
            return;
        }
        var r = this._requests[i];
        if (r.laststate < 0) {
            return;
        }
        this._cleanup(r, true);
        if (r.refresh) {
            r.refresh = false;
            window.dimgel.ajax.refresh(id, true);
        }
        else if (r.loopdelay > 0) {
            r.timeoutid = setTimeout("window.dimgel.ajax.refresh(" + r.id + ", false)", r.loopdelay * 1000);
        }
        else {
            this._requests.splice(i, 1);
        }
        r.callback(id, r.tag, -2, 'Request timed out.', null);
    }
};

function ajax_request(url, post, callback, tag, timeout, loopdelay)
{
  return window.dimgel.ajax.request(url, post, callback, tag, timeout, loopdelay);
}