import java.awt.*;

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

     /* This applet shows an animation in which a small square grows
        from the center of the window until it fills the whole square.
        Then, after a short delay, the process repeats.  As the sqaure grows,
        its brightness also increases.  This program depends on the
        class MosaicCanvas.
     */
                
   MosaicCanvas mosaic;  // the actual mosaic of colored squares

   Thread runner = null; // thread for running the moving disturbance animation
   boolean suspended;    // set to true when applet is suspended
   boolean finished;     // set to true when applet is destroyed
   
   public void init() {
      setLayout(new BorderLayout());
      mosaic = new MosaicCanvas(41,41);
      add("Center",mosaic);
   }
   
   synchronized public void start() {
      suspended = false;
      if (runner == null || !runner.isAlive()) {
         runner = new Thread(this);
         runner.start();
      }
      else
         notify();
   }
   
   synchronized public void stop() {
      suspended = true;
   }
   
  synchronized public void destroy() {
      finished = true;
   }
   
   public void run() {
      mosaic.fill(Color.black);
      while (true) {
         synchronized(this) {
            if (finished)
               break;
            try {
               wait(1000);
            }
            catch (InterruptedException e) {
            }
            while (suspended && ! finished)
               try {
                  wait();
               }
               catch (InterruptedException e) {
               }
            if (finished)
               break;
         }
         strobe();
      }
   }
   
   
   void strobe() {
           // Draw the animation, showing a square that starts at
           // the center of the mosaic and grows to fill the whole window.
           // The square gets brighter as it grows.  Note that the
           // animation ends immediately if the user closes the window.

      int rectSize;    // The number of rows (and columns) in the square.
      int left;        // The leftmost column in the square.
      int top;         // The topmost row in the square.
      int brightness;  // The brightness of the square, which increases from
                       //   55 to a maximum of 255 as the square grows.  This
                       //   quantity is used for all three color components,
                       //   giveing a gray color that brightens to white.

      left = 20;       // Start at the center of the 41-by-41 mosaic.
      top = 20;
      
      rectSize = 1;  
      brightness = 55;

      while (left >= 0) {
             // Draw the square in gray, pause so the user can see it, then
             // redraw the same rectangle in black, effectively erasing the
             // gray square.
          rectangle(top,left,rectSize,rectSize,brightness,brightness,brightness);
          synchronized(this) {
              while (suspended && !finished) {
                 try {
                    wait();
                 }
                 catch (InterruptedException e) {
                 }
              }
              if (finished)
                 return;
              try {
                 wait(200);
              }
              catch (InterruptedException e) {
              }
          }
          rectangle(top,left,rectSize,rectSize,0,0,0);
             // Now, adjust the parameters to get ready to draw the next square
          left--;
          top--;
          rectSize += 2;
          brightness += 10;
      }
      
   } // end strobe()
   

   void rectangle(int top, int left, int height, int width, int r, int g, int b) {
         // Draws the outline of a rectangle in the mosaic window by setting
         // the color of each little square on that rectangle;  top gives the
         // starting row of the rectangle;  left gives the starting column;
         // height gives the number of rows in the rectangle;  width is the
         // number of columns.  The red, green, and blue components of the 
         // color are specified by r, g, and b.
      int row, col;
      for ( row = top;  row < top + height;  row++ ) {
         mosaic.setColor(row, left, r, g, b);
         mosaic.setColor(row, left + width - 1, r, g, b);
      }
      for ( col = left;  col < left + height; col++ ) {
         mosaic.setColor(top, col, r, g, b);
         mosaic.setColor(top + height - 1, col, r, g, b);
      }
   }  // end rectangle


    
} // end of class