import java.awt.*;
import java.applet.Applet;
import java.net.*;
/*
  <applet code="AppletFrame" 
          width=300 height=50>
	  <param name="font"  value="TimesRoman">
	  <param name="text"  value="Виват, Россия!!">
	  <param name="sleep" value=5000>
  </applet>
*/

public class AppletFrame extends Applet implements Runnable {
  private Image bgImage1 = null;
  private Image bgImage2 = null;
  private Image offScreenImage;
  private Dimension offScreenSize;
  private Graphics offScreenGraphics;
  private Thread runner = null;
  private String theStr;
  private Color  colors [];
  private Font f;
  private FontMetrics   fm;
  private char   theChars[];
  private int    SleepTime=100;
  private int 	 strlen;
  private int    offsets [];
  private int 	 Xsize,Ysize;
  private int    xPos=10;	// Initial position of the string;
  private int	 yPos=30;	// Y-Postion 
  private int 	 phase=0,phase2=0;

  public void init() {
    float h;

    theStr = getParameter("font");
    if(theStr == null) {
      f = new Font("TimesRoman",Font.BOLD | Font.ITALIC,24);
    } else {
      f = new Font(theStr,Font.BOLD | Font.ITALIC,24);
    }
    fm = getFontMetrics(f); 
    yPos = fm.getAscent()+5;
    theStr = getParameter("text");
    if(theStr == null) {
      theStr="Vivet, Russia!";
    }
    Xsize = size().width;
    Ysize = size().height;
    resize(40+fm.stringWidth(theStr),20+fm.getHeight());
    strlen = theStr.length();
    theChars = new char [strlen];
    offsets  = new int  [strlen];
    colors   = new Color[strlen]; 
    theStr.getChars(0,strlen,theChars,0);
    for(int i=0;i<strlen;i++) {
      offsets[i] = xPos;
      xPos+=fm.charWidth(theChars[i]);
    }      
    for(int i=0;i<=strlen-3;i+=3) {
      //    for(int i=0;i<strlen;i++) {
      //      h = ((float)i)/((float)strlen);
      //      colors[i] = new Color(Color.HSBtoRGB(h,1.0f,1.0f));
      colors[i]  = new Color(255,255,255);
      colors[i+1]= new Color(0,0,255);
      colors[i+2]= new Color(255,0,0);
    }    
    try {
      MediaTracker tracker = new MediaTracker(this);
      bgImage1=getImage(new URL("file://localhost/home/serge/Java/n2.gif"));
      bgImage2=getImage(new URL("file://localhost/home/serge/Java/n1.jpg"));
      tracker.addImage (bgImage1, 0);
      tracker.addImage (bgImage2, 0);
    } catch (Exception e) { 
      System.out.println(e.toString());
    }
  }  
  
  public void start() {
    if(runner == null) {
      runner = new Thread(this);
      runner.start();
    }
  }

  public void stop() {
    if (runner != null && runner.isAlive())
      runner.stop();
    runner = null;
  }

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

  public final synchronized void update (Graphics g) {    
    Dimension d = size();
    if((offScreenImage == null) || (d.width != offScreenSize.width) ||  (d.height != offScreenSize.height)) {
      offScreenImage = createImage(d.width, d.height);
      offScreenSize = d;
      offScreenGraphics = offScreenImage.getGraphics();
    }
    offScreenGraphics.clearRect(0, 0, d.width, d.height);
    paint(offScreenGraphics);
    g.drawImage(offScreenImage, 0, 0, null);
    
  }

  public void paint(Graphics g) {
    int x = 0, y = 0; 
    phase--;
    if (phase < 0) phase=strlen-1;
    phase2--;
    if(phase2 < 0) phase2=Xsize;
    if(bgImage2 != null) { 
      while(y < size().height) { 
	x = 0;
	while(x < phase2) {
	  g.drawImage(bgImage1, x, y, this); 
	  x=x+bgImage1.getWidth(null);
	}
	x = phase2; 
	while(x < size().width) { 
	  g.drawImage(bgImage2, x, y, this); 
	  x=x+bgImage2.getWidth(null);
	}
	y=y+bgImage2.getHeight(null);
      }
    }
    g.setFont(f);
    for(int i=0;i<strlen;i++) {
      g.setColor(colors[(phase+i)%strlen]);
      g.drawChars(theChars,i,1,offsets[i],yPos);
    }
  }    
}
