// Applet Scroll v1.0 - scroll.java

import java.awt.*;
import java.applet.*;
import java.util.*;

public class scroll extends Applet implements Runnable
{
   protected Image background, textscreen;
   protected Thread scroll_thread = null;
   protected Dimension appletsize;
   protected Vector line;
   protected Vector lnmode;
   protected Color textcolor, backcolor, shadowcolor;
   protected int offset, hmargin, vmargin, delay;
   protected Font font;
   protected int style, fontsize;
   protected Rectangle textrect;
   protected int cur_line, cur_pos, cur_maxpos, cur_startpos, cur_justify;
   protected String cur_text;
   protected MediaTracker tracker;

   public void init()
   {
      int i;
      String sztemp;
      Integer htemp;

      background = this.getImage(this.getDocumentBase(),this.getParameter("image"));
      appletsize = this.size();
      textcolor = getColorParameter("textcolor");
      shadowcolor = getColorParameter("shadowcolor");
      backcolor = getColorParameter("backcolor");
      offset = getIntegerParameter("offset");
      hmargin = getIntegerParameter("hmargin");
      vmargin = getIntegerParameter("vmargin");
      delay = getIntegerParameter("delay");
      style = getIntegerParameter("style");
      switch (style)
      {
         case 1:
            style = Font.BOLD;
         break;
         case 2:
            style = Font.ITALIC;
         break;
         case 3:
            style = Font.ITALIC + Font.BOLD;
         break;
         default:
            style = Font.PLAIN;
         break;
      }
      fontsize = getIntegerParameter("fontsize");
      font = new Font(getParameter("font"), style, fontsize );
      line = new Vector();
      lnmode = new Vector();
      i=0;

      while ((sztemp = this.getParameter("line"+i))!=null)
      {
         htemp = new Integer(getIntegerParameter("lnmode"+i));
         line.addElement(sztemp);
         lnmode.addElement(htemp);
         i++;
      }

      textrect = new Rectangle(hmargin, vmargin, appletsize.width - 2*hmargin, appletsize.height - 2*vmargin);
      textscreen = this.createImage(textrect.width, textrect.height);

      tracker = new MediaTracker(this);
      tracker.addImage(background, 1);

      cur_line = 0;
      cur_pos = 0;
      System.out.println("Scroll v1.0 - by Horace Chan");
   }

   public void destory()
   {
      if (background != null)
         background.flush();
      if (textscreen != null)
         textscreen.flush();
   }

   public void start()
   {
      if (scroll_thread == null)
      {
         scroll_thread = new Thread(this);
         scroll_thread.start();
      }
   }

   public void stop()
   {
      if ((scroll_thread != null) && scroll_thread.isAlive())
      {
         scroll_thread.stop();
         scroll_thread = null;
      }
   }

   public void paint(Graphics g)
   {
      int i, j;
      for (i=0; i < appletsize.width; i += background.getWidth(this))
         for (j=0; j < appletsize.height; j += background.getHeight(this))
            g.drawImage(background, i, j, this);
   }

   public void paintline_mode0(Graphics g)
   {
      int x,y;

      g.setFont(font);
      g.setColor(backcolor);
      g.fillRect(0,0,textrect.width, textrect.height);

      x = cur_startpos - cur_pos;
      y = cur_justify;

      g.setColor(shadowcolor);
      g.drawString(cur_text, x+offset, y+offset);
      g.setColor(textcolor);
      g.drawString(cur_text, x, y);
   }

   public void paintline_mode1(Graphics g)
   {
      int x,y;

      g.setFont(font);
      g.setColor(backcolor);
      g.fillRect(0,0,textrect.width, textrect.height);

      x = cur_startpos + cur_pos;
      y = cur_justify;

      g.setColor(shadowcolor);
      g.drawString(cur_text, x+offset, y+offset);
      g.setColor(textcolor);
      g.drawString(cur_text, x, y);
   }

   public void paintline_mode2(Graphics g)
   {
      int x,y;

      g.setFont(font);
      g.setColor(backcolor);
      g.fillRect(0,0,textrect.width, textrect.height);

      x = cur_justify;
      y = ( cur_startpos - cur_pos ) / 3;

      g.setColor(shadowcolor);
      g.drawString(cur_text, x+offset, y+offset);
      g.setColor(textcolor);
      g.drawString(cur_text, x, y);
   }

   public void paintline_mode3(Graphics g)
   {
      int x,y;

      g.setFont(font);
      g.setColor(backcolor);
      g.fillRect(0,0,textrect.width, textrect.height);

      x = cur_justify;
      y = (cur_startpos + cur_pos) / 3;

      g.setColor(shadowcolor);
      g.drawString(cur_text, x+offset, y+offset);
      g.setColor(textcolor);
      g.drawString(cur_text, x, y);
   }

   public void paintline_mode4(Graphics g)
   {
      int x,y;
      FontMetrics fm;
      int htemp;

      htemp = cur_pos;
      Font font = new Font(getParameter("font"), style, htemp);
      g.setFont(font);
      fm = g.getFontMetrics(font);
      g.setColor(backcolor);
      g.fillRect(0,0,textrect.width, textrect.height);

      x = cur_justify = textrect.width/2 - fm.stringWidth(cur_text) / 2;
      y = cur_justify = textrect.height/2 + fm.getAscent()/2 - fm.getLeading()/2;

      g.setColor(shadowcolor);
      g.drawString(cur_text, x+offset, y+offset);
      g.setColor(textcolor);
      g.drawString(cur_text, x, y);

      if (fm.stringWidth(cur_text) > (textrect.width * 4))
         cur_maxpos = cur_pos - 1;
   }

   public void paintline_mode5(Graphics g)
   {
      int x,y;
      FontMetrics fm;
      int htemp;

      htemp = cur_startpos - cur_pos;
      Font font = new Font(getParameter("font"), style, htemp);
      g.setFont(font);
      fm = g.getFontMetrics(font);
      g.setColor(backcolor);
      g.fillRect(0,0,textrect.width, textrect.height);

      x = cur_justify = textrect.width/2 - fm.stringWidth(cur_text) / 2;
      y = cur_justify = textrect.height/2 + fm.getAscent()/2 - fm.getLeading()/2;

      g.setColor(shadowcolor);
      g.drawString(cur_text, x+offset, y+offset);
      g.setColor(textcolor);
      g.drawString(cur_text, x, y);

      if (htemp <= 1)
         cur_maxpos = cur_pos - 1;
   }

   public void run()
   {
      Graphics g;
      FontMetrics fm;
      int htemp;
      String sztemp;

      this.showStatus("Loading Image...");
      try { tracker.waitForAll();}
      catch (InterruptedException e)
      {
         this.showStatus("Error loading image!");
         return;
      }

      while(true)
      {

         g = textscreen.getGraphics();
         htemp = ((Integer)lnmode.elementAt(cur_line)).intValue();

         if (cur_pos == 0)
         {
            cur_text = (String)line.elementAt(cur_line);

            fm = g.getFontMetrics(font);
            switch(htemp)
            {
               case 1:
                  cur_startpos = - fm.stringWidth(cur_text);
                  cur_maxpos = textrect.width + fm.stringWidth(cur_text);
                  cur_justify = textrect.height/2 + fm.getAscent()/2 - fm.getLeading()/2;
               break;
               case 2:
                  cur_startpos = textrect.height * 3;
                  cur_maxpos = (textrect.height + fm.getHeight()) * 3;
                  cur_justify = textrect.width/2 - fm.stringWidth(cur_text) / 2;
               break;
               case 3:
                  cur_startpos = 0;
                  cur_maxpos = (textrect.height + fm.getHeight()) * 3;
                  cur_justify = textrect.width/2 - fm.stringWidth(cur_text) / 2;
               break;
               case 4:
                  cur_startpos = 0;
                  cur_maxpos = textrect.height * 2;
                  cur_justify = 0;
               break;
               case 5:
                  cur_startpos = textrect.height * 2;
                  cur_maxpos = textrect.height * 2;
                  cur_justify = 0;
               break;
               default:
                  cur_startpos = textrect.width;
                  cur_maxpos = textrect.width + fm.stringWidth(cur_text);
                  cur_justify = textrect.height/2 + fm.getAscent()/2 - fm.getLeading()/2;
               break;
            }
         }

         switch (htemp)
         {
            case 1:
               paintline_mode1(g);
            break;
            case 2:
               paintline_mode2(g);
            break;
            case 3:
               paintline_mode3(g);
            break;
            case 4:
               paintline_mode4(g);
            break;
            case 5:
               paintline_mode5(g);
            break;
            default:
               paintline_mode0(g);
            break;
         }

         cur_pos++;
         if (cur_pos > cur_maxpos)
         {
            cur_line++;
            cur_pos = 0;
         }
         if (cur_line >= line.size())
             cur_line = 0;

         g = this.getGraphics();
         g.drawImage(textscreen, textrect.x, textrect.y, this);

         try { Thread.sleep(delay); }
         catch (InterruptedException e) {};
      }
   }

   protected Color getColorParameter(String name)
   {
      String value = this.getParameter(name);
      int intvalue;
      try { intvalue = Integer.parseInt(value, 16); }
      catch (NumberFormatException e)
      { return null; }
      return new Color(intvalue);
   }

   protected boolean getBooleanParameter(String name)
   {
      Boolean tempbool;
      String value = this.getParameter(name);

      tempbool = new Boolean(value);
      return tempbool.booleanValue();
   }

   protected int getIntegerParameter(String name)
   {
      String value = this.getParameter(name);
      int intvalue;
      try  { intvalue = Integer.parseInt(value); }
      catch (NumberFormatException e)
      { return 0; }
      return intvalue;
   }

   public String[][] getParameterInfo()
   {
      String[][] info =
      {  {"image","image URL","image"},
         {"font", "font name", "font"} };
      return info;
   }

   public String getAppletInfo()
   {
      return "Scroll v1.0 - by Horace Chan";
   }

}
