﻿function init() {
 // wird beim Laden aufgerufen
 // registriert für alle sup-Tags, die nur Ziffern
 // enthalten, ein Klick-Ereignis
 var sups = document.getElementsByTagName("img");
 if (!sups) return false;
 for (var i = 0; i < sups.length; i++) {
  // sup enthält die Fußnotennummer
 // var sup = parseInt(sups[i].firstChild.nodeValue);
 var sup = parseInt(sups[i].getAttribute("fuss"));
  if (sup != null && !isNaN(sup)) {
   // Beim Registrieren als Ereignis lassen sich keine
   // Argumente übergeben -> das Skript erzeugt für jedes
   // Ereignis eine Funktion
   sups[i].onclick = new Function("ereignis", "FN.position_ermitteln(ereignis); fussnote(" + sup + ");");
  }
 }
}

function fussnote(nr) {
 // erzeugt den Fußnoten-Container und holt die Inhalte
 if (FN.container) FN.schliessen();
 document.getElementsByTagName("body")[0].appendChild(FN.erzeugen());
 FN.fussnotenueber.nodeValue = FN.fussnotenvorspann + nr;
 FN.holen(nr);
}

// Fußnoten-Layer-Objekt
var FN = {
 // Die Fußnote soll von außen zugänglich sein:
 container: null,		// DIV-Container
 fussnotenvorspann: "Bildinfo ",	// Überschrift-Vorspann
 fussnotenueber: null,		// Überschriftentext
 fussnotenabsatz: null,		// Absatz für Fussnotentext
 ajax: false,			// XMLHttpRequest-Objekt
 mausX: 0,			// horizontale und ...
 mausY: 0,			// vertikale Mausposition
 div_breite: 250,		// Breite und ...
 div_hoehe: 100,			// Höhe des Fußnoten-Containers
 abstandX: 10,			// horizontaler und ...
 abstandY: 10,			// vertikaler Abstand von Mauszeiger
 rollX: 0,			// horizontale und ...
 rollY: 0,			// vertikale Scrollposition

 erzeugen: function() {
  // Der Fußnoten-Layer wird bei jedem Aufruf neu erzeugt.
  // Alternativ könnte er mit den Stylesheet-Eigenschaften
  // visibility oder display aus- und eingeblendet werden.
  // erzeugt Div-Container
  FN.container = document.createElement("div");
  FN.container.id = "fussnoten";
  FN.container.style.width = FN.div_breite + "px";
  FN.container.style.height = FN.div_hoehe + "px";
  // Positionieren, abhängig von Mauszeiger und Browserfenster
  // Der Kasten soll rechts vom Mauszeiger erscheinen, wenn dort
  // noch Platz ist oder links kein Platz ist
  var pos_x = (FN.mausX + FN.abstandX + FN.div_breite < window.innerWidth || FN.div_breite + FN.abstandX > FN.mausX)?
   FN.mausX + FN.abstandX :	// rechts von Mauszeiger
   FN.mausX - FN.div_breite - FN.abstandX;	// links
  // Der Kasten soll über dem Mauszeiger erschein, wenn Platz ist
//  var pos_y = FN.mausY + FN.abstandY-30;	// unter Mauszeiger
 var pos_y = (FN.div_hoehe + FN.abstandY > FN.mausY)?
   FN.mausY + FN.abstandY :	// unter Mauszeiger
   FN.mausY - FN.div_hoehe - FN.abstandY;	// darüber   
  //alert('roll: '+FN.rollX + ' ' + FN.rollY);// + "\npos: "+ pos_x + ' ' + pos_y + "\nmaus: "+ FN.mausX + ' ' + FN.mausY);
  FN.container.style.left = FN.rollX + pos_x + "px";
  FN.container.style.top = FN.rollY + pos_y + "px";
  // Fußnoten-Überschrift
  var fn_h = document.createElement("h1");
  FN.fussnotenueber = document.createTextNode(FN.fussnotenvorspann);
  fn_h.appendChild(FN.fussnotenueber);
  // Link zum Schließen
  var fn_link = document.createElement("a");
  fn_link.setAttribute("href", "javascript:FN.schliessen()");
  // Absatz für Fußnotentext vorbereiten
  FN.fussnotenabsatz = document.createElement("p");
  // zusammensetzen
  fn_h.appendChild(fn_link);
  FN.container.appendChild(fn_h);
  FN.container.appendChild(FN.fussnotenabsatz);
  // Ereignis registrieren
//  FN.container.onmousedown = FN.ziehen_vorbereiten;
//  FN.container.style.cursor = "move";
  // zurückgeben
  return FN.container;
 },

 holen: function(nr) {
  // Ajax-Verbindung herstellen
  try {			// W3C-Standard
   FN.ajax = new XMLHttpRequest();
  } catch(w3c) {
   try {			// Internet Explorer
    FN.ajax = new ActiveXObject("Msxml2.XMLHTTP");
   } catch(msie) {
    try {		// Internet Explorer alt
     FN.ajax = new ActiveXObject("Microsoft.XMLHTTP");
    } catch(msie_alt) {
     alert("Ihr Browser kann keine Fußnoten anzeigen.");
     return false;	// !!! Link auf XML-Dokument
    }
   }
  }
  // Datei anfordern (asynchron)
  FN.ajax.open('GET', 'fussnoten.xml', true);
  FN.ajax.setRequestHeader('Content-Type', 'text/xml');
  // umgeht Internet Explorers Caching von GET-Anfragen
  FN.ajax.setRequestHeader('If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT');
  FN.ajax.send(null);
  // nach Status-Änderungen der Verbindung
  // werden die empfangenen Inhalte geparst
  FN.ajax.onreadystatechange = function() {
   // wenn Datei komplett empfangen ist ...
   if (FN.ajax.readyState == 4) {
    // Dokument nicht gefunden (Code 0 für lokale Tests):
    if (FN.ajax.status != 200 && FN.ajax.status != 0) {
     FN.fussnotenabsatz.firstChild.nodeValue = "Fussnoten-Datei konnte nicht gefunden werden!";
     return false;
    }
    // schreibe alle Fussnoten in fns
    var fns = FN.ajax.responseXML.getElementsByTagName("fussnote");
    // Eine Schleife sucht nach der Fußnotennummer
    for(var i = 0; i < fns.length; i++) {
     if (fns[i].getElementsByTagName("nr")[0].firstChild.nodeValue == nr) {
      klonen(fns[i].getElementsByTagName("p")[0].cloneNode(true), FN.fussnotenabsatz);
      return true;
     }
    }
    var nicht_gefunden = document.createTextNode("Fußnote " + nr + " wurde nicht gefunden!");
    FN.fussnotenabsatz.appendChild(nicht_gefunden);
    return false;
   }
  }
 },

 schliessen: function() {
  // löscht den Fußnoten-Container
  document.getElementsByTagName("body")[0].removeChild(FN.container);
  FN.container = null;
 },

 ziehen_vorbereiten: function(ereignis) {
  // registriert die ziehen-Funktion für Mausbewegungen,
  // Abbruch bei Loslassen der Maustaste
  if (!ereignis) var ereignis = window.event;
  FN.position_ermitteln(ereignis);
  document.onmousemove = FN.ziehen;
  document.onmouseup = FN.stopp;
 },

 position_ermitteln: function(ereignis) {
  // ermittelt die Position des Mauszeigers
  // (Pixel von der linken oberen Fensterecke)
  if (!ereignis) var ereignis = window.event;
  FN.mausX = ereignis.clientX;
  FN.mausY = ereignis.clientY;
  FN.roll();
  // Safari rechnet clientX/Y vom Dokumentenanfang aus
  if (FN.mausX > FN.rollX && FN.rollX >= window.innerWidth) FN.mausX -= FN.rollX;
  if (FN.mausY > FN.rollY && FN.rollX >= window.innerHeight) FN.mausY -= FN.rollY;
 },

 roll: function() {
  // Gibt die horizontale oder vertikale Scroll-Verschiebung zurück
  if (isFinite(self.pageYOffset)) {	// DOM
   FN.rollX = self.pageXOffset;
   FN.rollY = self.pageYOffset;
  } else if (isFinite(document.documentElement && document.documentElement.scrollTop)) {	// IE neu
   FN.rollX = document.documentElement.scrollLeft;
   FN.rollY = document.documentElement.scrollTop;
  } else if (isFinite(document.body.scrollTop)) {	// IE alt
   FN.rollX = document.body.scrollLeft;
   FN.rollY = document.body.scrollTop;
  }
 },

 ziehen: function(ereignis) {
   try {  
// verschiebt den Fußnoten-Container parallel zu Mausbewegungen
  if (!ereignis) var ereignis = window.event;
  // Sicherheitsmaßnahme: manche Browser kommen mit den Ereignissen
  // durcheinander, z.B. beim Scrollen in überlangen Fußnoten
  // (Safari) oder bei Maus-Hektik (IE); in diesem Fall löst ein
  // Mausklick den am Zeiger klebenden Container.
  document.onmousedown = FN.stopp;
  // 1.) aktuelle Position ermitteln
  var kastenX = parseInt(FN.container.style.left.slice(0,-2));
  var kastenY = parseInt(FN.container.style.top.slice(0,-2));
  // 2.) alte Mausposition speichern
  var mausX_alt = FN.mausX;
  var mausY_alt = FN.mausY;
  // 3.) neue Mausposition ermitteln
  FN.position_ermitteln(ereignis);
  // 4.) um die Differenz verschieben
  FN.container.style.left = kastenX + FN.mausX - mausX_alt + "px";
  FN.container.style.top = kastenY + FN.mausY - mausY_alt + "px";
  } catch(msie) {return false;}
 },

 stopp: function() {
  // löscht Event-Handler, lässt Fußnoten-Container los
  document.onmousemove = null;
  document.onmouseup = null;
  // gleicht Sicherheitsmaßnahme in FN.ziehen() aus
  if (document.onmousedown) document.onmousedown = FN.ziehen_vorbereiten;
 }

};

function klonen(quelle, ziel) {
 // Hilfsfunktion für Fußnoten-Darstellung im DOM
 // Einfaches cloneNode() funktioniert nicht bei komplexen
 // Gebilden; eine Schleife baut den Teilbaum nach.
 for(var i = 0; i < quelle.childNodes.length; i++) {
  var knoten = quelle.childNodes[i];
  switch (knoten.nodeType) {
   case 1:	// Elementknoten
    var neu = ziel.appendChild(document.createElement(knoten.nodeName));
    for (var j = 0; j < knoten.attributes.length; j++) {
     neu.setAttribute(knoten.attributes[j].nodeName, knoten.attributes[j].nodeValue);
    }
    klonen(knoten, neu);
    break;
   case 3:	// Textknoten
    subknoten = document.createTextNode(knoten.nodeValue);
    ziel.appendChild(subknoten);
   // andere Knotentypen sind nicht relevant
  }
 }
}

// Aufruf der init-Funktion beim Laden
window.onload = init;

