/*
    ajax.js, (c) fv.cz <devel@fv.cz>
    -- prace s AJAX (Asynchronous JavaScript and XML)
    --
    -- rev.0.6, 21.03.2008, 09:27, smid  :: *ajax_{GET|POST} callback: onLoad, onComplete, onError
    -- rev.0.5, 02.03.2008, 23:39, j3nda :: +callback: onLoad, onComplete, onError
    -- rev.0.4, 17.10.2007, 18:34, j3nda :: *ajax_{GET|POST}
    -- rev.0.3, 17.10.2007, 12:49, j3nda :: *ajax_envelopeFORM()
    -- rev.0.2, 15.10.2007, 16:44, j3nda :: +ajax_{GET|POST}, +ajax_envelope{ID|FORM}, @ajax_replace()
    -- rev.0.1, 31.05.2006, 13:49, j3nda :: revize souboru (via: 'www.jantichy.cz/vyuka/izi228/javascript' && 'ajax.js' <dennis.fridrich@visiontech.cz>)

    TODO: lepsi validade FORMulare ohledne .value hodnoty pro starsi prohlizece, ktere tuto moznost nemaji
    TODO: http://www.quirksmode.org/js/forms.html

    ======
    v pripade, ze se vola ajax_{GET|POST} vcetne funkce na 'callback', je nutne
    zajistit spravne vykonani "naseho" kodu v pripade, ze se pozadavek (ne)povede
    viz:
        http://developer.apple.com/internet/webcontent/xmlhttpreq.html

    napr: 
    function callback_processAjaxResponse() {
    // only if ajax shows "loaded"

        // only if "OK"
        if (ajax.readyState == 4) {
    
            // HTTP status
            if (ajax.status == 200) {
                $('votes').innerHTML = req.responseText;

            } else {
                alert("There was a problem retrieving the XML data:\n" + ajax.statusText);
            }
        }
    
    } 

    zde je tabulka moznych vlastnosti:
    Property  Description
    -------------------------------
    onreadystatechange  Event handler for an event that fires at every state change 
    readyState          Object status integer: 
      0 = uninitialized
      1 = loading
      2 = loaded
      3 = interactive
      4 = complete

    responseText        String version of data returned from server process
    responseXML         DOM-compatible document object of data returned from server process
    status              Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK"
    statusText          String message accompanying the status code

    ======
*/


// vytvori zakladni instanci pro praci s AJAXem
function ajax_instance() {
    var ajax = false;

    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    try {
        ajax = new ActiveXObject('Msxml2.XMLHTTP');

    } catch (e) {
        try {
            ajax = new ActiveXObject('Microsoft.XMLHTTP');
        } catch (E) {
            ajax = false;
        }
    }
    @end @*/
    if (!ajax && typeof XMLHttpRequest != undefined) {
        ajax = new XMLHttpRequest();
    }

    return ajax;
}


// doc: provede pozadavek: GET a vraceny vysledek zobrazi do 'element_id'
// doc: -- element_id          = id elementu v HTML dokumentu
// doc: -- url                 = url adresa pro odeslani pozadavku
// doc: -- err_msg             = text chybove zpravy, pokud se pozadavek nevydari
// doc: -- async               = 0=false|1=true, zda se bude jednat o asynchronni pozadavek [default: true]
// doc: -- callback            = funkce, ktera se zavola pri stavu pozadavku (element_id, ajax, err_msg)
// doc: -- callback            =  {
// doc: -- callback            =    onLoad    (element_id, url)           ~ pred spustenim pozadavku
// doc: -- callback            =    onComplete(element_id, ajax)          ~ po kompletnim pozadavku
// doc: -- callback            =    onError   (element_id, ajax, err_msg) ~ v pripade chyby
// doc: -- callback            =  }
function ajax_GET(element_id, url, err_msg, async, callback) {
    if (!url) {
        document.getElementById(element_id).innerHTML = "";
        return false;
    }

    if (async == undefined) { async=true; }

    var ajax = ajax_instance();
    if (!ajax) { return false; }

    ajax.open('GET', url, async);

    if (callback == undefined) {
        callback=undefined;
        c_onLoad=undefined;
        c_onComp=undefined;
        c_onErr =undefined;

    } else {
        if (callback['onLoad'] != undefined) { c_onLoad=callback['onLoad']; }
        if (callback['onComp'] != undefined) { c_onComp=callback['onComp']; }
        if (callback['onErr']  != undefined) { c_onErr =callback['onErr']; }
    }

    if (c_onLoad == undefined && c_onComp == undefined && c_onErr == undefined && callback != undefined) {
        ajax.onreadystatechange=callback(element_id, ajax, err_msg);

    } else {
        ajax.onreadystatechange = function() {
            if (ajax.readyState == 4) {
                if (ajax.status == 200) {
            
                    r=false;
                    if (c_onComp != undefined) {
                        r=c_onComp(element_id, ajax);
                    }
                    
                    if (!r) {
                        var which_element = document.getElementById(element_id);
                        which_element.innerHTML = ajax.responseText;
                    }

                } else {
                    r=false;
                    if (c_onError != undefined) {
                        c_onError(element_id, ajax, err_msg);
                    }

                    if (!r) {
                        var which_element = document.getElementById(element_id);
  
                        if (!err_msg) { err_msg="ajax: error while GET url data!"; }
                        which_element.innerHTML = err_msg+"<br />\n("+ ajax.status +") "+ ajax.statusText;
                    }
                }

            }
        }
        // END of function()

        if (c_onLoad != undefined) {
            c_onLoad(element_id, url);
        }
    }

    ajax.send(null);
    if (async == false) { return ajax.responseText; }

    return true;
}

