var TIMEOUT = 5000;

function ajaxlib_setDebugVisible(visible) {
    if((ajaxlib_debugdiv == undefined) != visible)
        return;
    if(visible) {
        ajaxlib_debugdiv = document.createElement('div');
        ajaxlib_debugdiv.style.position = 'absolute';
        ajaxlib_debugdiv.style.top = '100px';
        ajaxlib_debugdiv.style.left = '100px';
        ajaxlib_debugdiv.style.borderStyle = 'solid';
        ajaxlib_debugdiv.style.backgroundColor = 'white';
        ajaxlib_debugdiv.style.height = '300px';
        ajaxlib_debugdiv.style.overflow = 'auto';
        document.body.appendChild(ajaxlib_debugdiv);
    } else {
        document.body.removeChild(ajaxlib_debugdiv);
        ajaxlib_debugdiv = undefined;
    }
}

var ajaxlib_debugdiv = undefined;

function ajaxlib_debug(message) {
    if(ajaxlib_debugdiv == undefined)
        return;
    ajaxlib_debugdiv.innerHTML += '<br />'+message;
}

function ajaxlib_object_request(url, loadedFunction, loadingFunction) {
    this.id = ++ajaxlib_currentRequestId;
    ajaxlib_requests[this.id] = this;
    this.url = url;
    this.loadingFunction = (loadingFunction == undefined)?ajaxlib_defaultLoadingFunction:loadingFunction;
    this.loadedFunction = (loadedFunction == undefined)?ajaxlib_defaultLoadedFunction:loadedFunction;
    this.iframe = undefined;
    this.status = 'stopped';
    
    this.start = function() {
        if(this.status != 'stopped')
            return;
            
        ajaxlib_debug(this.url + ': start()');
        
        this.status = 'started';
        this.loadingFunction();
        
        if(ajaxlib_workingdiv == undefined)
            ajaxlib_createWorkingDiv();
        
        if(false) {
            this.iframe = document.createElement('iframe');
            this.iframe.id = 'ajaxlib_iframe_'+this.id;
            var this_workaround = this; //XXX is there a better way? something like ajaxlib_object_request.this?
            this.iframe.onload = function() { ajaxlib_debug('actually i did load'); this_workaround.loaded(); };
            this.iframe.src = this.url;
            this.iframe.style.display = 'none';
            this.iframe.style.visibility = 'hidden';
            this.iframe.style.height = '1px';
            ajaxlib_workingdiv.appendChild(this.iframe);
        } else {
            var iframestr = '<iframe id = "ajaxlib_iframe_'+this.id+'" onload="ajaxlib_requests['+this.id+'].loaded();" src="'+this.url+'" style="display: none; visibility: hidden; height: 1px;"></iframe>';
            var div = document.createElement('div');
            div.innerHTML += iframestr;
            ajaxlib_workingdiv.appendChild(div);
            this.iframe = document.getElementById('ajaxlib_iframe_'+this.id);
        }
    }
    
    this.loaded = function() {
        if(this.status != 'started') {
            ajaxlib_debug(this.url + ': loaded() ignored');
            return;
        }
        if(this.iframe == undefined) {
            alert('error in ajaxlib.js\nrequest complete, but iframe not defined');
            return;
        }
        ajaxlib_debug(this.url + ': loaded()');
        this.status = 'completed';
        this.loadedFunction(this.iframe.contentWindow.document);
    }
    
    this.retry = function() {
        ajaxlib_debug(this.url + ': retry()');
        this.iframe.src = this.iframe.src; // I don't like this for reloading, but it works though. and other tricks don't
        setTimeout('ajaxlib_checkStatus("'+this.id+'")', TIMEOUT);
    }
    
    this.cancel = function() {
        ajaxlib_debug(this.url + ': cancel()');
        this.status = 'completed';
        this.destroy();
    }
    
    this.destroy = function() {
        if(status == 'destroyed')
            return;
        ajaxlib_debug(this.url + ': destroy()');
        if(this.iframe != undefined) {
            ajaxlib_workingdiv.removeChild(this.iframe.parentNode);
            this.iframe = undefined;
        }
        if(ajaxlib_requests[this.id] != undefined)
            delete ajaxlib_requests[this.id];
        this.status = 'destroyed';
    }
}

var ajaxlib_currentRequestId = 0;
var ajaxlib_requests = new Array();
var ajaxlib_workingdiv = undefined;
var ajaxlib_defaultLoadingFunction = function() {};
var ajaxlib_defaultLoadedFunction = function() {};

function ajaxlib_setDefaultLoadingFunction(f) { ajaxlib_defaultLoadingFunction = f; }
function ajaxlib_setDefaultLoadedFunction(f) { ajaxlib_defaultLoadedFunction = f; }

function ajaxlib_makeRequest(url, toleranceTime, loadedFunction, loadingFunction) {
    var req = new ajaxlib_object_request(url, loadedFunction, loadingFunction);
    if((toleranceTime == undefined) || (toleranceTime == 0))
        ajaxlib_startRequest(req.id);
    else
        setTimeout('ajaxlib_startRequest("'+req.id+'")', toleranceTime); //TODO strip chars in url
}

function ajaxlib_startRequest(id) {
    if(ajaxlib_requests[id] == undefined)
        return;
    ajaxlib_requests[id].start(); //starts the request
    setTimeout('ajaxlib_checkStatus("'+id+'")', TIMEOUT); //timeout for the request - the request is started again in case of timeout
}

function ajaxlib_checkStatus(id) {
    if(ajaxlib_requests[id] == undefined)
        return;
    switch(ajaxlib_requests[id].status) {
        case 'stopped':
        case 'started':
            ajaxlib_requests[id].retry();
            break;
        case 'completed':
            ajaxlib_requests[id].destroy();
            break;
        case 'destroyed':
            break;
    }
}

function ajaxlib_createWorkingDiv() {
    ajaxlib_workingdiv = document.createElement('div');
    document.body.appendChild(ajaxlib_workingdiv);
}

function ajaxlib_cancelAll(regexp) {
    if(regexp == undefined)
        regexp = /.*/;
    for(i in ajaxlib_requests)
        if(ajaxlib_requests[i].url.match(regexp))
            ajaxlib_requests[i].cancel();
}