import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class tinyType extends Applet
    implements Runnable {               // Threaded application

    int maxLines=100,                   // Added by a user
        delay=100,                      // delay, controls scroll speed
        typedelay=100,                  // typedelay, controls type speed
        spacing=12,                     // spacing, between lines
        XPos=5,                         // XPos, indent 
        YPos,                           // YPos, starting position
        maxLine=0,                      // maxLine, # of Lines being sent 
        currentLine=0,                  // currentLine, where we are in the block 
        current,                        // current, initial position 
        height;                         // height, of the applet
    String[] Line = new String[100];    // Lines, to be displayed, 12 max
    Image offImage, bg;                 // Double buffering to eliminate
    Graphics offGrfx;                   // frame flicker
    Font outFont;                       // Output font (if passed)
    boolean customFont = false;         // Flag, is there a custom outFont?
    Color background, fontColor;
    Thread runner;

    public void init() {

        /****  Get attributes, if available  ****/
        String bgRed$      = getParameter("BGRED");
        String bgGreen$    = getParameter("BGGREEN");
        String bgBlue$     = getParameter("BGBLUE");
        String fgRed$      = getParameter("FGRED");
        String fgGreen$    = getParameter("FGGREEN");
        String fgBlue$     = getParameter("FGBLUE");
        String spacing$    = getParameter("SPACING");
        String delay$      = getParameter("DELAY");
        String typedelay$  = getParameter("TYPEDELAY");
        String XPos$       = getParameter("XPOS");
        String YPos$       = getParameter("YPOS");
        String maxLine$    = getParameter("MAXLINE");
        String background$ = getParameter("BACKGROUND");
        String fontName$   = getParameter("FONTNAME");
        String fontSize$   = getParameter("FONTSIZE");

        /****           Data lines           ****/
        for (int x=0; x<maxLines; x++) {
            Line[x] = getParameter("LINE" + Integer.toString(x+1));
        }

        /****          Setting Font          ****/
        if ((fontSize$ != null) && (fontName$ != null)) {
            int size = Integer.parseInt(fontSize$);
            outFont = new Font(fontName$, Font.PLAIN, size);
            customFont = true;
        }

        /****          Find maxline         ****/
        for (int x=0; x<100; x++) {
            if (Line[x] == null) break;
            maxLine++;
        }
        
        /****      Convert color values     ****/
        int Red=255;
        int Green=255; 
        int Blue=255;
        int fRed=0;
        int fGreen=0; 
        int fBlue=0;

        if (bgRed$ != null) Red = Integer.parseInt(bgRed$);
        if (bgGreen$ != null) Green = Integer.parseInt(bgGreen$);
        if (bgBlue$ != null) Blue = Integer.parseInt(bgBlue$);
        if (fgRed$ != null) fRed = Integer.parseInt(fgRed$);
        if (fgGreen$ != null) fGreen = Integer.parseInt(fgGreen$);
        if (fgBlue$ != null) fBlue = Integer.parseInt(fgBlue$);

        fontColor = new Color(fRed, fGreen, fBlue);

        background = new Color(Red, Green, Blue);
        setBackground(background);

        if (background$ !=null)
          bg = getImage(getDocumentBase(), background$);

        /****   Convert attribute values   ****/
        if (spacing$ != null)
	  spacing = Integer.parseInt(spacing$);
        
        if (delay$ != null)
	  delay = Integer.parseInt(delay$);

        if (typedelay$ != null)
	  typedelay = Integer.parseInt(typedelay$);
       
        if (XPos$ != null)
	  XPos = Integer.parseInt(XPos$);

        if (YPos$ != null)
            YPos = Integer.parseInt(YPos$);
        else
            YPos = size().height - (2*spacing);

        height = size().height;                                              

        /****        Set init index       ****/
        current = YPos;

        /****         Init buffer         ****/
        offImage = createImage(size().width, size().height);
        offGrfx = offImage.getGraphics();

    }

    public void paint(Graphics screen) {

        /****     Clear prev image        ****/
          offGrfx.setColor(background);
          offGrfx.fillRect(0,0,size().width, size().height);

        /****      Draw background        ****/
          if (bg != null)
            offGrfx.drawImage(bg, 0, current - height, null);

        /****      Set custom font        ****/
          offGrfx.setColor(fontColor);
          try { offGrfx.setFont(outFont); }
          catch (NullPointerException e) {}

        /****        Draw lines           ****/
          for (int i=0; i<(currentLine+1); i++) {
              try { offGrfx.drawString(Line[i],  XPos, current + (i * spacing)); }
              catch ( NullPointerException e ) {}
          }

        /****   Flip buffer to screen     ****/
          screen.drawImage(offImage, 0, 0, this);
    }

    public void update(Graphics screen) {

        /****      Override update        ****/
          paint(screen);
    }

    public void start() {
        if (runner == null) {
            runner = new Thread(this);
            runner.start();
        }
    }

    public void run() {
        String tempStr;

        while (true) {
 
            for (currentLine=0; currentLine<maxLine; currentLine++) {
                tempStr = Line[currentLine];
  
                for (int currentIndex=0; currentIndex<tempStr.length(); currentIndex++) {
                    Line[currentLine] = tempStr.substring(0, currentIndex+1);
                    repaint();
                    try { Thread.sleep(typedelay); }
                    catch (InterruptedException e) { }
                }
 
                /****      Scroll up 1 Line      ****/
   
                for  (int x=0; x<spacing; x++) {
                    current--;
                    repaint();
                    try { Thread.sleep(delay); }
                    catch (InterruptedException e) { }
                }
            }
            for  (int x=0; x<height; x++) {
                current--;
                repaint();
                try { Thread.sleep(delay); }
                catch (InterruptedException e) { }
            }
            current = YPos;
        }
    }

    public void stop() {
        if (runner != null) {
            runner.stop();
            runner = null;
        }
    }
}
