var loaded_texts = {};
var queue_funcs = {};
var queue_params = {};
var queue_i = {};

/**
 * Вот она - главная функция аякса, впрочем и единстевнная.
 * Она работает очень просто: ты передаешь ей адрес запроса, функцию-обработчик 
 * и параметры обработчика
 * (если они есть). 
 *
 * ПРИМЕР: у тебя есть php файл "alright.php" , 
 *                он возвращает "ok" или "failed" (просто делает echo).
 *            Например ты хочешь его где-то вызвать. Пишешь следующее:
 * 
 *            // это сам вызов - второй параметр - функция-обработчик:
 *            do_ajax2_request('alright.php?tell=me', "got_alright");
 *            
 *            // а вот сама функция обработчик:
 *            function got_alright(txt){
 *                // txt - это тот самый текст, который напечатал alright. Это может быть все что угодно,
 *                // хоть огромный HTML текст. Но в нашем случае мы ожидаем "ok" или "falied":
 *                if(txt=='ok')
 *                    alert("Все ОК!");
 *                else if(txt=='failed')  
 *                    alert("Все обломалось...");
 *                else    
 *                    alert("Что-то неожиданное.");
 *            }
 * 
 * Можно делать хоть сто одновременных аяксов - все будет правильно работать, 
 * каждый запрос будет вызывать своего обработчика правильно, даже если это 
 * один обработчик.
 */
function do_ajax2_request(request_url, return_function, ret_func_additional_parameters) {
    if (return_function == undefined) return_function = '';
    if (ret_func_additional_parameters == undefined) ret_func_additional_parameters = '';
    if (loaded_texts[request_url] != undefined) {
        if (loaded_texts[request_url] != 'queue') {
            if (!queue_i[request_url]) {    
                // we do not have the stack - but we have cache - sending it immediately:
                ajax_process_loaded_info(
                    loaded_texts[request_url], 
                    return_function, 
                    ret_func_additional_parameters,
                    request_url
                );
            } else {
                // it is loaded already before  - so we can send the cache (using queued stack):                
                for (var i=0; i < queue_i[request_url]; ++i){
                    ajax_process_loaded_info(
                        loaded_texts[request_url], 
                        queue_funcs[request_url][i], 
                        queue_params[request_url][i],
                        request_url
                    );                  
                }   
                queue_i[request_url] = 0;
            }   
            return;
        } else { 
            // if(loaded_texts[request_url] == 'queue')
            // this url seems to be loading now. so I gotta put this ret_func with its
            // parameters on queue - into the stack:
            if (queue_funcs[request_url] == undefined){
                queue_funcs[request_url] = [];
                queue_params[request_url] = [];
                queue_i[request_url] = 0;
            }
            // pushing
            queue_funcs[request_url][queue_i[request_url]] = return_function;
            queue_params[request_url][queue_i[request_url]] = ret_func_additional_parameters;
            queue_i[request_url]++;
            return;
        }
    }
    
    var xmlhttp = false;
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
     try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
     } catch (e) {
        try {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            xmlhttp = false;
        }
     }
    @end @*/
    if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
        xmlhttp = new XMLHttpRequest();
    }
    xmlhttp.open("GET", request_url, true);
    loaded_texts[request_url] = 'queue';
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState != 4) return;
        loaded_texts[request_url] = xmlhttp.responseText;
        do_ajax2_request(request_url);
    }                       
    do_ajax2_request(request_url, return_function, ret_func_additional_parameters);
    xmlhttp.send(null);                     
}       

function ajax_process_loaded_info(ajax_text, return_function, ret_func_additional_parameters, request_url) {
    if (!return_function) return false;
    
    if (ret_func_additional_parameters != '') {
        ret_func_additional_parameters = ', '+ret_func_additional_parameters;
    }
    
    if (return_function instanceof Function) {
        return_function(ajax_text);
    } else {
        eval(return_function+'(ajax_text'+ret_func_additional_parameters+')');
    }
}