// by Kirby Urner, 4D Solutions
// Last modified: Feb 28, 1999

import  java.awt.* ;
import  java.awt.event.*;

class Flipbook extends Panel implements Runnable {
// I'm a Flipbook, with my own thread which gets toggled to wait
// and notified to resume by mouse clicks (heard in Studio).

// I always draw on the next page from the one you're looking at
// (i.e. I'm double buffered).  I pass my drawspace to the Artist
// for new drawings.  Pass me a handle for the Artist object.

  protected Studio whocalls;
  protected Artist artist;

  Flipbook (Studio whocalls, Artist artist, int height, int width) {
        // register who's initializing me in whocalls
        this.whocalls = whocalls ;
        // register who's the source of my artwork in artist
        this.artist = artist;
        artist.maxheight = height;
        artist.maxwidth = width;
  }

  Image nextpage;
  Graphics drawspace;
  Color background = Color.white; //default
  Dimension pagesize;

  public void update (Graphics g) {
        Dimension d = getSize();
        // make sure my next page as big as I am
        if ((nextpage == null) || (d.width != pagesize.width)
                || (d.height != pagesize.height)) {
                nextpage = createImage(d.width, d.height);
                pagesize = d;
                drawspace = nextpage.getGraphics();
        }
        drawspace.setColor(background) ;
        drawspace.fillRect(0,0, d.width, d.height);
        // paint is where all the nitty gritty happens,
        // thanks to my artist in residence
        paint(drawspace) ;
        // flip to my next page
        g.drawImage(nextpage,0,0,this) ;
	}

  public void paint (Graphics drawspace) {
        // I'm passing my blank drawspace to my resident artist
        // (I can't draw worth beans myself -- I'm just a Flipbook)
        artist.compose(drawspace);
	}

  public void run () {
        // I run around in this loop at high speed
        while (true)  {
                try {
                   Thread.currentThread().sleep(50);
                   // Studio's Mouser listens for clicks and flips
                   // flipsuspended, prompting thread to wait/resume
                   synchronized(this) {
                       while (whocalls.flipsuspended) wait();
                   }
                }
                catch (InterruptedException e){}
                repaint(); // triggers my update method
        }
  }
}
