// -------------------------------------------------------------------------- 
// File: Curses.java 
// Class : CS1131 Introduction to Computer Science I 
// Author: Leo C. Ureel II 
// Description: The Curses! program is a random text generator. This program 
//              generates curses such as "May a thousand flees merrily infest 
//              your red Corvette!" Curses! was originally conceived by 
//              Tom Dwyer and Margot Crichfield in 1978. This version is 
//              based on Russ Walter's description of their work. 
//
//              This program works by maintaining three arrays of 
//              words/phrases; nouns, verbs, and objects. The computer 
//              randomly selects from each array and fills in the template:
// 
//                           May noun verb your object !
//
//              Templates are often employed to produce textual output that 
//              is human readable. However in production systems words and 
//              phrases are rarely chosen so randomly.
// -------------------------------------------------------------------------- 
// Modifications: 
// 01/05/2000 ureel - created. 
// -------------------------------------------------------------------------- 
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

// -------------------------------------------------------------------------- 
// Class: Curses 
// Description: Generates a random curse by filling in the form:
//              May noun verb your object! 
// -------------------------------------------------------------------------- 
public class curses extends Applet {
   // Declare and initialize data arrays.
   String nouns[ ] = { "an enraged camel",
                       "an ancient philosopher",
                       "a cocker spaniel",
                       "the Eiffel Tower",
                       "a cowardly moose",
                       "the silent majority",
                       "the last picture show",
                       "a furious trumpet player",
                       "Miss America",
                       "seven large chickens",
                       "an evil hoarde",
                       "Bill Clinton",
                       "tricky Dicky",
                       "the Jitterbug Boy",
                       "a burlesque dancer",
                       "the one-armed man",
                       "a manic robot",
                       "an altruistic alien",
                       "Mick Jagger",
                       "a picture dictionary",
                       "ten thousand bureaucrats",
                       "a superior intelligence",
                       "the Great Pyramid",
                       "Gohira",
                       "Godzilla's morning breath",
                       "Ultra Man",
                       "Andy Warhol's hair"};
   String verbs[ ] = { "send a mash note to",
                       "get inspiration from",
                       "redecorate",
                       "become an obsession of",
                       "make a salt lick out of",
                       "buy an interest in",
                       "overwhelm",
                       "pour yogurt on",
                       "sing an operatic solo to",
                       "lay an egg on",
                       "write a confession about",
                       "reveal the details of",
                       "be quoted out-of-context regarding",
                       "fart in the direction of",
                       "seek comfort in",
                       "record an album with",
                       "take a peek at",
                       "sit wearily upon"};
   String objects[ ] = { "mother-in-law",
                         "psychoanalyst",
                         "rumpus room",
                         "fern",
                         "garage",
                         "love letters",
                         "piggy bank",
                         "hamburger",
                         "dill pickle",
                         "Honda",
                         "Game Boy",
                         "home computer",
                         "significant other",
                         "new carpet",
                         "compact disc collection",
                         "favorite hat",
                         "gumby cat",
                         "ketchup",
                         "modem",
                         "final days",
                         "miserable life",
                         "font metrics",
                         "shadow"};
                   
   Image background, left, right; // Background images.
   MediaTracker t;
   int width = 0, n = 0, v = 0, o = 0; // Array index variables
                 

   // ------------------------------------------------------------------------
   // Method: init 
   // Description: Initializes the applet as follows. 
   // Side Effects: Loads image files into Image variables.
   //               Randomly sets array indices via selectParts. 
   // ------------------------------------------------------------------------
   public void init( ) {
      width = 300;
        
      // Load image files.
      t = new MediaTracker( this );
      background = getImage( getCodeBase( ), "background.gif" );
      t.addImage( background, 0 );
      left = getImage( getCodeBase( ), "left.gif");
      t.addImage( left, 1 );
      right = getImage( getCodeBase( ), "right.gif" );
      t.addImage( right, 2 );
      try { t.waitForAll( ); }
      catch ( InterruptedException ie ) { }

      setBackground( Color.white );

      // Randomly sets array indices.	
      selectParts( );
      } // end init
	

   // ----------------------------------------------------------------------- 
   // Method: mouseDown 
   // Description: Changes curse when applet is clicked upon. 
   // Inputs: Event e // Event object
   //         int x // x coordinate of mouse click. 
   //         int y // y coordinate of mouse click. 
   // Outputs: Always returns true. 
   // Side Effects: Loads image files into Image variables.
   //               Randomly sets array indices via selectParts. 
   // ----------------------------------------------------------------------
   public boolean mouseDown( Event e, int x, int y ) {
      selectParts( ); // Randomly selects new array indices.
      repaint( ); // Forces redisplay of applet window.
      return true;
      } // end mouseDown
   

   // ----------------------------------------------------------------------- 
   // Method: selectParts 
   // Description: Sets random indices for data arrays. 
   // Side Effects: Sets random indices for data arrays. 
   // ----------------------------------------------------------------------
   public void selectParts( ) {
      n = ( int ) Math.round( Math.random( ) * ( nouns.length - 1 ) );
      v = ( int ) Math.round( Math.random( ) * ( verbs.length - 1 ) );
      o = ( int ) Math.round( Math.random( ) * ( objects.length - 1 ) );
      } // end selectParts
	    

   // ----------------------------------------------------------------------- 
   // Method: paint 
   // Description: Display the applet window, 'paint'ing its contents. 
   // Inputs: Graphics g // Graphics context object. 
   // ----------------------------------------------------------------------
   public void paint( Graphics g ) {
      int x = 0, x1 = 0, x2 = 0, y = 0, y1 = 0, y2 = 0;
      FontMetrics fm = g.getFontMetrics( );
	    
      // Compose curse from data arrays using array indices.
      String part1 = "May " + nouns[ n ];
      String part2 = verbs[ v ];
      String part3 = "your " + objects[ o ] + ".";
      String msg = part1 + " " + part2 + " " + part3;

      // Draw background images.
      g.drawImage( background,
                   left.getWidth( null ),
                   0,
                   width - right.getWidth( null ) - left.getWidth( null ),
                   background.getHeight( null ),
                   null );
      g.drawImage( left, 0, 0, null );
      g.drawImage( right, width - right.getWidth( null ) , 0, null );
    
      // Determine print location in applet window.
      x = ( width - fm.stringWidth( msg ) ) / 2;
      y = fm.getAscent( ) + ( background.getHeight( null ) - fm.getHeight( ) ) / 2;
       if ( x > 25 ) {
         // Curse fits on single line in applet window.
         g.drawString( msg, x, y );
         }
      else {
         // Split curse into two lines.
         msg = part2 + " " + part3;
         x = ( width - fm.stringWidth( part1 ) ) / 2;
         x1 = ( width - fm.stringWidth( msg ) ) / 2;
         y = fm.getAscent( ) + ( ( background.getHeight( null ) / 2 ) - fm.getHeight( ) ) / 2;
         y1 = ( background.getHeight( null ) / 2 ) + y;
          if ( ( x > 25 ) && ( x1 > 25 ) ) {
            // Curse fits on two lines in applet window.
            g.drawString( part1, x, y + 10 );
            g.drawString( msg, x1, y1 - 10 );
            }
         else {
            // split curse into three lines.
            x = ( width - fm.stringWidth( part1 ) ) / 2;
            x1 = ( width - fm.stringWidth( part2 ) ) / 2;
            x2 = ( width - fm.stringWidth( part3 ) ) / 2;
            y = fm.getAscent( ) + ( ( background.getHeight( null ) / 3 ) - fm.getHeight( ) ) / 2;
            y1 = ( background.getHeight( null ) / 3 ) + y;
            y2 = ( 2 * ( background.getHeight( null ) / 3 ) ) + y;
            // Draw curse on three lines in applet window.
            g.drawString( part1, x, y + 10 );
            g.drawString( part2, x1, y1 );
            g.drawString( part3, x2, y2 - 10 );
            } // end nested if else

         } // end if else

      } // end paint

   } // end Curses

// -------------------------------------------------------------------------- 
// END OF FILE: Curses.java                           Author: Leo C. Ureel II