package animation;

public class AnimationController {
    public static final int DEFAULT_DELAY = 100;

    private Action next;
    private boolean continuous;
    private long lastTime;
    private long delay;
    private int stepOption;

    public AnimationController()
    {
        stepOption = 0;
        next = null;
        continuous = false;
        lastTime = 0;
        delay = DEFAULT_DELAY;
    }
    
    /**
     * Ask the controller, which kind of action should be done next.
     * The controller waits until it knows this for sure.
     * @return The action.
     * @throws  InterruptedException if any thread interrupted the
     *             current thread before or while the current thread
     *             was waiting for a notification.  The <i>interrupted
     *             status</i> of the current thread is cleared when
     *             this exception is thrown.
     */
    public Action getNextAction() throws InterruptedException
    {
        long old = lastTime;
        Action ret = null;
        synchronized( this ) {
            while( next == null )
                wait();
            lastTime = System.currentTimeMillis();
            ret = next;
        }
        if( !continuous )
            next = null;
        else
        {
            if( lastTime - old < delay )
            {
                Thread.sleep( delay - ( lastTime - old ) );
                System.out.println( "sleep: " + ( delay - ( lastTime - old ) ) );
                lastTime = System.currentTimeMillis();
            }
        }
        return ret;
    }

    /**
     * activates or deactivates automatic execution
     * @param c automatic execution will be activated if c is true
     * and deactivated otherwise
     */
    public void setContinuous( boolean c )
    {
        if( !c && continuous )
        {
            synchronized( this ) {
                next = null;
            }
        }
        this.continuous = c;
    }

    /**
     * sets the delay of the automatic execution.
     * You might also want to enable it by calling setContinuous()
     * @param delay the delay in milliseconds
     */
    public void setDelay( long delay )
    {
        this.delay = delay;
    }

    /**
     * sets the next action and wakes up one thread waiting for an answer of the controller.
     * @param a
     */
    public void setNextAction( Action a )
    {
        next = a;
        synchronized( this ) {
            notify();
        }
    }
    
    public void setStepOption( int opt )
    {
        stepOption = opt;
    }
    
    public int getStepOption()
    {
        return stepOption;
    }

    /**
     * checks if automatic execution is active
     * @return true if it is
     */
    public boolean isContinuous()
    {
        return continuous;
    }
}
