/*
 * @(#)Animator.java 5.1
 *
 */

package CH.ifa.draw.util;

import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;

import de.renew.draw.ui.ontology.DrawingView;


/**
 * Animator allows to start and stop an animation by using an {@link Animatable} object.
 */
public class Animator implements Runnable {
    private static final org.apache.log4j.Logger LOGGER =
        org.apache.log4j.Logger.getLogger(Animator.class);
    private static final int MAX_DELAY = 1000 / 16;
    private static final int MIN_DELAY = MAX_DELAY / 4;
    private final DrawingView _view;
    private final Animatable _animatable;
    private boolean _isRunning;

    /**
     * Constructs a new Animator with an Animatable object and a DrawingView.
     *
     * @param animatable the animatable to be started and stopped by this Animator
     * @param view a drawing view
     */
    public Animator(Animatable animatable, DrawingView view) {
        _view = view;
        _animatable = animatable;
    }

    /**
     * Stops the animation.
     */
    public void end() {
        _animatable.animationStop();
        _isRunning = false;
    }

    @Override
    public void run() {
        _isRunning = true;
        _animatable.animationStart();
        Runnable nextStep = () -> {
            _animatable.animationStep();
            _view.checkDamage();
        };
        while (_isRunning) {
            long tm = System.currentTimeMillis();
            try {
                EventQueue.invokeAndWait(nextStep);
            } catch (InterruptedException e) {
                break;
            } catch (InvocationTargetException e) {
                LOGGER.warn(e.getMessage());
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug(Animator.class.getSimpleName() + ": " + e);
                }
            }

            // Delay for a while
            try {
                tm += MAX_DELAY;
                Thread.sleep(Math.max(MIN_DELAY, tm - System.currentTimeMillis()));
            } catch (InterruptedException e) {
                break;
            }
        }
    }
}