/*

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: 5000,			 // Zeit, die ein Bild angezeigt wird (in Millisekunden)
	fadeStep: 0.5,			  // Prozent-Schritt beim Ãœberblenden
	random: false,			  // ZufÃ¤llige Reihenfolge der Bilder (true|false)
	autostart: true,			// sofort mit dem Fading starten (true|false)

	// automatische Einstellungen
	baseURL: "",				// 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="..." /> erzeugen)
			css = document.createElement("link");
			css.rel = "stylesheet";
			css.type = "text/css";
			css.href = this.baseURL + "/fader-framework.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();
