import java.applet.Applet;
import java.awt.*;
import java.awt.image.PixelGrabber;

public class jumboscreen extends Applet {
  final char diameter=8;
  final char spacing=diameter+2;
  final char width=60;
  final char height=15;
  final int imageheight=height*spacing;
  int imagewidth;
  int a, b, w, h;
  int red, green, blue;
  int positioncounter=0;
  int pixelmap[];
  String s;
  FontMetrics fm;
  int colorchoice=0;
  int effectchoice=0;

  List fontselection=new List(4, false);
  List size=new List(4, false);
  TextArea text=new TextArea("Your text here", 25, 3);
  Checkbox bold=new Checkbox("Bold");
  Checkbox italic=new Checkbox("Italic");
  Choice effect=new Choice();
  Choice color=new Choice();
  Button go=new Button("Go");
  TextArea log=new TextArea("Events log:\n", 50, 10);

  Image testimage=null;
  Graphics testgraphics=null;
  Image osi=null;
  Graphics osg=null;

  public void init() {
    setBackground(Color.white);
    imagewidth=width*spacing;
    osi=createImage(imagewidth, imageheight);
    osg=osi.getGraphics();
    osg.setColor(Color.black);
    osg.fillRect(0, 0, imagewidth, imageheight);
    osg.setColor(new Color(40, 40, 40));
    for (a=1; a<imageheight; a+=spacing) {
      for (b=1; b<imagewidth; b+=spacing)
        osg.fillOval(b, a, diameter, diameter);
    }
    pixelmap=new int[width*(height+1)];
    w=width;
    h=height;

    setLayout(null);
    fontselection.setBounds(10, imageheight+10, 150, 100);
    add(fontselection);
    size.setBounds(220, imageheight+10, 45, 100);
    add(size);
    bold.setBounds(170, imageheight+10, 50, 30);
    italic.setBounds(170, imageheight+40, 50, 30);
    add(bold);
    add(italic);
    text.setBounds(275, imageheight+10, 300, 50);
    add(text);
    color.setBounds(275, imageheight+70, 100, 25);
    add(color);
    effect.setBounds(385, imageheight+70, 100, 25);
    add(effect);
    go.setBounds(495, imageheight+70, 40, 25);
    add(go);
    log.setBounds(10, imageheight+130, 400, 100);
    add(log);

    String fonts[]=Toolkit.getDefaultToolkit().getFontList();
    for (a=0; a<fonts.length; a++)
      fontselection.addItem(fonts[a]);

    for (a=6; a<=32; a++)
      size.addItem(Integer.toString(a));

    color.addItem("No color scheme");
    color.addItem("Alternating letters");
    color.addItem("Triple stripe");
    color.addItem("Random letters");
    color.addItem("Random");

    effect.addItem("No special effect");
    effect.addItem("Scroll text");
    effect.addItem("Flash text");
    effect.addItem("Letter-at-once");
    effect.addItem("Dissolve");
    effect.addItem("Laser printer");
    effect.addItem("SPLAT!");
    effect.addItem("Spotlight");

    fontselection.select(3);
    size.select(6);
    setfont();
    postEvent(new Event(go, 1004, ""));
    log.append("Initialization complete\n");
  }

  public void update(Graphics g) {
    paint(g);
  }

  public void paint(Graphics g) {
    if (effectchoice==0) {
      g.drawImage(osi, -width*spacing, 0, this);
    } else if (effectchoice==1) {
      g.drawImage(osi, positioncounter, 0, this);
      positioncounter -= spacing;
      if (positioncounter+imagewidth <= spacing*width)
        positioncounter=0;
      pause();
    } else if (effectchoice==2) {
      if (positioncounter%15==0)
        g.drawImage(osi, -(Math.abs(positioncounter)%2)*width*spacing, 0, this);
      positioncounter--;
      pause();
    } else {
      g.setColor(Color.white);
      g.drawString("Not implemented yet", 0, 0);
    }
    System.gc();
    repaint();
  }

  public boolean handleEvent(Event g) {
    if (g.target instanceof List || g.target instanceof Checkbox)
      setfont();
    if (g.target == color && g.id==1001) {
      colorchoice=color.getSelectedIndex();
      postEvent(new Event(go, 1004, ""));
    }
    if (g.target == effect && g.id==1001)
      effectchoice=effect.getSelectedIndex();
    if (g.target instanceof Button && g.id==1004) {
      s=text.getText();
      a=s.length();
      char array[]=new char[a];
      s.getChars(0, s.length()-1, array, 0);
      log.append("Text is "+Integer.toString(a)+" characters long\n");
      fm=text.getFontMetrics(text.getFont());
      log.append("Font: "+text.getFont().toString()+"\n");
      w=fm.charsWidth(array, 0, a)+10;
      imagewidth=w+width*2;
      h=0;
      do {
        a=s.length();
        testimage=createImage(imagewidth, height);
        testgraphics=testimage.getGraphics();
        testgraphics.setFont(text.getFont());
        testgraphics.setColor(Color.black);
        testgraphics.fillRect(0, 0, imagewidth, height);
        testgraphics.setColor(new Color(230, 200, 50));
        testgraphics.drawString(s, width, fm.getAscent()+fm.getLeading()-h);
        if (colorchoice==1 || colorchoice==3) {
          while (a>0) {
            if (colorchoice==1 && a%3==2)
              testgraphics.setColor(new Color(230, 80, 50));
            if (colorchoice==1 && a%3==1)
              testgraphics.setColor(new Color(80, 230, 50));
            if (colorchoice==1 && a%3==0)
              testgraphics.setColor(new Color(230, 200, 50));
            if (colorchoice==3)
              testgraphics.setColor(new Color((float)(Math.random()), (float)(Math.random()), (float)(Math.random())));
            testgraphics.drawString(s.substring(0, a), width, fm.getAscent()+fm.getLeading()-h);
            a--;
          }
        }
        pixelmap=new int[imagewidth*height];
        PixelGrabber pg=new PixelGrabber(testimage, 0, 0, imagewidth, height, pixelmap, 0, imagewidth);
        try {
          pg.grabPixels();
        } catch (InterruptedException e) {
          showStatus(e.toString());
        }
        h+=1;
        b=0;
        for (positioncounter=0; positioncounter<imagewidth; positioncounter++)
          b += (pixelmap[positioncounter] & 0xFFFFFF);
      } while (b==0);
      log.append("Image created: "+Integer.toString(imagewidth)+"x"+Integer.toString(height)+" pixels\n");
      log.append("Text shifted up "+Integer.toString(h)+" pixels\n");
      imagewidth *= spacing;
      osi=createImage(imagewidth, imageheight);
      osg=osi.getGraphics();
      osg.setColor(Color.black);
      osg.fillRect(0, 0, imagewidth, imageheight);
      positioncounter=0;
      for (a=1; a<imageheight; a+=spacing) {
        for (b=1; b<imagewidth; b+=spacing) {
          red = (pixelmap[positioncounter] >> 16) & 0xFF;
          green = (pixelmap[positioncounter] >> 8) & 0xFF;
          blue = pixelmap[positioncounter] & 0xFF;
          osg.setColor(new Color(red, green, blue));
          if (red==0 && green==0 && blue==0) {
            osg.setColor(new Color(20, 20, 20));
          } else if (colorchoice==2 && a<(int)(imageheight/3)) {
            osg.setColor(new Color(230, 80, 50));
          } else if (colorchoice==2 && a>(int)(2*imageheight/3)) {
            osg.setColor(new Color(80, 230, 50));
          } else if (colorchoice==4) {
            osg.setColor(new Color((float)(Math.random()), (float)(Math.random()), (float)(Math.random())));
          }
          osg.fillOval(b, a, diameter, diameter);
          positioncounter++;
        }
      }
      log.append(Integer.toString(positioncounter)+" pixels processed\n");
      positioncounter=0;
      repaint();
      return true;
    }
    return false;
  }

  public void setfont() {
    text.setFont(new Font(fontselection.getSelectedItem(),
                (bold.getState() ? Font.BOLD : Font.PLAIN) | 
                (italic.getState() ? Font.ITALIC : Font.PLAIN),
                Integer.parseInt(size.getSelectedItem())));
  }

  public void pause() {
    try {
      Thread.sleep(50);
    } catch (InterruptedException Y) {
      showStatus(Y.toString());
    }
  }
}