/**************************************************************************
* Copyright (c) 1996 Jim Crossley
*
* Although it's unlikely that anyone would actually want it,
* permission is hereby granted, without written agreement and
* without license or royalty fees, to use, copy, modify, and
* distribute this software and its documentation for any purpose,
* provided that the above copyright notice and the following three
* paragraphs appear in all copies of this software, its documentation
* and any derivative work.
*
* In no event shall Jim Crossley or Automated Design Systems, Inc. be
* liable to any party for direct, indirect, special, incidental, or
* consequential damages arising out of the use of this software and
* its documentation.
*
* The software provided hereunder is on an "as is" basis, and neither
* Jim Crossley nor Automated Design Systems, Inc. has any obligation
* to provide maintenance, support, updates, enhancements, or modifications.
*
* Derived or altered versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
***************************************************************************/
package swirly;

import java.awt.*;

/**
 * The Swirl.
 *
 * @author Jim Crossley
 * @version 1.0, 10/17/1996
 */
class Swirl implements Runnable {
    protected static int DEFAULT_REPS = 100;

    // Members
    SwirlyLand box; /** The component on which to draw. */
    Polygon p; /** The collection of points that define a Swirly. */
    Color color; /** The color of the Swirly. */
    int x; /** The x coordinate. */
    int y; /** The y coordinate. */
    int r; /** The Swirl's radius. */
    boolean clockwise; /** The direction of rotation. */
    int reps; /** The number of repetitions. */
    Thread swirler = null; /** A thread that swirls */

    /**
     * The constructor that sets the member variables.
     */
    Swirl(SwirlyLand c, int x, int y, int r, Color color, boolean direction, int reps) {
        super();
        box = c;
        this.color = color;
        this.x = x;
        this.y = y;
        this.r = r;
        clockwise = direction;
        this.reps = reps;
    }

    /**
     * Alternate constructor that uses the DEFAULT_REPS constant.
     */
    Swirl(SwirlyLand c, int x, int y, int r, Color color, boolean direction) {
        this(c,x,y,r,color,direction,DEFAULT_REPS);
    }

    /**
     * Draw the polygon.
     */
    protected void draw(Color c) {
        Graphics g = box.getGraphics();
        g.setColor(c);
        g.drawPolygon(p);
        //g.drawOval(x-r, y-r, 2*r, 2*r);
        g.dispose();
    }

    /**
     * Rotate the polygon.  This is what makes the Swirl swirl!
     * The magic is contained within the equations used in the addPoint method.
     */
    protected void rotate(int init) {
        p = new Polygon();
        if (clockwise) init = -init;
        for (int i=0; i < 360; i++) {
            double t = i / 360.0;
            p.addPoint((int)(x + r * t * Math.cos(8 * t * Math.PI + init)),
                       (int)(y + r * t * Math.sin(8 * t * Math.PI + init)));
        }
    }

    /**
     * Rotate the polygon, draw it, sleep, then erase it.
     * Repeat..
     */
    public void run() {
        for (int i=0; i++ < reps && Thread.currentThread() == swirler;) {
            try {
                rotate(i);
                draw(color);
                swirler.sleep(25);
                draw(box.getBackground());
            }
            catch (Exception e) {
                break;
            }
        }
        swirler = null;
    }

    /**
     * Start the thread.
     */
	public void start() {
		if (swirler == null) {
			swirler = new Thread(this);
			swirler.start();
		}
	}

    /**
     * Stop this thread.
     */
	synchronized public void stop() {
		if (swirler != null) {
		    swirler.stop();
    		swirler = null;
    	}
	}

}

