package com.brackeen.javagamebook.graphics;
import java.awt.Image;
import java.util.ArrayList;

/**
    Klasa Animation zarządza serią rysunków (ramek) oraz
    czasem wyświetlania każdej z ramek.
*/
public class Animation {
    private ArrayList frames;
    private int currFrameIndex;
    private long animTime;
    private long totalDuration;

    /**
        Tworzy nowy, pusty obiekt Animation.
    */
    public Animation() {
        frames = new ArrayList();
        totalDuration = 0;
        start();
    }

    /**
        Dodaje do animacji rysunek o określonym czasie wyświetlania.
    */
    public synchronized void addFrame(Image image,
        long duration)
    {
        totalDuration += duration;
        frames.add(new AnimFrame(image, totalDuration));
    }

    /**
        Uruchamia animację od początku.
    */
    public synchronized void start() {
        animTime = 0;
        currFrameIndex = 0;
    }

    /**
        W razie potrzeby modyfikuje bieżącą ramkę (rysunek) animacji.
    */
    public synchronized void update(long elapsedTime) {
        if (frames.size() > 1) {
            animTime += elapsedTime;

            if (animTime >= totalDuration) {
                animTime = animTime % totalDuration;
                currFrameIndex = 0;
            }

            while (animTime > getFrame(currFrameIndex).endTime) {
                currFrameIndex++;
            }
        }
    }

    /**
        Pobiera bieżący rysunek z animacji. Zwraca null,
        jeżeli animacja nie zawiera rysunków.
    */
    public synchronized Image getImage() {
        if (frames.size() == 0) {
            return null;
        }
        else {
            return getFrame(currFrameIndex).image;
        }
    }

    private AnimFrame getFrame(int i) {
        return (AnimFrame)frames.get(i);
    }

    private class AnimFrame {

        Image image;
        long endTime;

        public AnimFrame(Image image, long endTime) {
            this.image = image;
            this.endTime = endTime;
        }
    }
}
