/****************************************************************/
/*   Written by Janette Duvall     Copyright (c) 1998           */
/*                                                              */
/*   this is just an example of easy animation                  */
/*   It's easy because                                          */
/*      it doesn't double buffer                                */
/*      it is not object oriented                               */
/*      it is just one shape on the screen at a time            */
/*                                                              */
/*   It does show how to center things and calculate where      */
/*   a screen position.  It has some really hokey work          */
/*   arounds for parts of java I'm still chasing.               */
/*                                                              */
/*   I hate these boxes.  They are so ugly but they do intro    */
/*   duce what we do and make it obvious you don't want to      */
/*   read this.                                                 */
/*                                                              */
/****************************************************************/

import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;

public class GoOval extends java.applet.Applet implements Runnable
{
        Thread  myThread;
        int     width, height;
        int     xPos, yPos;
        Color   color;
        int     pass;

        // the font stuff
        FontMetrics     fm;
        Font            myfont;
        int             margin;

        public void init()
        {
                color = Color.blue;
                width = 1;
                height = 50;
                xPos = 0;
                yPos = 0;
                pass = 1;

                // retrieve some font info so we don't run into the message
                myfont = new Font("Courier", Font.PLAIN, 12);
                fm = getFontMetrics(myfont);
                margin = 20 + fm.getHeight();
        }

        public void start()
        {
             if ( myThread == null )
             {
                myThread =  new Thread(this);
                myThread.start();
             }
        }

        public void run()
        {
                // set the variables that just work here
                int     deltaX = 3;         // needs to be bigger than 2 to escape
                int     deltaY = 4;

             // now we loop
             while (true)
             {
                // if we run off the screen then go back small circles
                if ( ( height >= (size().height - margin) ) ||
                                      width >= size().width  )
                {
                   width = 1;
                   height = 1;
                   if ( ++pass > 5 )
                   {
                        pass = 1;
                        height = 50;
                        color = nextColor(color);
                   }
                   else if ( pass == 3 )
                   {
                        xPos = size().width / 2;
                        yPos = ( size().height - margin ) / 2;
                   }
                }

                // find the center according to the circle
                // pass 5 we move it around by changing the x and y
                switch (pass)
                {
                        case 1:
                             xPos = (size().width - ++width) / 2;
                             yPos = (size().height - height - margin) / 2;
                             break;

                        case 3:
                             // increment the width and height first
                             width ++;
                             height ++;

                             // if we have hit a side BOUNCE
                             if ( deltaX > 0 )
                             {
                                if ( xPos + width > size().width )
                                        deltaX = - deltaX;
                             }
                             else      // we are less than zero
                             {
                                if ( xPos <= 0 )
                                        deltaX = - deltaX;
                             }

                             if ( deltaY > 0 )
                             {
                                if ( yPos + height > size().height - margin )
                                        deltaY = - deltaY;
                             }
                             else
                             {
                                if ( yPos <= 0 )
                                        deltaY = - deltaY;
                             }
                             xPos += deltaX;
                             yPos += deltaY;
                             break;

                        default:
                             xPos = (size().width - ++width) / 2;
                             yPos = (size().height - ++height - margin) / 2;
                             break;
                }

                // call the paint to show the picture
                repaint();

                // now we sleep so the user can admire our work
                try     { Thread.sleep(500); }
                catch(InterruptedException e)
                   { System.out.println( " exception caught " + e);   }
             }
        }

        public void stop()
        {
             if ( myThread != null )
             {
                myThread.stop();
                myThread = null;
             }
        }

        public void paint(Graphics g)
        {
                int stepSize = 8;

                // set the color to our saved color
                g.setColor( color );

                // draw the oval 
                switch ( pass )
                {
                     case 1:     // the assignment really was just one dimensional growth
                        g.drawString("Here is the assignment", 20,
                                                        ( size().height - 20) );
                        g.fillOval( xPos, yPos, width, height );
                        break;

                     case 2:         // to show I can really do something I am doing 2-D growth
                        g.drawString("I'm scoring brownie points here", 20, ( size().height - 20) );
                        g.fillOval( xPos, yPos, width, height );
                        break;

                     case 5:            // But really! one is boring so let's spice it up
                        g.drawString("Look at this bulls eye", 20, ( size().height - 20) );
                        for ( int i = width; i >=0; i -= stepSize )
                        {
                            // this works because height = width ( circle ) right now
                            g.fillOval( xPos + (width - i)/2, yPos + (height - i)/2, i, i );
                            // change the color for the next circle
                            if ( g.getColor() == color )
                                g.setColor( Color.white );
                            else
                                g.setColor( color );
                        }
                        break;


                     case 4:         // look at the cool 3-D on this bug!
                        g.drawString("You gotta see my COOL bug", 20,
                                                ( size().height - 20) );
                        g.fillOval( xPos, yPos, width, height );
                        for ( int i = width - 8; i >=0; i -= stepSize )
                        {
                            g.setColor( Color.white);
                            g.fillOval( xPos, yPos, i, i );
                            g.setColor( color );
                            g.fillOval( xPos+stepSize/4, yPos+stepSize/4,
                                         i-stepSize/2, i-stepSize/2 );
                        }
                        break;

                     case 3:          // This is the version that ' does everything '

                        // first we need to center the string and all that stuff
                        String str = "Here is my eternal admiration version";

                        int strLen = fm.stringWidth(str);
                        switch ( strLen / size().width )
                        {
                            case 1:        //  the window is too small so make 2 lines 
                                   // divide the string in half
                                   str = "Here is my eternal";
                                   String str2 = "admiration version";

                                   // Now do second line
                                   strLen = fm.stringWidth( str2 );
                                   int  xline2 =  (size().width - strLen)/2;
                                   g.drawString( str2, xline2, size().height - 4 );

                                   // We'll fall through to do the first line

                            case 0:          // center 1st line of text
                                   strLen = fm.stringWidth( str );
                                   int xline1 = (size().width - strLen)/2;
                                   g.drawString(str, xline1, (size().height - 20) );
                                   break;

                            default:
                                   g.drawString("Grow Window", 10,
                                                        (size().height - 20) );
                                   break;
                         }              // switch for draw string

                         // now it's time to draw the ball and watch it bounce
                         int   thisHeight = height;
                         int   thisWidth = width;

                         // check the edge and squish the ball
                         if ( xPos + width > size().width)
                                thisWidth = width - (size().width - xPos);

                         if ( yPos + height > size().height - margin )
                                thisHeight = height - (size().height - yPos);

                         g.fillOval( xPos, yPos, width, height );

                         break;
                      
                }                // end of the switch
        }

        Color   nextColor( Color thisColor )
        {
                if ( thisColor == Color.blue )
                        thisColor =  Color.red;
                else if ( thisColor == Color.red )
                        thisColor =  Color.yellow;
                else if ( thisColor == Color.yellow )
                        thisColor =  Color.orange;
                else if ( thisColor == Color.orange )
                        thisColor =  Color.green;
                else if ( thisColor == Color.green )
                        thisColor =  Color.pink;
                else if ( thisColor == Color.pink )
                        thisColor =  Color.gray;
                else if ( thisColor == Color.gray )
                        thisColor =  Color.cyan;
                else if ( thisColor == Color.cyan )
                        thisColor =  Color.magenta;
                else
                        thisColor =  Color.blue;

                return (thisColor);
        }
}

