//File: FishWinks.java
//Uses: DrawingObjectList.java
//Uses: FlipBook.java

/* This is a simple object-list and flip-book based
   drawing of a fish swimming across the screen and
   and winking when his/her eye is at the middle
   of the screen.

   Note that the fish is to swim from the right to
   the left.

   H. J. Bernstein, 29 November 2003
   
 */


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

public class FishWinks extends Applet
{
// Global data
    DrawingObjectList dol = null;

// Initialization
  public void init() {
    dol = null;
  }


// paint method to to the actual drawing
  public void paint (Graphics g_real) {
    
    // declare variables
    Graphics g;       // a graphics object
    Dimension size    // dimensions of the window
        = getSize();
    int frame;        // the current frame
    int frames;       // the total number of frames
    int cx = size.width,
        cy = size.height,
        diameter = (int)(.2*Math.min(cx, cy));
    int ii;
    int shift;
    int rshift;
    Color bodycolor = Color.yellow;             // yellow body
    Color seacolor  = new Color(128,128,255);   // light blue sea
    Color linecolor = Color.red;                // red line color
     
    frames = (int)(cx+diameter*4.0);
    
    // If the DOL exists and is the right size
    // use the pages we already created.
    
    if (dol == null 
       || dol.curFrames != frames 
       || dol.curWidth != cx 
       || dol.curHeight != cy ) {
       
      dol = new DrawingObjectList(g_real,cx,cy, this, frames);

      // draw some waves
      dol.setColor(seacolor,0,frames-1);
      // first fill the background with blue to the tops of the wave2
      dol.fillRect(0,diameter/2,cx-1,cy-1-diameter/2,0,frames-1);
      // now change to white and cut out the waves
      dol.setColor(Color.white,0,frames-1);
      for(ii=0; ii< cx; ii += diameter) {
        dol.fillOval(ii,diameter/6,diameter,diameter/2,0,frames-1);
      }
    
      for (frame = 0; frame < frames; frame++) {
        int ledge;                       // front of the fish
        ledge  = frames-frame-2*diameter-diameter/2;
        dol.setFrame(frame);

        // we now need to draw our fish.  We will use two
        // filled arcs for the body, of length 2*diameter and
        // height diameter.  To come in from the right
        // we shift in x by frames-3*frame

        // We will need a periodic shift
 
        shift = (frame%42) -10;          // a number from -10 through 31
        if (shift > 10 ) shift = 21-shift;// now -10 through 10
                                          // and 10 down to -10
        rshift = (diameter*shift)/10;     // and -diameter through diameter


        // Draw a dorsal fin

        dol.setColor(bodycolor);
        dol.fillArc(ledge+diameter+diameter/4-diameter/3,cy/2-2*diameter/3,
        2*diameter/3,diameter/3,90,180);
        dol.setColor(seacolor);
        dol.fillOval(ledge+diameter+diameter/4-diameter/6,cy/2-2*diameter/3,
        diameter/3,diameter/3);

        // Draw the body with the mouth working

        dol.setColor(bodycolor);
        dol.fillArc(ledge,cy/2-diameter/2,
        2*diameter,diameter,0,170+shift);
        dol.fillArc(ledge,cy/2-diameter/2,
        2*diameter,diameter,190-shift,170+shift);
        
        // Add a tail, make it waggle

        dol.fillArc(ledge+2*diameter,cy/2-diameter/4,
        diameter,diameter/2,90,180);
        dol.setColor(seacolor);
        dol.fillArc(ledge+2*diameter+diameter/4-rshift/6+1,
        cy/2-diameter/4,
        diameter/2+rshift/3,diameter/2,90,180);

        // draw side fin

        dol.setColor(linecolor);
        dol.drawArc(ledge+diameter+diameter/10,
          cy/2-diameter/4+(rshift+diameter)/8,
          2*diameter/3,diameter/2-(rshift+diameter)/4,180,90);
        dol.drawArc(ledge+diameter+diameter/10+diameter/6,
          cy/2-diameter/4+(rshift+diameter)/8,
          diameter/3,diameter/2-(rshift+diameter)/4,180,90);

        // draw an eye

        dol.drawOval(ledge+diameter-diameter/2-diameter/10,
           cy/2-diameter/4-diameter/10,
           diameter/5,diameter/5);
        dol.fillOval(ledge+diameter-diameter/2-diameter/20,
           cy/2-diameter/4-diameter/20,
           diameter/10,diameter/10);

        // blink the eye if we are near the middle

        if ((ledge+diameter-diameter/2 - cx/2) > -diameter/5 &&
            (ledge+diameter-diameter/2 - cx/2) < diameter/5 ) {
           dol.setColor(bodycolor);
           // half close the eye
           dol.fillArc(ledge+diameter-diameter/2-diameter/10-1,
           cy/2-diameter/4-diameter/10-1,
           diameter/5+2,diameter/5+2,0,180);
           // close completely in the middle
           if ((ledge+diameter-diameter/2 - cx/2) > -diameter/10 &&
             (ledge+diameter-diameter/2 - cx/2) < diameter/10 ) {
             dol.setColor(bodycolor);
             dol.fillArc(ledge+diameter-diameter/2-diameter/10-1,
             cy/2-diameter/4-diameter/10,
             diameter/5+2,diameter/5-1,0,-180);
             dol.setColor(linecolor);
             dol.drawArc(ledge+diameter-diameter/2-diameter/10-1,
             cy/2-diameter/4-diameter/10,
             diameter/5+2,diameter/5-1,0,-180);
           } else {
             dol.setColor(linecolor);
             dol.drawLine(ledge+diameter-diameter/2-diameter/10,
               cy/2-diameter/4,
               ledge+diameter-diameter/2+diameter/10,
               cy/2-diameter/4);
           }
        } 
      }
    } 
    
    // display the entire set of frames
    for (frame = 0; frame < frames; frame++) {

 
      dol.ShowPage(this,frame);
      try {
        Thread.sleep(25);               // sleep for 25 msec
      } catch (InterruptedException t){}
    }
   try {
      Thread.sleep(1000);              // sleep or 1 sec
    } catch (InterruptedException t) {}
    repaint();
  }

}
