/*
 * Copyright (C) 1998  Ralf Wiebicke
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package de.rw7;

import java.awt.*;

public class MagicLine extends java.applet.Applet implements Runnable
{
	Color Line, Backgr;

	public void init()
	{
		setNum(5);
		Backgr = Color.black;
		Line = Color.white;
		System.out.println("Applet: init()");
	}

	public void destroy()
	{
		System.out.println("Applet: destroy()");
	}

	public void start()
	{
		if (Running == null)
		{
			Running = new Thread(this);
			Running.start();
		};
		System.out.println("Applet: start()");
	}

	public void stop()
	{
		if (Running != null)
		{
			Running.stop();
			Running = null;
		};
		System.out.println("Applet: stop()");
	}

	int Num = 0;
	float Lx[], Ly[], Vx[], Vy[];
	Polygon Pix;
	boolean PixValid;
	static float k = 0.0001f, rho = -0.7f;
	Rectangle B, P;
	Thread Running = null;

	void setNum(int Num)
	{
		if (Num < 2)
			Num = 2;
		this.Num = Num;
		Lx = new float[Num];
		Ly = new float[Num];
		Vx = new float[Num];
		Vy = new float[Num];
		PixValid = false;
		Pix = new Polygon(new int[Num], new int[Num], Num);
		for (int i = 0; i < Num; i++)
		{
			Lx[i] = (float) i / (float) Num;
			Ly[i] = 0f;
			Vx[i] = 0f;
			Vy[i] = ((float) i) / ((float) Num) / 10f;
			Pix.xpoints[i] = 0;
			Pix.ypoints[i] = 0;
		};
		B = getBounds();
		P = getBounds();
		P.x += 3;
		P.y += 3;
		P.width -= 6;
		P.height -= 6;
		P.width /= 2;
		P.height /= 2;
	}

	private final void calcPix()
	{
		if (!PixValid)
		{
			for (int i = 0; i < Num; i++)
			{
				Pix.xpoints[i] = P.x + (int) (P.width * (Lx[i] + 1));
				Pix.ypoints[i] = P.y + (int) (P.width * (Ly[i] + 1));
			};
			PixValid = true;
		};
	}

	public void run()
	{
		float dx, dy, r, Ix, Iy;

		while (Running != null)
		{
			try
			{
				Thread.sleep(50);
			}
			catch (InterruptedException e)
			{
			}

			for (int i = 0; i < Num; i++)
				for (int j = i + 1; j < Num; j++)
				{
					dx = Lx[i] - Lx[j];
					dy = Ly[i] - Ly[j];
					r = (float) Math.sqrt(dx * dx + dy * dy);
					r = k / (r * r * r);
					Ix = dx * r;
					Iy = dy * r;
					Vx[i] -= Ix;
					Vx[j] += Ix;
					Vy[i] -= Iy;
					Vy[j] += Iy;
				}
			for (int i = 0; i < Num; i++)
			{
				Lx[i] += Vx[i];
				Ly[i] += Vy[i];
				if (Lx[i] > 1)
				{
					Lx[i] = 2f - Lx[i];
					Vx[i] *= rho;
				}
				else if (Lx[i] < (-1f))
				{
					Lx[i] = -2f - Lx[i];
					Vx[i] *= rho;
				}
				if (Ly[i] > 1)
				{
					Ly[i] = 2f - Ly[i];
					Vy[i] *= rho;
				}
				else if (Ly[i] < (-1f))
				{
					Ly[i] = -2f - Ly[i];
					Vy[i] *= rho;
				}
			}
			PixValid = false;
			repaint();
		}
	}

	private final void male(Graphics g)
	{
		for (int i = 0; i < Num; i++)
			g.drawRect(Pix.xpoints[i] - 3, Pix.ypoints[i] - 3, 6, 6);
		g.drawPolygon(Pix);
	}

	public void paint(Graphics g)
	{
		g.setColor(Backgr);
		g.fillRect(0, 0, B.width, B.height);
		g.setColor(Line);
		calcPix();
		male(g);
	}

	public void update(Graphics g)
	{
		g.setColor(Backgr);
		male(g);
		g.setColor(Line);
		calcPix();
		male(g);
	}

} // class MagicLine
