/* 
Definition eines Objekts, welches Browserinformationen zur Verfuegung stellt.
Die Implementierung erfolgt als Singleton - Initialisierung erfolgt automatisch
nach dem Laden des Quellcodes und das Objekt steht unter seinem Namen
(browserInformation) direkt zur Verfuegung. Nach Aufruf einer Seite, die das
Script einbindet, stehen die Informationen ?ber die entsprechenden get-Methoden zur Verfuegung.

'Browser: ' 		 browserInfo.getBrowserName(); 
'Version: ' 		 browserInfo.getBrowserVersion(); 
'Betriebssystem: ' 	 browserInfo.getOperatingSystem();
'Version: ' 		 browserInfo.getOSVersion();
*/

var browserInfo = new function BrowserCheck () {
  // Definition einer privaten Methode searchBrowserInfo, die keine
  // Parameter erwartet.
  // Diese Methode ermittelt Informationen zur Browseranwendung aus der
  // Eigenschaft userAgent des Navigator-Objekts.
  var searchBrowserInfo = function () {
    // Variablen zur Speicherung der emittelten Informationen
    var bname, ver;
    // UserAgent-String aus dem Navigator-Objekt enthaelt Browserinformationen
    var bs = navigator.userAgent;
    // Zeichenketten zur Identifikation der Browseranwendungen
    // Weitere Browser koennen erkannt werden, indem die untere Liste entsprechend
    // vervollstaendigt wird.
    var browserCheck = [ { identification: 'Firefox', name: 'Firefox', version: 'Firefox/\([0-9.]\+\)' },
             { identification: 'Konqueror', name: 'Konqueror', version: 'Konqueror/\([0-9.]\+\)' },
             { identification: 'MSIE', name: 'Internet Explorer', version: 'MSIE \([0-9.]\+\)' },
             { identification: 'Camino', name: 'Camino', version: 'Camino/\([0-9.]\+\)' },
             { identification: 'Opera', name: 'Opera', version: 'Opera/\([0-9.]\+\)' },
             { identification: 'Netscape', name: 'Netscape', version: 'Netscape[0-9]\?/\([0-9.]\+\)' },
             { identification: 'Safari', name: 'Safari', version: 'Safari/\([0-9.]\+\)' },
             { identification: 'Gecko', name: 'Mozilla', version: 'rv:\([0-9.]+\)' }
           ];
    var i = 0;
    // Zur Erkennung des Browsers nacheinander die obere Liste durchgehen bis
    // ein Browser erkannt wurde oder aber die Alternativen ausgehen.
    while (!bname && browserCheck[i]) {
      // Identifikationsstring im User-Agent enthalten?
      if (bs.indexOf (browserCheck[i].identification) != -1) {
        // Browser erkannt: Name des Browsers speichern...
        bname = browserCheck[i].name;
        // und Version des erkannten Browsers ermitteln.
        if (bs.match (RegExp (browserCheck[i].version)) != -1)
          // Versionsstring im UserAgent-String gefunden.
          ver = RegExp.$1;
      }
      i++;
    }
    // Ermittelte Browserinformationen als Objekt mit den Eigenschaften
    // name und version zurueckgeben. Was nicht erkannt wurde wird mit
    // der Zeichenkette unbekannt belegt.
    return { name: bname || 'unbekannt', version: ver || 'unbekannt' };
  }

  // Private Methode zur Ermittlung von Informationen zum genutzten Betriebssystem.
  // Ausgewertet werden Informationen, die im JavaScript-Objekt navigator unter
  // der Eigenschaft userAgent gespeichert sind.
  var searchOSInfo = function () {
    // Variablen zur Speicherung der Inofrmationen zum Betriebssystem
    var os, ver;
    // Verarbeitet werden die in der userAgent-Eigenschaft des navigator-Objekts
    // gespeicherten Informationen.
    var bs = navigator.userAgent;
    // Zeichenketten zur Erkennung der verschiedenen Betriebssysteme
    // Eine entsprechende Erweiterung dieser Liste ermoeglicht das Erkennen
    // weiterer Betriebssysteme und deren Versionen.
    var osCheck = [ { identification: 'Win', osname: 'Windows', versions: [ { identification: 'Windows NT 5\.1', name: 'Windows XP' },
                      { identification: 'Win(dows )?95', name: 'Windows 95' },
                      { identification: 'Win(dows )?98', name: 'Windows 98' },
                      { identification: 'Windows NT 4\.0', name: 'Windows NT 4.0' },
                      { identification: 'Windows NT 5\.0', name: 'Windows 2000' },
                      { identification: 'Windows NT 5\.2', name: 'Windows Server 2003' },
                      { identification: 'Windows NT 6\.0', name: 'Windows Vista' } 
                          ] },
        { identification: 'Mac', osname: 'Mac OS', versions: [ { identification: 'Mac', version: '\((PPC\?Intel) Mac OS X[^;]\*\)'}
                         ] },
        { identification: 'Linux', osname: 'Linux', versions: [ { identification: 'Debian', version: 'Debian-\([^) "]*\)'},
                      { identification: 'Ubuntu', version: 'Ubuntu[-\/]\([^) "]\*\)'},
                      { identification: 'Fedora', version: 'Fedora/\([^) "]\*\)'}
                          ] }
            ];
    var i = 0;
    // Liste der bekannten Betriebssysteme solange abarbeiten, bis das Betriebssystem
    // erkannt wurde oder die Erkennung mangels entsprechender Informationen bzgl.
    // des eingesetzten Betriebssystems fehlschlaegt.
    while (!os && osCheck[i]) {
      // Entsprechung mit einem der oberen Systeme gefunden?
      if (bs.indexOf (osCheck[i].identification) != -1) {
        // Grundsaetzlicher Typ des Betriebssystems erkannt und dessen Name speichern.
        os = osCheck[i].osname;
        var j = 0;
        // Genauere Versionsangaben ueber das System ermitteln.
        // Hier wird nach Entsprechungen mit den Versionsangaben aus der
        // oberen Versionsliste des jeweiligen Betriebssystems gesucht.
        while (!ver && osCheck[i].versions[j]) {
          // Bestimmte Version identifizierbar?
          if (bs.search (RegExp (osCheck[i].versions[j].identification)) != -1)
            // Wenn es zu einem System mehrere Varianten gibt (z.B.
            // unterschiedliche Distributionen bei Linux) wird nun
            // versucht genauere Informationen zum System zu ermitteln.
            if (osCheck[i].versions[j].version) {
              // Gefundene Systemvariante speichern...
              ver = osCheck[i].versions[j].identification;
              // und versuchen die Versionsnummer zu ermitteln.
              if (bs.search (RegExp (osCheck[i].versions[j].version)) != -1)
                // Versionsstring erkannt: Speicherung dieser Angaben
                ver += ' ' + RegExp.$1;
            }
            else
            // Ansonsten wird der Name der Betriebssystemversion festgehalten.
              ver = osCheck[i].versions[j].name;
          j++;
        }
      }
      i++;
    }
    // Informationen zum Betriebssystem als Objekt mit den Eigenschaften
    // name und version zurueckgeben. Wurden Komponenten nicht erkannt, so
    // liefert die entsprechende Eigenschaft das String unbekannt.
    return { name: os || 'unbekannt', version: ver || 'unbekannt' };
  }

  // Private Variablen des Objekts
  // Variable zur Speicherung der Browserinformationen.
  // Initialisiert das Objekt mit den ermittelten Browserdaten
  var browser = searchBrowserInfo();
  // Variable zur Speicherung der Informationen zum Betriebssystem.
  // Initialisiert das Objekt mit Informationen zum genutzten Betriebssystem
  var os = searchOSInfo();

  // Oeffentliche Methoden des Objekts
  // Liefert den Namen des benutzten Browsers
  this.getBrowserName = function () {
    return browser.name;
  }

  // Liefert die Version der Browseranwendung
  this.getBrowserVersion = function () {
    return browser.version;
  }

  // Liefert den Namen des Betriebssystems
  this.getOperatingSystem = function () {
    return os.name;
  }

  // Liefert die Version des Betriebssystems
  this.getOSVersion = function () {
    return os.version;
  }
};