package kinetix.hyperc1.userPlugIns;

/********************************************************************************\
**                                                                              **
**  (C) Copyright 1997 by Autodesk, Inc.                                        **
**                                                                              **
**  This program is copyrighted by Autodesk, Inc. and is licensed to you under  **
**  the following conditions.  You may not distribute or publish the source     **
**  code of this program in any form.  You may incorporate this code in object  **
**  form in derivative works provided such derivative works are (i.) are de-    **
**  signed and intended to work solely with Autodesk, Inc. products, and (ii.)  **
**  contain Autodesk's copyright notice "(C) Copyright 1997 by Autodesk, Inc."  **
**                                                                              **
**  AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.  AUTODESK SPE-  **
**  CIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR  **
**  A PARTICULAR USE.  AUTODESK, INC.  DOES NOT WARRANT THAT THE OPERATION OF   **
**  THE PROGRAM WILL BE UNINTERRUPTED OR ERROR FREE.                            **
**                                                                              **
\********************************************************************************/

/**************************************************************************
WavyPlugIn:  Samply PlugIn using piDraw()

Author:  Amalgamated YoYoDyne PlugIns, Inc.(Hyperwire demonstration file)

Version:  1.0

**************************************************************************/


import java.applet.Applet;

import kinetix.hyperc1.runtime.*;

import java.awt.*;


/*** Object Class ***/

public class WavyPlugIn extends HwVisualUserPlugIn

	{

	private Point cp[] = new Point[4];

	private Point vel[] = new Point[4];

	private int velocityMultiplier = 10;

	private String text = "KINETIX";
	private int fontSize = 18;

	private long prevTime = -1;

	private Rectangle[] constrainR = new Rectangle[4];

	private Font myFont;

	private Color textColor = Color.black;

	private Point dropShadowOffset = new Point(3, 3);

	private boolean useShadow = true;



	private static final double MAX_VEL = 8.0;


	/* Funtion to generate a random velocity */

	private final Point randomVel()

		{

		return new Point((int) (Math.random() * MAX_VEL), (int) (Math.random() * MAX_VEL));

		}



	/* Called at applet initialization */

	public void piEventAppletInit(Applet theApplet) throws HwException

		{

		vel[0] = randomVel();

		vel[1] = randomVel();

		vel[2] = randomVel();

		vel[3] = randomVel();


		/* register this plugin with the refreshdaemon */

		mRunService.siPlugInWantsTicks(true);



		Rectangle r = ((VisualRunService) mRunService).siGetAbsRect();

		int d = r.width / 5;

		int yc = r.height / 2;

		int w4 = r.width / 4;

		cp[0] = new Point(d, yc);

		cp[1] = new Point(d * 2, yc);

		cp[2] = new Point(d * 3, yc);

		cp[3] = new Point(d * 4, yc);



		myFont = new Font("System",Font.BOLD, fontSize);

		FontMetrics fontMetrics = theApplet.getGraphics().getFontMetrics( myFont );

		int charHeight = fontMetrics.getHeight();

		int rh = r.height - (2 * charHeight);

		constrainR[0] = new Rectangle(0, charHeight, w4, rh);

		constrainR[1] = new Rectangle(w4, charHeight, w4 * 2, rh);

		constrainR[2] = new Rectangle(w4, charHeight, w4 * 2, rh);

		constrainR[3] = new Rectangle(w4 * 3, charHeight, w4 - charHeight, rh);

		}



	/* compute point on curve */

	private final Point getBezierPT(Point v[], double t)

		{

		int 	i, j;		

		Point	q;

		Point vTemp[];



		vTemp = new Point[4];

		for (i = 0; i < 4; i++)

			vTemp[i] = new Point(v[i].x, v[i].y);



		for (i = 1; i < 4; i++)

			{	

			for (j = 0; j <= (3-i); j++)

				{

				vTemp[j].x = (int) ((1.0 - t) * vTemp[j].x + t * vTemp[j + 1].x);

				vTemp[j].y = (int) ((1.0 - t) * vTemp[j].y + t * vTemp[j + 1].y);

				}

			}



		q = vTemp[0];



		return q;

		}



	/* called by piDraw() to draw text */

	private final void drawTextOnBez(String text, Point v[], int ox, int oy, Graphics g, Point dropOffset)

		{

		int nChar = text.length();

		double t;

		Point pos;



		g.setFont(myFont);

		for (int i = 0; i < nChar; i++)

			{

			t = ((double) i / ((double) (nChar - 1)));

			pos = getBezierPT(v, t);

			if (useShadow)

				{

				Color oldColor = g.getColor();

				g.setColor(Color.black);

				g.drawString(text.substring(i, i + 1), pos.x + ox + dropOffset.x, pos.y + oy + dropOffset.y);

				g.setColor(oldColor);

				}

			g.drawString(text.substring(i, i + 1), pos.x + ox, pos.y + oy);

			}

		}



	/* called by runtime when plugin needs to be redrawn */

	public void piDraw(Graphics g, Rectangle aClipRect)

			throws HwException

		{

		Rectangle r = ((VisualRunService) mRunService).siGetAbsRect();

		g.setColor(textColor);

		drawTextOnBez(text, cp, r.x, r.y, g, dropShadowOffset);

		}



	/* keep text to bounding rect */

	private final void constrainToBox(Point p, Point v, Rectangle r)

		{

		if (p.x < r.x)

			{

			p.x = r.x;

			v.x = -v.x;

			}

		else if (p.x >= (r.x + r.width))

			{

			p.x = (r.x + r.width) - 1;

			v.x = -v.x;

			}

		if (p.y < r.y)

			{

			p.y = r.y;

			v.y = -v.y;

			}

		else if (p.y >= (r.y + r.height))

			{

			p.y = (r.y + r.height) - 1;

			v.y = -v.y;

			}

		}


	/* called when this plugin receives a timer tick */

	public void piEventRefreshDaemonTick(long timeNow, RefreshDaemon worldMover ) 

			throws HwException

		{

		if (prevTime < 0)

			prevTime = timeNow;



		long deltaTime = timeNow - prevTime;

		prevTime = timeNow;



		int dV = (int) ( deltaTime * velocityMultiplier );

		Rectangle newRect = ((VisualRunService) mRunService).siGetAbsRect();

		Point rSize = new Point(newRect.width, newRect.height);



		for (int i = 0; i < 4; i++)

			{

			cp[i].x += (vel[i].x * dV) / 1000;

			cp[i].y += (vel[i].y * dV) / 1000;

			constrainToBox(cp[i], vel[i], constrainR[i]);

			}



	 	worldMover.invalidateRect(newRect.x, newRect.y, newRect.width, newRect.height);

		}


	/* Properties Interface */

	public void fiSetSpeed(int i)

		{

		velocityMultiplier = i;

		}



	public void fiSetText(String s)

		{

		text = s;

		}



	public void fiSetColor(Color c)

		{

		textColor = c;

		}



	public void fiSetUseShadow(boolean b)

		{

		useShadow = b;

		}



	public void fiSetShadowOffset(Point p)

		{

		dropShadowOffset = p;

		}


	public void fiSetFontSize(int i)
		{
		fontSize = i;
		}


	/* Wire Interface */

	public void wiSetText(String s)

		{

		text = new String(s);

		}

	}