var FaderFramework = {

    // "Einstellungen"
    className: "fader",

    // Voreinstellungen für einen Fader
    viewTime: 5000,
    fadeStep: 0.5,
    random: false,
    autostart: true,

    // automatische Einstellungen
    baseURL: "",
    oldWinOnLoad: false,
    inits: new Array(),
    faders: new Object(),

    start: function () {
        this.oldWinOnLoad = window.onload;

        window.onload = function () {
            if (typeof(FaderFramework.oldWinOnLoad) == "function") {
                FaderFramework.oldWinOnLoad();
            }

            FaderFramework.onload();
        };
    },


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

        var scripts, i, fader, css;

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

        // fader muss eigentlich gefunden worden sein, es sei denn der Dateiname wurde geändert...
        if (fader) {
            this.baseURL = fader.src.replace(/(.*)\/[^\/]+$/, "$1");
        }

        // zu initialisierende Fader einrichten
        for (i = 0; i < this.inits.length; i++) {
            // Fader erstellen lassen
            fader = new this.Fader(this.inits[i]); // this.Fader ist eine Konstruktor-Funktion!

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

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


    // 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",
                images: ["pfad/bild1.jpg", "pfad/bild2.jpg"], // weitere Bilder möglich
                // optionale Einstellungen
                viewTime: 20000,
                fadeStep: 1,
                random: true,
                autostart: false
            }
        */
        this.inits[this.inits.length] = einstellungen; // für später abspeichern
    },


    // 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()
    */

        // wie "einstellungen" aussehen muss, siehe Funktion "init"!
        var className, imgs, i, r, vorhanden;

        // 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.ads.length < 2
        ) {
            // also gibt es keinen Fader für diesen init-Aufruf
            return false;
        }


        // Einstellungen des Faders vornehmen
        this.id = einstellungen.id;
        this.ads = einstellungen.ads;
        this.images = new Array(); // Bilder werden hier nicht als Zeichenketten, sondern später als HTML-Elementobjekte abgelegt...
        this.random = einstellungen.random ? einstellungen.random : FaderFramework.random;
        this.autostart = (typeof(einstellungen.autostart) != "undefined") ? einstellungen.autostart : FaderFramework.autostart;
        this.viewTime = einstellungen.viewTime ? einstellungen.viewTime : FaderFramework.viewTime;
        this.fadeStep = einstellungen.fadeStep ? einstellungen.fadeStep : FaderFramework.fadeStep;
        this.stopped = false; // hiermit kann später der Fader angehalten werden
        this.playList = new Array(); // Wiedergabeliste
        this.oldPlayList = [0]; // vorherige Wiedergabeliste (besteht aus einem einzigen Bild)
        this.counter = 0; // aktuell angezeigtes Bild (Zähler für Playlist)


        // DOM-Baum des HTML-Dokumentes auf den Fader vorbereiten

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

        // vor das ursprüngliche Bild setzen
        i = document.getElementById(this.id); // ursprüngliches Bild
        i.parentNode.insertBefore(this.element, i);

        // ursprüngliches Bild entfernen
        i.parentNode.removeChild(i);

        var a, img;
        // Bilder aus der Liste zu echten Bildobjekten machen und ins <span>-Element einhängen
        for (i = 0; i < einstellungen.ads.length; i++) {

            this.ads[i].img = document.createElement("img");
            this.ads[i].img.src = einstellungen.ads[i].image;
            this.ads[i].img.alt = einstellungen.ads[i].title;

            if (i > 0) {
            this.ads[i].img.className = "next";
            }
            this.ads[i].img.style.opacity = "0";
            // IE?
            this.ads[i].img.style.filter = "alpha(opacity=0)";
            this.ads[i].img.style.border = "0";

    this.element.appendChild(this.ads[i].img);
}


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


        // Playlist generieren (enthält nur die Nummern der Bilder)
        this.createPlayList = function () {
            this.playList = new Array();

            if (this.random) {
                // zufällige Reihenfolge
                while (this.playList.length < this.ads.length) {
                    vorhanden = false; // Zufallszahl bereits vorhanden?
                    r = Math.floor(Math.random() * (this.ads.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.ads.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) {
            // "single" ist true oder false und dient dazu, bei angehaltenem Fader einen einmaligen Wechsel zu ermöglichen. Wird kein Parameter übergeben, dann wird single nicht als true interpretiert.
            if (single) {
                this.stopped = true;
            }

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

            // Counter weiterzählen (oder zurücksetzen)
            this.counter = (this.counter < this.playList.length -1) ? this.counter +1 : 0;

            // Neue Playlist fällig (nur bei zufälliger Wiedergabe)?
            if  (this.counter == 0) {
                // neue Zufalls-Playlist generieren
                this.oldPlayList = this.playList; // aktuelle Playlist speichern
                this.createPlayList(); // neue aktuelle Playlist erstellen
            }

            // Fading einleiten
            this.fade();
        };
        // Fade-Funktion für den Bilderwechsel (jeder Aufruf entspricht einem Fading-Schritt)
        this.fade = function (step) {
            var imgs = new Array(), v;

            // Wenn kein Wert übertragen wurde, dann muss das Fading von vorne durchgeführt werden
            step = (!step) ? 0 : step;
            if (step == 0)
                 {
                 this.element.removeAttribute("href");
                 this.element.removeAttribute("target");
                 }
            // Das letzte Bild steht in der Liste vor dem aktuellen (falls dieses ganz am Anfang steht, gilt das letzte der alten Playlist)
            imgs[0] = (this.counter == 0) ? this.ads[this.oldPlayList[this.oldPlayList.length -1]].img : this.ads[this.playList[this.counter -1]].img;
            // Das neue Bild ist das, auf welches der Counter zeigt
            imgs[1] = this.ads[this.playList[this.counter]].img;
            for (i = 0; i < imgs.length; i++) {
                v = (i == 0) ? (100 - step) : step;
                imgs[i].style.opacity = v/100;
                // IE?
                if (imgs[i].style.filter != "undefined") {
                    imgs[i].style.filter = "alpha(opacity=" + v + ")";
                }
            }

            step += this.fadeStep;

            if (step <= 100) {
                // nächsten Fade-Schritt ausführen
                window.setTimeout(""
                    + "FaderFramework.faders."
                    + this.id
                    + ".fade("
                    + step
                    + ");",
                1);
            } else {
                // Bildübergang abgeschlossen -> nach der Pause nächstes Bild
                this.element.href = einstellungen.ads[this.playList[this.counter]].href;
                this.element.title = einstellungen.ads[this.playList[this.counter]].title;
                if (typeof(einstellungen.ads[this.playList[this.counter]].target) != "undefined") {
                this.element.target = einstellungen.ads[this.playList[this.counter]].target;
                }

                else {
                this.element.removeAttribute("target");
                }

                window.setTimeout(""
                    + "FaderFramework.faders."
                    + this.id
                    + ".next();",
                this.viewTime);
            }
        };

        // Playlist erzeugen
        this.createPlayList();

        // fertigen Fader zurückgeben
        return;
    }
}

FaderFramework.start();
