/* SkyLogo.java
 * Copyright (C) 1998 by Hongtao Chen
 *
 * E-mail: htchen@atlonline.com
 * WWW: http://www.lamar.edu/~hongtao
 *
 ***************************************************************************
 * Permission to use, copy, modify, and distribute this software and its
 * documentation without fee for NON-COMMERCIAL purposes is hereby granted.
 *
 * THE AUTHOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
 * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHOR SHALL NOT BE LIABLE
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 ***************************************************************************/

import java.awt.*;

public class SkyLogo extends java.applet.Applet
    implements Runnable {
  private String paramStr;
  private String textStr = null;
  private String fontName;
  private int fontStyle;
  private int fontSize;
  private int sleepTime;
  private int strlen;
  private Thread runner = null;
  private Color bgColor;
  private char charStr[];
  private int charOffsets[];
  private Color colors[];
  private int yOffset;
  private int phase = 0;
  private Image bgImage=null;
  private Image offScreenImage=null;
  private Graphics offScreenGC=null;
  private Image virtualImage=null;
  private Graphics virtualGC=null;

  private Font f;
  private FontMetrics fm;
  private boolean stopped = false;
  private MediaTracker tracker;
  private int mx,my;
  private int X,Y;

  public void init() 
  {
    float h;

    mx = size().width;
    my = size().height;

    virtualImage = createImage(mx*3, my*3);
    virtualGC = virtualImage.getGraphics();
    offScreenImage = createImage(mx, my);
    offScreenGC = offScreenImage.getGraphics();

    paramStr = getParameter("bgcolor");
    if (paramStr == null)
      bgColor = Color.blue;
    else try {
      bgColor = new Color(Integer.parseInt(paramStr, 16));
    }
    catch (NumberFormatException e) {
      bgColor=Color.blue;
    }
    setBackground(bgColor);

    tracker = new MediaTracker(this);
    paramStr = getParameter("bgimage");
    if (paramStr != null)
    {
      bgImage = getImage(getDocumentBase(),paramStr);
      tracker.addImage(bgImage,0);
    }

    textStr = getParameter("text");
    if (textStr == null) {
	  textStr = "Colorful Logo";
    }
    fontName = getParameter("fontname");
    if (fontName == null) {
	  fontName = "TimesRoman";
    }
    paramStr = getParameter("fontstyle");
    if (paramStr == null)
      fontStyle = Font.PLAIN;
    else if (paramStr.equals("B"))
	  fontStyle = Font.BOLD;
    else if (paramStr.equals("I"))
	  fontStyle = Font.ITALIC;
    else if (paramStr.equals("BI"))
	  fontStyle = Font.BOLD | Font.ITALIC;
    else
      fontStyle = Font.PLAIN;
    paramStr = getParameter("fontsize");
    if (paramStr == null)
	  fontSize = 36;
    else try {
      fontSize = Integer.parseInt(paramStr);
    } catch (Exception e) {
      fontSize = 36;
    }
    paramStr = getParameter("sleeptime");
    if (paramStr == null)
	  sleepTime = 100;
    else try {
      sleepTime = Integer.parseInt(paramStr);
    } catch (Exception e) {
      sleepTime = 100;
    }
    f=new Font(fontName,fontStyle,fontSize);
    fm=getFontMetrics(f);
    yOffset = (fm.getAscent()+(my-(fm.getAscent()+fm.getDescent()))/2);
    strlen = textStr.length();
    charStr =  new char [strlen];
    charOffsets = new int [strlen];
    textStr.getChars(0,strlen,charStr,0);
    colors = new Color[strlen];
    int xPos = 0;
    for (int i = 0; i < strlen; i++) {
      h = ((float)i)/((float)strlen);
      colors[i] = new Color(Color.HSBtoRGB(h,1.0f,1.0f));
      charOffsets[i] = xPos;
      xPos+=fm.charWidth(charStr[i]);
    }
    xPos = (mx-xPos)/2;
    for (int i = 0; i < strlen; i++) 
      charOffsets[i] += xPos;

    offScreenGC.setColor(bgColor);
    offScreenGC.fillRect(0,0,mx,my);
    offScreenGC.setFont(f);

    X=Y=0;
  }

  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() 
  {
    try
    {
      tracker.waitForID(0);
    } catch (InterruptedException e)
    {
      return;
    }
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

    int bgWidth = 0;
    int bgHeight = 0;
    int xTitles = 0;
    int yTitles = 0;
    bgWidth = bgImage.getWidth(this);
    bgHeight = bgImage.getHeight(this);
    if (bgWidth > 0)
    {
      xTitles = mx/bgWidth;
      yTitles = my/bgHeight;

      for(int y=0; y<virtualImage.getHeight(this); y=y+bgHeight)
        for(int x=0; x<virtualImage.getWidth(this); x=x+bgWidth)
          virtualGC.drawImage(bgImage, x,y, this);
    } 
    else bgImage = null;

    while (runner != null) 
    {
      try 
      {
	    Thread.sleep(sleepTime);
      } catch (InterruptedException e) { }

      if (bgImage!=null)
      {
        if ( -(--X) > ((0==xTitles)? mx: xTitles*bgWidth)) X = 0;
        if ( -(--Y) > ((0==yTitles)? my: yTitles*bgHeight)) Y = 0;
      }
/*
*/
      repaint();
    }
  }

  public void update(Graphics g) {
    int x, y;
    phase--;
    if (phase < 0)
      phase=strlen-1;

    if (bgImage!=null)
      offScreenGC.drawImage(virtualImage, X, Y, this);
    else
    {
      offScreenGC.setColor(bgColor);
      offScreenGC.fillRect(0,0,mx,my);
     }
/*
*/

    for(int i=0;i<strlen;i++)
     {
       x = charOffsets[i];
       offScreenGC.setColor(colors[(phase+i)%strlen]);
       offScreenGC.drawChars(charStr,i,1,x,yOffset);
     }
    g.drawImage(offScreenImage, 0, 0, this);
  }

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

}

