
/*
   This code is, for the moment, totally uncommented.  Sorry.
   
   David Eck
   Department of Mathematics and Computer Science
   Hobart and William Smith Colleges
   Geneva, NY   14456
   E-mail:  eck@hws.edu
   WWW:     http://math.hws.edu/eck
   
   June 18, 1996
   
   NOTE:  YOU CAN DO ANYTHING YOU WANT WITH THIS CODE, EXCEPT COPYRIGHT IT,
          PATENT IT, OR OTHERWISE TRY TO CLAIM CREDIT FOR IT.
          
*/

import java.awt.*;
import java.util.Random;

public class LittleCADemo extends java.applet.Applet implements Runnable {

   int[] world = null, newWorld=null;
   int left = 0, cells = -1;
   Thread runner = null;
   Color myRed;
   Color myBackground;
   int hilited = -1;
   
   public void init() {
      myBackground = new Color(150,150,255);
      setBackground(myBackground);
      myRed = new Color(200,0,0);
   }
   
   public void stop() {
      if (runner != null) {
         runner.stop();
         runner = null;
         hilited = -1;
         world = null;
         newWorld = null;
      }
   }
      
   void putHilite(Graphics g) {
      int leftSquare = (hilited == 0)? cells-1 : hilited-1;
      int rightSquare = (hilited == cells-1)? 0 : hilited+1;
      tripleSquare(g,left+leftSquare*20+2,5);
      tripleSquare(g,left+hilited*20+2,5);
      tripleSquare(g,left+rightSquare*20+2,5);
      tripleSquare(g,left+hilited*20+2,31);
   }
   
   void tripleSquare(Graphics g, int a, int b) {
      for (int i=1; i<=3; i++)
         g.drawRect(a-i,b-i,16+2*i,16+2*i);
   }
      
   void hilite(Graphics g, int cellNum) {
      if (cellNum != hilited) {
         if (hilited >= 0) {
            g.setColor(myBackground);
            putHilite(g);
         }
         hilited = cellNum;
         if (hilited >= 0) {
            g.setColor(Color.blue);
            putHilite(g);
         }
      }
   }
   
   void makeWorld(Graphics g) {
         g.setFont(new Font("Helvetica", Font.BOLD, 12));
         left = g.getFontMetrics().stringWidth("New World:  ") + 7;
         cells = (size().width - left) / 20;
         if (cells < 0)
            cells = 0;
         left = left + ((size().width - left) - 20*cells) / 2;
         if (world == null || world.length != cells) {
            world = new int[cells];
            for (int i=0; i<cells; i++)
               world[i] = 0;
            world[(cells-1)/2] = 1;
            newWorld = null;
         }
   }
   
   public void paint(Graphics g) {
      g.setFont(new Font("Helvetica", Font.BOLD, 12));
      if (runner == null)
         makeWorld(g);
      g.setColor(myRed);
      g.drawString("The World:",7,18);
      g.drawString("New World:",7,44);
      for (int i=0; i<cells; i++) {
         if (world[i] == 0)
            g.setColor(Color.white);
         else
            g.setColor(Color.black);
         g.fillRect(left + i*20 + 2, 5, 17, 17);
      }
      if (newWorld != null) {
         for (int i=0; i<cells; i++) {
            if (newWorld[i] < 0)
               g.setColor(myBackground);
            else if (newWorld[i] == 0)
               g.setColor(Color.white);
            else
               g.setColor(Color.black);
            g.fillRect(left + i*20 + 2, 31, 17, 17);
         }
      }
      if (hilited >= 0) {
         g.setColor(Color.blue);
         putHilite(g);
      }
   }
   
   public boolean mouseDown(Event evt, int x, int y) {
      if (runner == null) {
         runner = new Thread(this);
         runner.start();
      }
      return true;
   }
   
   public void run() {
      Graphics g = getGraphics();
      g.setFont(new Font("Helvetica", Font.BOLD, 12));
      makeWorld(g);
      newWorld = new int[cells];
      for (int i=0; i<cells; i++)
         newWorld[i] = -1;
      for (int i=0; i<cells; i++) {
         hilite(g,i);
         try { Thread.sleep(200); }
         catch (InterruptedException e) { }
         int a = (i==0)? cells-1 : i-1;
         int b = (i==cells-1)? 0 : i+1;
         if (world[a] == world[i] && world[b] == world[i]) {
            newWorld[i] = 0;
            g.setColor(Color.white);
         }
         else {
            newWorld[i] = 1;
            g.setColor(Color.black);
         }
         g.fillRect(left+i*20+2,31,17,17);
         try { Thread.sleep(300); }
         catch (InterruptedException e) { }
      }
      hilite(g,-1);
      for (int i=0; i<cells; i++) {
         try { Thread.sleep(200); }
         catch (InterruptedException e) { }
         world[i] = newWorld[i];
         newWorld[i] = -1;
         for (int j=30; j>=6; j-=2) {
            g.copyArea(left+i*20+2,j,17,20,0,-2);
            try { Thread.sleep(25); }
            catch (InterruptedException e) { }
         }
      }
      newWorld = null;
      runner = null;
   }
   
}

