/*
 * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */
import java.awt.*;
import java.applet.Applet;

/* 
 * This applet animates graphics that it generates.  This example
 * isn't a good one to copy -- it flashes.  The next couple of examples 
 * will show how to eliminate the flashing.
 */

public class FlashingGraphics extends Applet implements Runnable {
    int squareSize;
    int frameNumber;
    int delay;
    Thread animatorThread;
    boolean fillColumnTop = true;
    int fps;

    public void init() {
	String str;

	// How many milliseconds between frames?
	str = getParameter("fps");
	try {
	    fps = (str != null) ? Integer.parseInt(str) : 10;
	} catch (Exception e) {
	    fps = 10;
	}
	delay = (fps > 0) ? (1000 / fps) : 100;

	// How many pixels wide is each square?
	str = getParameter("squareWidth");
	try {
	    squareSize = (str != null) ? Integer.parseInt(str) : 20;
	} catch (Exception e) {
	    squareSize = 20;
	}
    }

    public void start() {
	if (animatorThread == null) {
	    animatorThread = new Thread(this);
	    animatorThread.start();
	}
    }

    public void stop() {
	animatorThread = null;
    }

    public boolean mouseDown(Event e, int x, int y) {
	if (animatorThread == null) {
	    start();
	}
	else {
	    stop();
	}
	return false;
    }

    public void run() {
	// Remember the starting time
	long startTime = System.currentTimeMillis();

	while (Thread.currentThread() == animatorThread) {
	    // Display the next frame of animation.
	    repaint();

	    // Delay depending on how far we are behind.
	    try {
		startTime += delay;
		Thread.sleep(Math.max(0, 
				      startTime-System.currentTimeMillis()));
	    } catch (InterruptedException e) {
		break;
	    }

	    frameNumber++;
	}
    }

    public void paint(Graphics g) {
	Dimension d = size();
	boolean fillSquare;
	boolean fillNextFrame;
	int rowWidth = 0;
	int x = 0, y = 0;
	int w, h;
	int tmp;

	// Set width of first "square". Decide whether to fill it.
	fillSquare = fillColumnTop;
	fillColumnTop = !fillColumnTop;
	tmp = frameNumber % squareSize;
	if (tmp == 0) {
	    w = squareSize;
	    fillNextFrame = !fillSquare;
	} else {
	    w = tmp;
	    fillNextFrame = fillSquare;
	}

	// Draw from left to right.
	while (x < d.width) {
	    int colHeight = 0;

	    //Draw the column.
	    while (y < d.height) {
		colHeight += squareSize;

		// If we don't have room for a full square, cut if off.
		if (colHeight > d.height) {
		    h = d.height - y;
		} else {
		    h = squareSize;
		}

		// Draw the rectangle if necessary.
		if (fillSquare) {
		    g.fillRect(x, y, w, h);
		    fillSquare = false;
		} else {
		    fillSquare = true;
		} 

		y += h;
	    } // while y

	    // Determine x, y, and w for the next go around.
	    x += w;
	    y = 0;
	    w = squareSize;
	    rowWidth += w;
	    if (rowWidth > d.width) {
		w = d.width - x;
	    }
	    fillSquare = fillColumnTop;
	    fillColumnTop = !fillColumnTop;
	} // while x
	fillColumnTop = fillNextFrame;
    }
}
