/*
 
	ScrollingText
	Matt Howitt
	mhowitt@fas.harvard.edu
	March 1996

	#include <std_disclaimer.h>

	Source released into the public domain. Do with it what you will.
*/

import java.awt.*;

public class ScrollingText extends java.applet.Applet implements Runnable {

	static String id = "ScrollingText Matt Howitt mhowitt@fas.harvard.edu";

	// Variables that control the location of text
	int x, y;
	int xstart, ystart;
	int xstop, ystop;

	// Other control variables
	Font font;
	FontMetrics metrics;
	Graphics gc;
	Image offscreen;
	Rectangle apprect;
	int width, height;

	// Command line argument variables
	Color bgColor;
	Color fgColor;
	String text;
	String fontname;
	String valign;
	String align;
	String direction;
	int fontsize;
	int fontstyle;
	int delay;
	int xdelta;
	int ydelta;

	Thread thread = null;

	public void init() {
		parseArgs();

		apprect = bounds();
		width = apprect.width;
		height = apprect.height;
		resize(width, height);

		offscreen = createImage(width, height);
		gc = offscreen.getGraphics();
		font = new Font(fontname, fontstyle, fontsize);
		gc.setFont(font);
		metrics = gc.getFontMetrics(font);

		int fheight = metrics.getMaxAscent() - metrics.getMaxDescent() + 2;
		int fwidth = metrics.stringWidth(text);

		try {
			if(align.equalsIgnoreCase("Left"))
				x = 0;
			else if(align.equalsIgnoreCase("Right"))
				x = width - fwidth + 1;
			else
				x = (width - fwidth) / 2;
		}
		catch (Exception e) {
			x = (width - fwidth) / 2;
		}

		try {
			if(valign.equalsIgnoreCase("Bottom"))
					y = height - 1;
			else if(valign.equalsIgnoreCase("Top"))
				y = fheight + 1;
			else
				y = (height - fheight) / 2 + fheight;
		}
		catch (Exception e) {
			y = (height - fheight) / 2 + fheight;
		}

		try {
		if(direction.equalsIgnoreCase("BottomTop")) {
			ystart = y = height + fheight;
			ystop = -fheight;
			int dist = Math.abs(ystop - ystart);
			if(dist % ydelta != 0)
				ystop -= ydelta - (dist % ydelta);
			xstart = x;
			xstop = xdelta = 0;
			ydelta = -ydelta;
		}
		else if(direction.equalsIgnoreCase("LeftRight")) {
			xstart = x = -fwidth;
			xstop = width;
			int dist = Math.abs(xstop - xstart);
			if(dist % xdelta != 0)
				xstop += xdelta - (dist % xdelta);
			ystart = y;
			ystop = ydelta = 0;
		}
		else if(direction.equalsIgnoreCase("TopBottom")) {
			ystart = y = -fheight;
			ystop = height + fheight;
			int dist = Math.abs(ystop - ystart);
			if(dist % ydelta != 0)
				ystop += ydelta - (dist % ydelta);
			xstart = x;
			xstop = xdelta = 0;
		}
		else {   // RightLeft
			xstart = x = width;
			xstop = -fwidth;
			int dist = Math.abs(xstop - xstart);
			if(dist % xdelta != 0)
				xstop -= xdelta - (dist % xdelta);
			ystart = y;
			ystop = ydelta = 0;
			xdelta = -xdelta;
		}
		}
		catch (Exception e) {
			xstart = x = width;
			xstop = -fwidth;
			int dist = Math.abs(xstop - xstart);
			if(dist % xdelta != 0)
				xstop -= xdelta - (dist % xdelta);
			ystart = y;
			ystop = ydelta = 0;
			xdelta = -xdelta;
		}
        }

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

	public void stop() {
        	thread = null;
        }

   	public void run() {
        	while (thread != null) {
            		try {
                		Thread.sleep(delay);
                	} 
            		catch (InterruptedException e) {}
            		repaint();
        	}
        	thread = null;
        }

   	public void update(Graphics g) {
        	paint(g); 
   	} 

	public void paint(Graphics g) {
        	gc.setColor(bgColor);
        	gc.fillRect(0, 0, width, height);

		gc.setColor(fgColor);
        	gc.drawString(text, x, y);
		g.drawImage(offscreen, 0, 0, this);

		if(y != ystop) {
			y += ydelta;
		}
		else {
			y = ystart;
		}
       		if(x != xstop) {
			x += xdelta;
		}
		else {
			x = xstart; 
		}
        }        
 
	private void parseArgs() {
		text = getParameter("Text");
		// null pointer exception will throw us out later.

		fontname = getParameter("Font");
		if(fontname == null) {
			fontname = new String("Arial");
		}

		String s = getParameter("FontSize");
		try {
			fontsize = Integer.parseInt(s); 
		}
		catch(Exception e) {
			fontsize = 36;
		}

		s = getParameter("FontStyle");
		try {
			if(s.equalsIgnoreCase("Plain"))
				fontstyle = Font.PLAIN;
			else if(s.equalsIgnoreCase("Italic"))
				fontstyle = Font.ITALIC;
			else if(s.equalsIgnoreCase("BoldItalic") ||
                                s.equalsIgnoreCase("ItalicBold"))
				fontstyle = Font.ITALIC | Font.BOLD;
			else
				fontstyle = Font.BOLD;
		}
		catch(Exception e) {
			fontstyle = Font.BOLD;
		}

		s = getParameter("Delay");
		try {
			delay = Integer.parseInt(s);
		}
		catch(Exception e) {
			delay = 50;
		}

		s = getParameter("Dist");
		try {
			ydelta = xdelta = Integer.parseInt(s);
		}
		catch(Exception e) {
			ydelta = xdelta = 5;
		}

		bgColor = parseColor(getParameter("bgColor"));
		if(bgColor == null)
			bgColor = Color.white;		
		fgColor = parseColor(getParameter("fgColor"));
		if(fgColor == null)
			fgColor = Color.blue;

		valign = getParameter("valign");
		align = getParameter("align");
		direction = getParameter("direction");
	}

	private Color parseColor(String s) {
		try {
			if(s.equalsIgnoreCase("Yellow"))
				return Color.yellow;
			else if(s.equalsIgnoreCase("Blue"))
				return Color.blue;
			else if(s.equalsIgnoreCase("Black"))
				return Color.black;
			else if(s.equalsIgnoreCase("Red"))
				return Color.red;
			else if(s.equalsIgnoreCase("White"))
				return Color.white;
			else if(s.equalsIgnoreCase("Green"))
				return Color.green;
			else if(s.equalsIgnoreCase("Pink"))
				return Color.pink;
			else if(s.equalsIgnoreCase("Orange"))
				return Color.orange;
			else {
				int off1 = s.indexOf(',');
				int r = Integer.parseInt(s.substring(0, off1));
				int off2 = s.indexOf(',', off1 + 1);
				int g = Integer.parseInt(s.substring(off1 + 1, off2));
				int b = Integer.parseInt(s.substring(off2 + 1));
				return new Color(r, g, b);
			}			
		}
		catch (Exception e) {
			return null;
		}
	}
}
