/* 
 * This partial program is a template that shows how to have
 * a applet with an animation.  The animation is drawn in a Canvas.
 * The Canvas is obtained by making a separate class, Drawarea, 
 * that "extends" the Canvas, has a thread, and has a double buffer
 * to prevent flickering in the drawing.  This class will have:
 *   - a set of variables that are the "properties" of the drawing
 *   - a constructor method that initializes the properties
 *   - a paint method that does the drawing (using the property variables)
 *   - an update method that does *not* blank the old picture
 *   - a start method to start the thread
 *   - a stop method to stop the thread
 *   - a run method that the thread executes
 * 
 * To use the Drawarea, the applet creates an instance of the class,
 * using the name of the class as a type.  It can assign the
 * property variables of the Drawarea in response to the user buttons
 * and textfields.  
 * The applet should also have its own start, stop and paint methods, 
 * which just call the start, stop, and paint methods of Drawarea so 
 * that these are used whenever the window area needs it.
 */

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Bounce extends Applet implements ActionListener
{
  // create an instance of the canvas class below
  Drawarea drawing = new Drawarea ( );
  Panel controls = new Panel ( ); 
  
  // buttons for the user to start and stop the animation
  Button pause, resume;
  
  // add variables for additional panels and components go here

  public void init ( ) 
  {  
   //   create components and add them to panels, add event listeners,
   //        including the pause and resume buttons
   //  create the control panel
   // set the layout and contents of the whole applet   
    setLayout ( new BorderLayout ( ) );
    add ( drawing, BorderLayout.CENTER );
    add ( controls, BorderLayout.SOUTH );
   }

// the following three methods can be used without changes to start and
// stop the thread of the canvas, and to paint the canvas 
    // the applet start method
    public void start() 
    {  drawing.start ( );
     }
  
    // the applet stop method 
    public void stop( ) 
    {  drawing.stop ( );
     }
     
    // the applet paint method
    public void paint ( Graphics g ) 
    {  drawing.paint ( g );
     }
  
    // method to respond to action events
    public void actionPerformed ( ActionEvent event )
    {
       // respond to other buttons here. 

      // respond to pause button by calling the thread suspend method
      if ( event.getSource ( ) == pause )
         {  drawing.thread.suspend ( ) ;  }
         
      // respond to resume button by calling the thread resume method
      if ( event.getSource ( ) == resume )
      {  drawing.thread.resume ( ) ; }
   }   
}  // end of applet

class Drawarea extends Canvas implements Runnable
{
  // variables that are properties of the drawing
 
  // include these variables without change
  Thread thread;     
  // variables for double buffering: a separate image used as a canvas    
  //       and its graphics
  Image buffer;      
  Graphics gbuffer; 
  
  public Drawarea ( )
  {
  // initialization (except for values that depend on the size of the canvas)
    }
 
// use these two methods without change 
   public void start() 
   {   // create a thread and start it running
       if ( thread == null ) 
           { thread = new Thread( this );
              thread.start();
            }
    }
  
   public void stop() 
   {  // stop the thread from running and destroy it
       if ( thread != null ) 
          { thread.stop();
             thread = null;
           }
    }
   
  // this run method is what the thread executes
   public void run() 
   { // continuous loop
      while ( thread != null ) 
      {
         repaint();
         try 
             // wait for 20 milliseconds before continuing to repaint
             { Thread.sleep(20);
              } catch ( InterruptedException e ) {   };    
       }
    }
  
// give an update that does not blank out background (removing flicker)
   public void update (Graphics g)
   { paint (g);
   }
    
  public void paint ( Graphics g ) 
  {  
  // the first time, do initialization that depends on the size of the canvas
     if ( buffer == null )
     {      
        // Create an off-screen image for double buffering:
        buffer = createImage( getSize( ).width, getSize( ).height );
        // Get off-screen graphics context:
        gbuffer = buffer.getGraphics(); 
     }
     //  all drawing should take place on gbuffer
     // draw background to cover up previous image
     gbuffer.setColor ( getBackground ( ) );
     gbuffer.fillRect ( 0, 0,  getSize( ).width , getSize( ).height );

     // draw everything using gbuffer here, including setColor
         
     // draw the buffer in the canvas drawarea by using graphics g
     // this makes the drawing appear in the applet all at once
     g.drawImage( buffer, 0, 0, this );
  }
}