/**
 * Klasse zur Steuerung von Animations-Effekten, die verkettet nacheinander ablaufen sollen.
 *
 * 
 * Alles-Erklärender-Und-Keine-Fragen-Offen-Lassender-Beispiel-Code:
 *
 *    var fxChain = new SwFxChain();
 *    fxChain.push( 'logo', {duration:2000, transition:Fx.Transitions.Quad.easeOut}, {'margin-left':800}, 0 );
 *    fxChain.push( 'logo', {duration:1000, transition:Fx.Transitions.Quad.easeOut}, {'margin-left':0} ), 0;
 *    fxChain.pushP( 'logo', {duration:500, transition:Fx.Transitions.Quad.easeOut}, {'margin-top':400}, 500 );
 *    fxChain.pushF( function() { alert('pushF test') } );
 *    fxChain.start();
 *
 */
function SwFxChain() {

    // Variablen Initialisierten
    this.chain = new Array();
    
    // Diese Chain registrieren
    if (!window.swFxChains || window.swFxChains == null) {
        window.swFxChains = new Array();
    }
    this.chainId = window.swFxChains.length;
    window.swFxChains[this.chainId] = this;
    
    /**
     * Aktuelle Größe der Chain auslesen.
     */
    this.size = function() {
        return this.chain.length;
    }
    
    /**
     * Aktion anhängen.
     */    
    this.push = function(target, options, params, delay) {
        var o = new Object();
        o['target'] = target;
        o['options'] = options;
        o['params'] = params;
        o['delay'] = delay;
        o['parallel'] = false;
        this.chain.push(o);
    }

    /**
     * Aktion anhängen, die zeitgleich zur letzten Aktion ablaufen soll.
     */    
    this.pushP = function(target, options, params, delay) {
        var o = new Object();
        o['target'] = target;
        o['options'] = options;
        o['params'] = params;
        o['delay'] = delay;
        o['parallel'] = true;
        this.chain.push(o);
    }

    /**
     * Pseudo-Aktion anhängen, die eine Funktion ausführt.
     */
    this.pushF = function(f) {
        var o = new Object();
        o['function'] = f;
        this.chain.push(o);
    }
    
    /**
     * Letzte Aktion der Kette entfernen und zurückgeben.
     */    
    this.pop = function() {
        return this.chain.pop();
    }
    
    /**
     * Erste Aktion der Kette entfernen und zurückgeben.
     */    
    this.shift = function() {
        return this.chain.shift();
    }
    
    /**
     * Eine bestimmte Aktion in der Kette abrufen.
     */
    this.get = function(i) {
        return this.chain[i];
    }
            
    /**
     * Eine bestimmte Aktion in der Kette entfernen.
     */
    this.remove = function(i) {
        var chainNew = new Array();
        for (var j=0; j<this.chain.length; j++) {
            if (j != i) {
                chainNew.push(this.chain[j]);
            }
        }
        this.chain = chainNew;
    }
   
    /**
     * Alle Aktionen aus der Kette entfernen.
     */
    this.removeAll = function() {
        while(this.chain.length > 0) {
            this.remove(this.chain.length-1);
        }
    }
    
    /**
     * Die Abarbeitung der Kette starten.
     */
    this.start = function() {
        this.next();
    }
    
    /**
     * Einen Schritt weiter in der Kette.
     */
    this.next = function() {
        if (this.size() > 0) {
            var o = this.shift();
            if (o['function'] != null) {
                // Funktion aufrufen
                o['function']();
                this.next();
            } else {
                // Animation starten
                eval("o['options'].onComplete = function() { window.swFxChains["+this.chainId+"].next(); }");
                if (!document.getElementById(o['target'])) {
                    alert("Element not found: ".o['target']);
                    return;
                }
                var fx = $(o['target']).effects(o['options']);
                if (o['delay'] != 0) {
                    fx.start.delay(o['delay'], fx, o['params'])
                } else {
                    fx.start(o['params']);
                }
                // Parallel ablaufende Animationen starten
                while (this.size() > 0 && this.get(0)['parallel'] == true) {
                    var o = this.shift();
                    if (!document.getElementById(o['target'])) {
                        alert("Element not found: ".o['target']);
                        return;
                    }
                    var fx = $(o['target']).effects(o['options']);
                    if (o['delay'] != 0) {
                        fx.start.delay(o['delay'], fx, o['params'])
                    } else {
                        fx.start(o['params']);
                    }
                }
            }
        }
    }
    
}


