/* 
 * XTicker.java --
 *
 *      a ticker tape component.
 *
 * Copyright 1995 Regents of the University of California
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that this copyright
 * notice appears in all copies.  The University of California
 * makes no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 *
 * rcsid = "$Header: /disks/barad-dur/now/rywang/src/java/classes/ryw/XTicker.java,v 1.5 1995/11/15 21:44:42 rywang Exp $ xFS (Berkeley)"
 */

package ryw;

import java.awt.*;
import java.awt.image.*;
import java.util.Vector;


/**
 * the way this thing works:
 * it has a print buffer and a queue of strings to be printed.
 * during each iteration, we shift the print buffer to the left by
 * one character.  the right end of the print buffer is padded with
 * spaces or stuff from the print queue.
 */
public class XTicker extends Canvas implements Runnable {
    final String tickerFont      = "Courier";
    final int    tickerFontStyle = Font.BOLD;
    final int    tickerFontSize  = 12;
    final int    tickerSleep     = 60;


    Font        font;
    FontMetrics fontMet;
    int         fontHeight;
    int         visibleChars;
    String      printString;
    Vector      queue;
    Thread      worker;

    
    public XTicker (int w, int h) {
	resize (new Dimension (w, h));
	font = new Font (tickerFont, tickerFontStyle, tickerFontSize);
	printString = new String ();
	queue = new Vector ();
    }


    public void initialize (String initMsg) {
	Graphics g   = getGraphics ();
	fontMet      = g.getFontMetrics (font);
	fontHeight   = fontMet.getHeight ();
	visibleChars = size().width / fontMet.charWidth ('A');

	for (int i = 0; i < visibleChars; i++)
	    printString += " ";

	printString += initMsg;

	repaint ();
    }

    
    public void paint (Graphics g) {
	Dimension size = size ();
	g.setColor (Color.darkGray);
	g.fill3DRect (0, 0, size.width, size.height, false);

	if (printString == null)
	    return;

	String actual = printString.substring (0, visibleChars);
	Rectangle bounds = bounds ();
	g.setColor (Color.green);
	g.setFont (font);
	g.drawString (actual,
		      (bounds.width  - fontMet.stringWidth  (actual)) / 2,
		      (bounds.height + fontHeight) / 2 - 4);
    }


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


    public void stop () {
	worker.stop ();
    }


    public void run () {
	String newString;
	int currLen;
	
	for (;;) {

	    /*
	     * during each iteration, we shift the string
	     * left by one character.
	     */

	    currLen = printString.length ();
	    if (currLen <= visibleChars) {

		/*
		 * we are running out of characters to print.
		 */
		newString = printString.substring (1, currLen);

		if (queue.isEmpty ()) {

		    /*
		     * the print queue is empty, pad the print
		     * buffer with an extra space.
		     */
		    newString += " ";
		} else {

		    /*
		     * take one string from the queue and concatenate
		     * it to the print buffer.
		     */
		    String moreString = (String) queue.firstElement ();
		    queue.removeElementAt (0);
		    newString += moreString;
		}
	    } else {
		newString = printString.substring (1, currLen);
	    }
	    printString = newString;

	    repaint ();
	    
	    if (tickerSleep > 0) {
		try {
		    Thread.sleep (tickerSleep);
		} catch (InterruptedException e) {
		    break;
		}
	    }
	}
    }


    public void addString (String str) {
	queue.addElement (str);
    }
}

