/* Fader-Framework zum Einrichten von Bilderwechseln */

var FaderFramework = {

	// "Einstellungen"
	className: "fader",	// die Klasse, die unser Element trägt, in dem die Bilder sitzen sollen

	// Voreinstellungen für einen Fader
	viewTime: 4000,				// Zeit, die ein Bild angezeigt wird (in Millisekunden)
	fadeStep: 1.5,			  // Prozent-Schritt beim Überblenden
	random: true,			  // Zufällige Reihenfolge der Bilder (true|false)
	autostart: true,			// sofort mit dem Fading starten (true|false)

	// automatische Einstellungen
	baseURL: "fader/",		// hier steht später der Pfad zum Verzeichnis, in dem sich dieses Script befindet.
	oldWinOnLoad: null,		// hier steht später vielleicht eine abgespeicherte Funktion
	inits: new Array(),		 // hier stehen später auszuführende Initialisierungen
	faders: new Object(),	   // hier werden die Fader stehen


	// Initialisier-Funktion - startet das FaderFramework (wird noch während des Ladens der Seite ausgeführt)
	start: function () {
		this.oldWinOnLoad = window.onload; // alte onload-Funktion abspeichern (falls vorhanden)

		// neue (anonyme!) onload-Funktion erstellen um eventuelle alte Funktion(en) zu kapseln
		window.onload = function () {
			// War bereits eine Funktion in window.onload abgelegt worden?
			if (typeof(FaderFramework.oldWinOnLoad) == "function") {
				// hier kann man nicht "this" benutzen, da diese Funktion nicht zu einem größeren Objekt gehört!
				FaderFramework.oldWinOnLoad(); // gespeicherte onload-Funktion ausführen
			}

			FaderFramework.onload(); // unsere onload-Funktion ausführen
		};
	},

// onload-Funktion wird unmittelbar nach dem vollständigen Laden des Dokuments ausgeführt
	onload: function () {
		/* "this" verweist auf unser FaderFramework-Objekt! */

		var i, fader, css, scripts = document.getElementsByTagName("script");

// baseURL herausfinden, um weitere Komponenten dieses Scripts nachladen zu können
		for (i = 0; i < scripts.length; i++) {
			if (scripts[i].src && scripts[i].src.match(/fader-framework\.js/)) {
				this.baseURL = scripts[i].src.replace(/(^|\/)fader-framework\.js$/, "");
			}
		}

		// weitere Komponenten einbinden wenn baseURL ermittelt wurde
		if (this.baseURL) {
			// unsere CSS-Datei einbinden (also <link rel="stylesheet" type="text/css" href="../fader/..." /> erzeugen)
			css = document.createElement("link");
			css.rel = "stylesheet";
			css.type = "text/css";
			css.href = this.baseURL + "fader/fader.css";
			// <link />-Element im <head> hinten anfügen
			document.getElementsByTagName("head")[0].appendChild(css);
		}

		// vorgemerkte Fader erstellen
		fader = this.inits;
		delete this.inits; // wenn this.inits nicht existiert, dann erstellt this.init() echte Fader, anstatt sie nur vorzumerken

		for (i = 0; i < fader.length; i++) {
			this.init(fader[i]);
		}
	},


// Funktion zum Einrichten eines Faders (wird noch während des Ladens der Seite ausgeführt - eventuell mehrmals)
	init: function (einstellungen) {
		/* "einstellungen" ist ein Objekt, das folgende Struktur haben muss:
			{
				id: "id-des-HTML-Elements",				   // muss einmalig sein!!
				images: ["pfad/bild1.jpg", "pfad/bild2.jpg"], // weitere Bilder möglich
				// optionale Angaben
				viewTime: 20000,
				fadeStep: 1,
				random: true,
				autostart: false
			}
		*/

		var fader;

		if (this.inits) {
			this.inits[this.inits.length] = einstellungen; // für später abspeichern

		} else {
			fader = new this.Fader(einstellungen); // this.Fader ist eine Konstruktor-Funktion!

			// abspeichern wenn Fader erfolgreich erstellt wurde
			if (fader != false && !this.faders[einstellungen.id]) {
				this.faders[fader.id] = fader;

				if (fader.autostart) {
					// Fader autostarten
					window.setTimeout(function () {	fader.start(); }, fader.viewTime); // start() wird dem Fader in der Konstruktor-Funktion verliehen, ebenso viewTime
				}
			}
		}
	},


	// Konstruktor:  Bauplan eines Faders
	Fader: function (einstellungen) {
	/*
		In diesem Konstruktor verweist "this" immer auf das zu erzeugende Objekt - vorausgesetzt,
		dieser Konstruktor wird mit dem Schlüsselwort "new" aufgerufen, z.B. var a = new this.Fader()
	*/

		// Darf eventuell kein Fader eingerichtet werden?
		if (
			// keine ID (oder ein Leerstring) übergeben
			!einstellungen.id
			||
			// kein HTML-Element mit dieser ID vorhanden
			!document.getElementById(einstellungen.id)
			||
			// für diese ID ist bereits ein Fader eingerichtet
			FaderFramework.faders[einstellungen.id]
			||
			// weniger als zwei Bilder angegeben
			einstellungen.images.length < 2
		) {
			// also gibt es keinen Fader für diesen init-Aufruf
			return new Boolean(false);
		}

		// Einstellungen des Faders vornehmen - wie "einstellungen" aussehen muss, siehe Funktion "init"!
		this.id = einstellungen.id;
		this.images = new Array(); // Bilder werden hier nicht als Zeichenketten, sondern später als HTML-Elementobjekte abgelegt...
		this.random = (typeof einstellungen.random != "undefined") ? einstellungen.random : FaderFramework.random;
		this.autostart = (typeof einstellungen.autostart != "undefined") ? einstellungen.autostart : FaderFramework.autostart;
		this.viewTime = einstellungen.viewTime || FaderFramework.viewTime;
		this.fadeStep = einstellungen.fadeStep || FaderFramework.fadeStep;
		this.stopped = false; // hiermit kann später der Fader angehalten werden
		this.playList = new Array(); // Wiedergabeliste
		this.counter = 0; // aktuell angezeigtes Bild (Zähler für Playlist)
		this.dir = ""; // Richtung - "backwards" führt zu umgekehrter Reihenfolge
		this.fading = false; // blockt die Funktion next, um Störungen beim Überblenden zu verhindern


		// <span>-Element als Container erzeugen und mit der Fader-Klasse ausrüsten
		this.element = document.createElement("span");
		this.element.className = FaderFramework.className;

		// Opera korrigieren
		if (window.opera) {
			this.element.style.display = "inline-table";
		}

		// das ursprüngliche Bild ersetzen
		var i;
		i = document.getElementById(this.id); // ursprüngliches Bild
		i.parentNode.replaceChild(this.element, i);

		// Bilder aus der Liste zu echten Bildobjekten machen und ins <span>-Element einhängen
		for (i = 0; i < einstellungen.images.length; i++) {
			this.images[i] = document.createElement("img");
			this.images[i].src = einstellungen.images[i];
			this.images[i].alt = "";

			// nur erstes Bild ins Dokument Einhängen
			if (i == 0) {
				this.element.appendChild(this.images[i]);
			}
		}


		/*
			Funktionen (Methoden) des Faders definieren!
		*/


		// Playlist generieren (enthält nur die Nummern der Bilder)
		this.createPlayList = function () {
			var i, r;

			this.playList = new Array();

			if (this.random) {
				// zufällige Reihenfolge
				while (this.playList.length < this.images.length) {
					vorhanden = false; // Zufallszahl bereits vorhanden?
					r = Math.floor(Math.random() * (this.images.length));
					for (i = 0; i < this.playList.length; i++) {
						if (r == this.playList[i]) {
							vorhanden = true;
						}
					}

					if (!vorhanden) {
						this.playList[this.playList.length] = r;
					}
				}

			} else {
				// geordnete Reihenfolge
				for (i = 0; i < this.images.length; i++) {
					this.playList[i] = i;
				}
			}
		};


		// Funktion zum Starten des Faders
		this.start = function () {
			this.stopped = false;
			this.next();
		};

		// Funktion zum Stoppen des Faders
		this.stop = function () {
			this.stopped = true; // verhindert, dass weitere window.setTimeout-Funktionen gestartet werden
		};


		// Funktion zum Anzeigen des nächsten Bildes
		this.next = function (single, dir) {
			// "single" ist true oder false und dient dazu, einen einmaligen Wechsel zu ermöglichen, ohne eine Slideshow zu starten. Wird kein Parameter übergeben, dann wird single nicht als true interpretiert.
			if (single) {
				this.stopped = true;
			}

			// Richtungsänderung übernehmen
			if (typeof dir == "string") {
				this.dir = dir;
			}

			// wurde der Fader angehalten?
			if ((this.stopped && !single) || this.fading) {
				return; // Ja -> keinen Bildwechsel durchführen!
			}

			// Counter weiterzählen (oder zurücksetzen)
			if (this.dir != "backwards") {
				this.counter = (this.counter < this.playList.length -1) ? this.counter +1 : 0;
				// Neue Playlist fällig?
				if  (this.counter == 0) {
					// neue Playlist generieren
					this.createPlayList(); // neue Playlist erstellen
				}
			} else {
				this.counter = (this.counter > 0) ? this.counter -1 : this.playList.length -1;
				// Neue Playlist fällig?
				if  (this.counter == this.playList.length -1) {
					// neue Playlist generieren
					this.createPlayList(); // neue Playlist erstellen
				}
			}


			// neues Bild zum Überblenden ins Element einhängen
			this.element.appendChild(this.images[this.playList[this.counter]]);
			this.images[this.playList[this.counter]].className = "next";

			// Fading einleiten
			this.fade();
		};

		// Fade-Funktion für den Bilderwechsel (jeder Aufruf entspricht einem Fading-Schritt)
		this.fade = function (step) {
			var fader = this, imgs = this.element.getElementsByTagName("img");

			// Bilderwechsel sperren, um Störungen während des Überblendens verhindern
			this.fading = true;

			// Wenn kein Wert übertragen wurde, dann muss das Fading von vorne durchgeführt werden
			step = step || 0;

			// neues Bild überblenden
			imgs[1].style.opacity = step/100;
			imgs[1].style.filter = "alpha(opacity=" + step + ")"; // IE?

			step += this.fadeStep;

			if (step <= 100) {
				window.setTimeout(function () { fader.fade(step); }, 1);
			} else {
				// Bilderwechsel wieder freischalten
				this.fading = false;

				// neues Bild ent-positionieren
				imgs[1].className = "";
				// altes Bild entfernen
				this.element.removeChild(imgs[0]);
				// Bildübergang abgeschlossen -> nach der Pause nächstes Bild
				window.setTimeout(function () { fader.next(); }, this.viewTime);
			}
		};

		// Fader initialisieren
		this.createPlayList();
	// fertigen Fader zurückgeben
	}
}

FaderFramework.start();