// Funktion, mit der sich eine Funktion beim Laden des Dokuments ausfuehren laesst
function addLoadEvent (func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    };
  }
}

// Fuehre die Funktion suchtTextknoten beim Laden aus
addLoadEvent(sucheTextknoten);

// Wir legen eine Standard-Sprache fest, falls keine Sprache angegeben wurde
var standardLanguage = "de";

// In den folgenden Objekten speichern wir abhaengig von
// der Sprache die Anfuehrungszeichen
var openingQuotes = new Object();
var closingQuotes = new Object();
openingQuotes['de'] = "\u201E";
closingQuotes['de'] = "\u201C";
openingQuotes['en'] = "\u201C";
closingQuotes['en'] = "\u201D";
openingQuotes['fr'] = "\u00AB";
closingQuotes['fr'] = "\u00BB";
openingQuotes['es'] = "\u00AB";
closingQuotes['es'] = "\u00BB";

var openingSingleQuotes = new Object();
var closingSingleQuotes = new Object();
openingSingleQuotes['de'] = "\u201A";
closingSingleQuotes['de'] = "\u2018";
openingSingleQuotes['en'] = "\u2018";
closingSingleQuotes['en'] = "\u2019";
openingSingleQuotes['fr'] = "\u2039";
closingSingleQuotes['fr'] = "\u203A";
openingSingleQuotes['es'] = "\u2039";
closingSingleQuotes['es'] = "\u203A";

// Diese Funktion hangelt sich durch alle Knoten des HTML-Dokuments und
// sucht Textknoten, deren Inhalt veraendert werden soll
function sucheTextknoten () {

  // Hole die Sprache aus dem lang- oder xml:lang-Attribut des html-Elements,
  // sofern gesetzt; Vorgabe: standardLanguage
  var lang = standardLanguage, masterlang = standardLanguage;
  var html_element = document.documentElement;
  if (html_element.getAttribute("xml:lang")) {
    lang = masterlang = html_element.getAttribute("xml:lang").substring(0, 2);
  } else if (html_element.getAttribute("lang")) {
    lang = masterlang = html_element.getAttribute("lang").substring(0, 2);
  }
  if (!openingQuotes[lang]) {
    // Sind fuer die Sprache des Dokuments keine Anfuehrungszeichen gespeichert,
    // verwende englische Anfuehrungszeichen
    lang = masterlang = "en";
  }

  // Hier beginnt das Durchsuchen der Textknoten

  // Ueberpruefe, ob der Browser DOM Traversal unterstuetzt.
  // Schliesse Safari aus, denn dieser kennt zwar createTreeWalker(),
  // hat aber eine grob fehlerhafte Umsetzung: Es werden
  // nicht alle Textknoten gefunden.
  if (document.createTreeWalker && !/Safari/.test(navigator.userAgent) &&
      !/AppleWebKit/.test(navigator.userAgent)) {

    // Erzeuge einen TreeWalker, der alle Textknoten durchlaeuft
    tw = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, true);

    // Schreite zum ersten Textknoten vor
    tw.firstChild();

    // Aeltere Konqueror-Versionen kennen zwar TreeWalker, der TreeWalker
    // laesst sich allerdings nicht mit firstChild() und nextSibling() fortbewegen.
    // Steige in diesem Fall aus und versuche es mit der Alternativmethode.
    if (document.body !== tw.currentNode) {

      var parentNode, nodeName, className;
      // Durchlaufe alle Textknoten mit einer Schleife
      do {

        // Steige zum Elementknoten auf, das den Textknoten enthaelt
        parentNode = tw.currentNode.parentNode;

        tagName = parentNode.nodeName.toLowerCase();
        className = parentNode.className.toLowerCase();

        // Ueberspringe den Knoten, falls nichts geaendert werden soll
        if (/noquotes/.test(className) ||
          tagName == "script" || tagName == "code" ||
          tagName == "kbd" || tagName == "pre") {
          continue;
        }

        // Schaue nach, ob der Elternknoten eine Sprachangabe besitzt
        if (parentNode.hasAttribute("xml:lang")) {
          lang = parentNode.getAttribute("xml:lang").substring(0, 2);
        } else if (parentNode.lang) {
          lang = parentNode.lang.substring(0, 2);
        }

        // Hier passiert die Magie: Veraendere den Text des Textknotens
        tw.currentNode.nodeValue = veraendereTextknoten(tw.currentNode.nodeValue, lang);

        // Setze die urspruengliche Dokumentsprache wieder ein
        lang = masterlang;

      } while (tw.nextSibling());

      // Steige nach erfolgreicher Arbeit aus der Funktion aus
      return;
    }
  }

  // Alternativzweig fuer Browser, die das neuere TreeWalker-Objekt nicht kennen,
  // z.B. der Internet Explorer

  // Erstelle eine Liste mit allen Elementen im Dokumentkoerper
  var elementliste = document.body.getElementsByTagName("*");

  var i, thisNode, tagName, className;
  // Durchlaufe die Elementliste
  for (i = 0; i < elementliste.length; i++) {

    thisNode  = elementliste[i];
    tagName   = thisNode.tagName.toLowerCase();
    className = thisNode.className.toLowerCase();

    // Ueberspringe den Knoten, falls nichts geaendert werden soll
    if (/noquotes/.test(className) ||
      tagName == "script" || tagName == "code" ||
      tagName == "kbd" || tagName == "pre") {
      continue;
    }

    // Schaue nach, ob der Elementknoten eine Sprachangabe besitzt
    // (leider beachtet der IE das Attribut xml:lang nur im html-Element)
    if (thisNode.lang) {
      lang = thisNode.lang.substring(0, 2);
    }

    // Durchlaufe alle Kindknoten, sofern solche existieren
    if (thisNode.hasChildNodes()) {
      textNode = thisNode.firstChild;
      do {
        // Wenn es sich nicht um einen Textknoten handelt,
        // fahre mit dem naechsten Kindknoten fort
        if (textNode.nodeType != 3) {
          continue;
        }
        // Hier passiert die Magie: Veraendere den Text des Textknotens
        textNode.nodeValue = veraendereTextknoten(textNode.nodeValue, lang);

      } while (textNode = textNode.nextSibling);
    }
    // Setze die urspruengliche Dokumentsprache wieder ein
    lang = masterlang;
  }
}


// Diese Funktion veraendert einen uebergebenen String mittels Regulaeren Ausdruecken
function veraendereTextknoten (string, lang) {

  // Breche die Ersetzung ab, wenn der Textknoten sowieso nur aus Weissraum-Zeichen
  // besteht. Dies macht das Script geringfuegig schneller, weil die vielen
  // replace()-Aufrufe umgangen werden.
  if (/^\s+$/.test(string)) {
    return string;
  }

  // Ersetze einfache Anfuehrungszeichen
  string = string.replace(/(^|\s|[\("\-])'([^']*)'($|[\.,;:!?\/"\)\-]|\s)/g, "$1" +
    openingSingleQuotes[lang] + "$2" + closingSingleQuotes[lang] + "$3");
  string = string.replace(/(^|\s|\(|\-)'$/g, "$1" + openingSingleQuotes[lang]);
  string = string.replace(/^'([\.,;:!?\/\)\-]|\s)/g, closingSingleQuotes[lang] + "$1");
  // Apostroph (de)
  string = string.replace(/([xs])'($|[\.,;:!?\/\)\-]|\s)/g, "$1" +
    closingSingleQuotes["en"] + "$2");
  // Apostroph (en)
  string = string.replace(/([a-z])'s/g, "$1" + closingSingleQuotes["en"] + "s");

  // Ersetze doppelte Anfuehrungszeichen
  string = string.replace(/(^|\s|\(|\-)"([^"]*)"($|[\.,;:!?\/\)\-]|\s)/g,
    "$1" + openingQuotes[lang] + "$2" + closingQuotes[lang] + "$3");
  // wichtig fuer "<span>inhalt</span>"
  string = string.replace(/(^|\s|\(|\-)"(\s*)$/g, "$1" + openingQuotes[lang] + "$2");
  string = string.replace(/^(\s*)"([\.,;:!?\/\)\-]|\s)/g, "$1" +
    closingQuotes[lang] + "$2");

  // Ersetze drei Punkte durch eine horizontale Ellipse
  string = string.replace(/[\.]{3}/g, "\u2026");

  // Ersetze die gaengigen Brueche
  string = string.replace(/([^0-9]|^)1\/2([^0-9]|$)/g, "$1\u00BD$2");
  string = string.replace(/([^0-9]|^)1\/3([^0-9]|$)/g, "$1\u2153$2");
  string = string.replace(/([^0-9]|^)2\/3([^0-9]|$)/g, "$1\u2154$2");
  string = string.replace(/([^0-9]|^)1\/4([^0-9]|$)/g, "$1\u00BC$2");
  string = string.replace(/([^0-9]|^)3\/4([^0-9]|$)/g, "$1\u00BE$2");
  string = string.replace(/([^0-9]|^)1\/5([^0-9]|$)/g, "$1\u2155$2");
  string = string.replace(/([^0-9]|^)2\/5([^0-9]|$)/g, "$1\u2156$2");
  string = string.replace(/([^0-9]|^)3\/5([^0-9]|$)/g, "$1\u2157$2");
  string = string.replace(/([^0-9]|^)4\/5([^0-9]|$)/g, "$1\u2158$2");

  // Ersetze Symbole, Smileys und Pfeile
  string = string.replace(/\(c\)/g, "\u00A9");
  string = string.replace(/\(r\)/g, "\u00AE");
  string = string.replace(/\(tm\)/g, "\u2122");
  string = string.replace(/:-\)/g, "\u263A");
  string = string.replace(/(&lt;|<)--/g, "\u2190");
  string = string.replace(/--(&gt;|>)/g, "\u2192");
  string = string.replace(/(&lt;|<)==/g, "\u21D0");
  string = string.replace(/==(&gt;|>)/g, "\u21D2");

  return string;
}

