// Obecná funkce pro provádění AJAX požadavků.
// Očekává jeden argument, což je objekt obsahující sadu nastavení.
// Všechna jsou popsána v komentářích níže.
function ajax( nastaveni ) {
    // Načteme nastavení nebo uložíme výchozí.
    nastaveni = {
        // Typ HTTP požadavku
        metoda: nastaveni.metoda || "POST",

        // URL, na kterou bude požadavek proveden
        url: nastaveni.url || "rss.xml",

        // Časový limit dokončení požadavku
        timeout: nastaveni.timeout || 5000,
        
        attr: nastaveni.attr || "",

        // Funkce, které se zavolají při selhání či úspěchu požadavku
        // nebo při jeho dokončení (ať už úspěšném či neúspěšném)
        onComplete: nastaveni.onComplete || function(){},
        onError: nastaveni.onError || function(){},
        onSuccess: nastaveni.onSuccess || function(){},

        // Typ dat, který bude vrácen ze serveru.
        // Výchozí  nastavení znamená, že typ bude určen podle serveru
        // a podle toho se dále zachováme.
        data: nastaveni.data || ""
    };
    
    // Pokud je použit IE, vytvoříme kontejner pro XMLHttpRequest objekt
    if ( typeof XMLHttpRequest == "undefined" )
    XMLHttpRequest = function(){
            // Internet Explorer používá pro vytvoření nového
            // XMLHttpRequest objektu ActiveXObject.
            return new ActiveXObject(
                    // IE 5 používá odlišný XMLHTTP objekt než IE6
                    navigator.userAgent.indexOf("MSIE 5") >= 0 ?
                    "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP"
            );
    };
    
    // Vytvoříme objekt požadavku.
    var xml = new XMLHttpRequest();

    // Otevřeme asynchronní požadavek typu POST.
    //xml.open("GET", "rss.xml", true);
    var script = nastaveni.url + nastaveni.attr;
    xml.open(nastaveni.metoda, script, true);
    
    // Počkáme na požadavek pět sekund, potom to vzdáme.
    var timeoutLength = 5000;

    // Pamatujeme si, jestli byl požadavek úspěšně dokončen.
    var pozadavekDokoncen = false;

    // Inicializujeme callback funkci, která se spustí za pět sekund
    // a zruší požadavek (pokud se tak již nestalo).
    setTimeout(function(){
         pozadavekDokoncen = true;
    }, timeoutLength);

    // Hlídáme změny stavu požadavku.
    xml.onreadystatechange = function(){
        // Čekáme na kompletní načtení dat,
        // a ujistíme se, že časový limit požadavku ještě nevypršel.
        if ( xml.readyState == 4 && !pozadavekDokoncen ) {
            // Zkontrolujeme, zda byl požadavek úspěšný
            if ( httpSuccess( xml ) ) {
                // Zavoláme callback funkci pro úspěšné provedení požadavku
                // s daty vrácenými ze serveru.
                nastaveni.onSuccess( httpData( xml, nastaveni.typ ) );

            // Jinak nastala chyba, zavoláme tedy callback funkci pro chybový stav.
            } else {
                nastaveni.onError();
            }

            // Zavoláme callback funkci pro dokončení požadavku.
            nastaveni.onComplete();

            // Uklidíme po sobě, abychom předešli úniku paměti.
            xml = null;
        }
    };

    // Navážeme spojení se serverem.
    //kvuli Firefoxu musi byt uveden v send fci argument null
    xml.send(null);

    
    // Zjistíme, zda HTTP požadavek uspěl.
    function httpSuccess(r) {
        try {
            // Pokud nebyl vrácen žádný stav a žádáme o místní soubor,
            // pak byl požadavek úspěšný.
            return !r.status && location.protocol == "file:" ||
    
                // Jakýkoliv status od 200 do 299 je dobrý.
                ( r.status >= 200 && r.status < 300 ) ||
    
                // Úspěšně dokončeno, pokud dokument nebyl změněn.
                r.status == 304 ||
    
                // Prohlížeč Safari vrací prázdný satus, pokud soubor nebyl změněn.
                navigator.userAgent.indexOf("Safari") >= 0 && typeof r.status == "undefined";
        } catch(e){}
    
        // Pokud kontrola stavu vyhodila výjimku, předpokládáme, že požadavek také neuspěl.
        return false;
    }

    // Získáme správná data z HTTP odpovědi.
    function httpData(r,typ) {
        // Získáme hlavičku Content-Type.
        var ct = r.getResponseHeader("Content-Type");
    
        // Pokud nebyl určen výchozí typ, zjistíme, zda server vrátil
        // nějaký druh XML.
        var data = !typ && ct && ct.indexOf("xml") >= 0;
    
        // Pokud bylo ze serveru vráceno XML, získáme XML dokument;
        // jinak vrátíme textový obsah, který server poslal.
        data = typ == "xml" || data ? r.responseXML : r.responseText;
        
        // Pokud je udán typ "script", provedeme vrácený text jako JavaScript.
        if ( typ == "script" )
            eval.call( window, data );
    
        // Vrátíme data z odpovědi (buď XML dokument, nebo textový řetězec).
        return data;
    }

}


