/*
 * 1.1 version.
 */

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

/**
 * Based on Arthur van Hoff's animation examples, this Applet
 * can serve as a template for all animation applets.
 */

public class AnimatorApplet extends Applet implements Runnable {
    private int nFrameNumber = -1;
    private int nDelay;
    private Thread animatorThread;
    private boolean bFrozen = false;

    public void init() {
        String str;
        int nFps = 10;

        /* How many milliseconds between frames? */
        str = getParameter("nFps");
        try {
            if (str != null) {
                nFps = Integer.parseInt(str);
            }
        } catch (Exception e) {
        }
        nDelay = (nFps > 0) ? (1000 / nFps) : 100;

        /* Add a listener for a mouse press */
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                if (bFrozen) {
                    bFrozen = false;
                    start();
                } else {
                    bFrozen = true;
                    stop();
                }
            }
        } );
    }

    public void start() {
        if (bFrozen) { 
            /* Do nothing.  The user has requested that
               we stop changing the image. */
        } else {
            /* Start animating! */
            if (animatorThread == null) {
                animatorThread = new Thread(this);
            }
            animatorThread.start();
        }
    }

    public void stop() {
        /* Stop the animating thread. */
        animatorThread = null;
        showStatus("Press mouse to resume");
        if ((nDelay = nDelay / 2) < 3)
        	nDelay = 3;
    }

    public void run() {
        /* Just to be nice, lower this thread's priority so
           it can't interfere with other processing going on. */
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

        /* Remember the starting time. */
        long startTime = System.currentTimeMillis();

        /* Remember which thread we are. */
        Thread currentThread = Thread.currentThread();

        /* This is the animation loop. */
        while (currentThread == animatorThread) {
            /* Advance the animation frame. */
            nFrameNumber++;

            /* Display it. */
            repaint();

            /*Delay depending on how far we are behind. */
            try {
                startTime += nDelay;
                Thread.sleep(Math.max(0, 
                             startTime - System.currentTimeMillis()));
            } catch (InterruptedException e) {
                break;
            }
        }
    }

    /* Draw the current frame of animation. */
    public void paint(Graphics g) {
        g.drawString("Frame " + nFrameNumber, 10, 30);
        paintPicture(g);
        showStatus("Press mouse to stop");
    }
    
    /* Draw a centered resizing square of varing color. */

    private static final int nCenterX = 300/2;
    private static final int nCenterY = 100/2;
    private static final int nSizeMin = 2;
    private static final int nSizeMax = 40;
    private static int nSize    = nSizeMin;
    private static int nSign    = 1;
    
    private void paintPicture(Graphics g) {
        g.setColor(new Color(6*nSize, 3*nSize, 256-84+2*nSize));
        g.fillRect(nCenterX - nSize, nCenterY - nSize, 2*nSize, 2*nSize);
        if (nSize > nSizeMax || nSize < nSizeMin)
            nSign = -nSign;
        nSize += nSign;
   }
}
