/* *********************************** API ****************************************
contructor MH_AJAX_Request(url) //Konstruktor
  url: wenn eine url übergeben wird, dann startet direkt ein Request

function startRequest(url)
  stößt einen Request an; Bei gelingen: führt Functor Start aus. Bei einem Ergebnis: Führt Functor Found aus
  -url: zu übergebende URL, falls leer, wird versucht, die letzte URL zu verwenden

function startRequest(url)
  stößt einen Request an; Bei gelingen: führt Functor Start aus. Bei einem Ergebnis: Führt Functor Found aus
  -url: zu übergebende URL, falls leer, wird versucht, die letzte URL zu verwenden

function startRequestWithCounter(countDown, millisecBetwTry,url)
  stößt einen Request an und überprüft diesen in regelmäßigen Abständen über den Functor Count
  //countDown*millisecBetwTry/1000 = Sekunden bis Abbruch (dann Aufruf Functor Error
  -countDown: Anzahl der Wiederholungen, bis abgebrochen wird
  -millisecBetwTry: Anzahl der Millisekunden zwischen zwei Wiederholungen
  -url: zu übergebende URL, falls leer, wird versucht, die letzte URL zu verwenden

function getRequestText()
  liefert den zuletzt erhaltenen Text zurück

function requesting()
  liefert true, falls gerade ein Request läuft

function setURL(url)
  setzt die URL, von der Abgefragt werden soll (hilfreich in Kombo mit "startRequestWithCounter"

function set[FunctorName]Functor(functor)
  setzt einen Functor/Listener, der Aufgerufen wird, falls das Ereigniss eintritt
  -functor: beliebige Funktion, die Aufgerufen wird



functor Start: sobald ein Request abgesetzt wird
               Parameter1: das RequestObjekt
functor Count: Wird bei jeder Wiederholung der Funktion startRequestWithCounter aufgerufen
               Parameter1: zu verbleibende Wiederholungen
               Parameter2: Anzahl der Millisekunden zwischen zwei Wiederholungen
               Parameter3: das RequestObjekt
functor Found: sobald ein Request etwas gefunden hat
               Parameter1: zurückgelieferter Text
               Parameter2: das RequestObjekt
functor Error: falls ein Fehler auftritt wird dieses Funktor aufgerufen. Wenn er nicht gesetzt wird, wird eine Standardmeldung abgesetzt
               Parameter1: Fehlernummer; (1: Zeitüberschreitung, 0: kann AJAX nicht ausfuhren)
               Parameter2: Standardfehlermeldung
               Parameter3: requestObject (this)
functor Close: sobald ein Request beendet wird
               Parameter1: das RequestObjekt

******************************************************************************** */

function MH_AJAX_Request(nGetOrPost) {

  var thisObject = this;
  var http_url = false;
  var http_param = false;
  var http_request = false;
  var http_request_text = false;
  var http_requesting = false;
  var http_counting = false;
  var functor_start = false;
  var functor_found = false;
  var functor_error = false;
  var functor_close = false;
  var functor_count = false;
  var counter_downtime = -1;
  var counter_millisecBetwTry = 500;
  var errorType = new Array('Fehler: Kann keine XMLHTTP-Instanz erzeugen', 'Fehler: Abfrage fehlgeschlagen: Zeitüberschreitung!');
  if (nGetOrPost!=null) getorpost=nGetOrPost; else var getorpost = 'GET'
  var requests = 0;

  this.startRequest = function (url,params) {
    if (url!=null) http_url=url; else url=http_url;
    if (params!=null) http_param=params;

    if (!http_requesting) {
      http_request = false;
      http_requesting = false;
    }

    if (window.XMLHttpRequest) { // Mozilla, Safari,...
      http_request = new XMLHttpRequest();
      if (http_request.overrideMimeType) http_request.overrideMimeType('text/xml');
    } else if (window.ActiveXObject) { // IE
      try {
        http_request = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          http_request = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {}
      }
    }

    if (!http_request) {
      requestError(0);
      return false;
    }

    if (functor_start) functor_start(thisObject);
    http_requesting=true;
    requests++;
    http_request.onreadystatechange = writeRequestInhalt;
    try {
      if (getorpost=='GET') {
        if (http_param!=null) url+='&'+http_param;
        http_request.open('GET', url, true);
        http_request.send(null);
      } else {
        http_request.open('POST', url, true);
        //Send the proper header information along with the request
        http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        http_request.setRequestHeader("Content-length", http_param.length);
        http_request.setRequestHeader("Connection", "close");
        http_request.send(http_param);
      }
    } catch(e){
      requestError(2,e);
      return false;
    }
  }

  this.startRequestWithCounter = function (countDown, millisecBetwTry,url, params) {
    if (millisecBetwTry!=null) counter_millisecBetwTry = millisecBetwTry;
    if (countDown==null) counter_downtime = 20; else counter_downtime = countDown;

    if (!http_requesting) thisObject.startRequest(url, params);
    http_counting=true;
    runCounter();
  }

  var runCounter = function () {
    if (counter_downtime>0) {
      if (functor_count && !http_request_text) {
        functor_count(counter_downtime, counter_millisecBetwTry,thisObject);
        counter_downtime--;
        window.setTimeout(function(){thisObject.counterStep();},counter_millisecBetwTry);
      }
    } else {
      if (counter_downtime==0 && http_requesting && http_counting) {
        requestError(1);
        stop();
      }
    }
  }

  this.counterStep = function () {
    if (http_counting) runCounter();
  }

  var writeRequestInhalt = function() {
    if(http_requesting) {
      try {
        if (http_request.readyState == 4) {
          switch(http_request.status) {
            case 200:
              http_request_text=http_request.responseText;
              if (functor_found) functor_found(http_request_text,thisObject);
              break;
            case 401:
            case 403:
              requestError(http_request.status,"Fehler "+http_request.status+": Berechtigung um auf Seite zuzugreifen fehlt:\n"+http_url)
              http_request_text=false;
              break;
            case 404:
            case 405:
              requestError(http_request.status,"Fehler "+http_request.status+": Seite existiert nicht:\n"+http_url)
              http_request_text=false;
              break;
            default:
              requestError(http_request.status,'Unbekannter Fehler in Request. ReadyState='+http_request.readyState+'; Status='+http_request.status+'; Seite='+http_url);
              http_request_text=false;
              break;
          }
          http_requesting=false;
          stop();
        }
      } catch(e) {requestError(3,e);}
    }
  }

  var stop = function () {
    http_requesting=false;
    http_counting=false;
    counter_downtime=-1;
    if (functor_close) functor_close(thisObject);
  }

  var requestError = function(errno,txt) {
    if (errorType[errno]) errorMsg = errorType[errno]; else errorMsg = "Unbekannter Fehler im Request-Object";
    if (txt!=null) errorMsg = txt;
    if (functor_error!=false) {
      functor_error(errno,errorMsg,thisObject);
    } else {
      if (functor_error!=-1) alert(errorMsg);
    }
    stop();
  }

  this.getRequestText = function () { return http_request_text; }
  this.requesting = function () { return http_requesting; }

  this.setURL = function (url, params) {
    http_url=url;
    http_param = params;
  }
  this.setStartFunctor = function (functor) {functor_start=functor;}
  this.setFoundFunctor = function (functor) {functor_found=functor;}
  this.setErrorFunctor = function (functor) {functor_error=functor;}
  this.setCloseFunctor = function (functor) {functor_close=functor;}
  this.setCountFunctor = function (functor) {functor_count=functor;}
}
