/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pulpcore.scene;

import pulpcore.Stage;
import pulpcore.animation.Easing;
import pulpcore.image.Colors;
import pulpcore.image.CoreGraphics;
import pulpcore.image.CoreImage;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.ImageSprite;

/**
 * Base class for transitions between Scenes.
 *
 * Subclasses should override transitionStart() and optionally
 * transitionUpdate(int) and transitionEnd().
 *
 * toSprite and fromSprite hold images of the scene we're leaving
 * and the one we're going to.
 * @author eric
 */
public abstract class TransitionScene extends Scene2D {

    protected boolean pushNewScene = true;

    protected CoreImage fromImage, toImage;
    protected Scene fromScene;
    protected Scene2D toScene;
    protected CoreGraphics toGraphics;

    protected int duration;
    protected int timer;
    protected static final int DEFAULT_DURATION = 500; //ms

    protected ImageSprite fromSprite, toSprite;

    protected Easing easing;

    public TransitionScene() {
        
        Scene fromScene = Stage.getScene();
        toImage = new CoreImage(Stage.getWidth(), Stage.getHeight());
        toGraphics = toImage.createGraphics();
        duration = DEFAULT_DURATION;
        timer = 0;
        toSprite = new ImageSprite(toImage, 0,0);
        easing = Easing.NONE;
        add(new FilledSprite(Colors.BLACK));
    }

    public TransitionScene(Scene2D toScene) {
        this();
        this.toScene = toScene;
    }

    public TransitionScene backgroundColor(int color) {
        add(new FilledSprite(color));
        return this;
    }
    
    private void go() {
        
        fromImage = Stage.getScreenshot();
        fromSprite = new ImageSprite(fromImage, 0,0);
        if (pushNewScene) Stage.pushScene(this);
        else Stage.replaceScene(this);
        toScene.load();
        add(fromSprite);
        add(toSprite);
        toGraphics.clear();
        toScene.redrawNotify();
        toScene.drawScene(toGraphics);
        toScene.unload();
        toSprite.setDirty(true);
        transitionStart();
    }

    protected abstract void transitionStart();
    protected void transitionUpdate(int elapsedTime) {;}
    protected void transitionEnd() {;}

    public void update(int elapsedTime) {
        timer += elapsedTime;

//        toScene.updateScene(elapsedTime);
        transitionUpdate(elapsedTime);

        if (timer > duration) {
            transitionEnd();
            Stage.replaceScene(toScene);
        }

    }

    public TransitionScene transitionTo(Scene2D to) {
        this.toScene = to;
        return this;
    }

    public TransitionScene duration(int dur) {
        duration = dur;
        return this;
    }

    public TransitionScene easing(Easing e) {
        this.easing = e;
        return this;
    }

    public void pushScene() {
        pushNewScene = true;
        go();
    }

    public void replaceScene() {
        pushNewScene = false;
        go();
    }

}
