[an error occurred while processing this directive]
import java.applet.*;
import java.awt.*;

public class poetry extends Applet {

   // board width and height  
   final int boardWidth = 500;
   final int boardHeight = 500;

   // applet size
   final int appletWidth = boardWidth;
   final int appletHeight = boardHeight + 50;

   // for double buffering to prevent flicker
   Image offScreenImage;
   Graphics offScreen;

   // do things with the font
   Font wordFont;
   FontMetrics wordMetrics;

   // is there an active tile?
   boolean activeTile = false;

   // number of words
   int numberWords;

   // define the array of tiles
   Tile tiles[];

////////////////////////////////////////////////////////////////////////////

   public void init() {

      resize (appletWidth, appletHeight);

      try {
         offScreenImage = createImage (appletWidth, appletHeight);
         offScreen = offScreenImage.getGraphics ();
      } catch (Exception e) {
         // double-buffering not available
         offScreen = null;
      }

      // what font to use
      wordFont = new Font("Helvetica", Font.BOLD, 12);
      // in case the font is stupid
      if (wordFont == null)
         wordFont = getFont();
      wordMetrics = getFontMetrics (wordFont);

      // list of words
      String wordList[] = {
	"compiler", "memory", "jolt", "caffeine", "assembler", "hacker",
	"cracker", "database", ".com", "network", "kernel", "geek",
	"keyboard", "disk", "monitor", "luser", "backbone", "bandwidth",
	"bug", "buffer", "code", "core", "bit", "mass", "daemon", "protocol",
	"feature", "file", "inode", "foo", "bar", "microsoft", "bill",
	"I", "an", "a", "I", "a", "the", "the", "ly", "ly", "ing", "ing",
	"ed", "ed", "y", "or", "and", "is", "it", "linux", "guru", "hex",
	"planets", "lamer", "magic", "nano-", "child", "fluid", "regexp",
	"RFC", "root", "tera-", "website", "portal", "user", "virus",
	"warez", "zero", "zombie", "bucket", "/dev/null", "BSD", "apparatus",
	"egg", "sausage", "fiddle", "death", "garden", "meat", "milk",
	"language", "suit", "music", "fudge", "pole", "woman", "bytes",
	"robo-", "leg", "free", "threaded", "stable", "obfuscated",
	"deprecated", "canonical", "dangling", "@", "down", "elvish",
	"with", "along", "under", "raven", "or", "client", "consultant",
	"fiber", "seeking", "backhoe", "optic", "cable", "ethernet",
	"evil", "faulty", "forked", "unstable", "hairy", "hung", "random", 
	"elaborate", "tiny", "luscious", "repulsive", "raw", "essential", 
	"mad", "gorgeous", "smooth", "delicate", "TRUE", "FALSE", 
	"enormous", "yellow", "greasy", "sweaty", "abort", "are", "banish", 
	"beat", "blow", "boil", "boot",	"can", "code", "compile", "compress",
	"configure", "conjure", "crack", "crash", "creep", "debug", "delete",
	"did", "dream", "dump", "echo", "finger", "fsck", "ftp", "go",
	"win", "windows", "addict", "MUD", "IRC", "hotmail", "die",
	"gobble", "grep", "hack", "has", "have", "heave", "ignore", 
	"interrupt", "kill -9", "kludge", "leave", "let", "like", "live", 
	"login", "logout", "mash", "mumble", "munch", "nuke", "overflow", 
	"process", "ream", "recall", "rm -rf", "RTFM", "see", "sleep",
	"smear", "smell","spawn", "spray", "squish", "swap", "swim", 
	"sync", "take", "telnet", "think", "trip", "tweak", "use", 
	"want", "watch", "whisper", "will", "worship", "freely", 
	"truly", "automagically", "program", "me", "you", "'s" };

      numberWords = wordList.length;
      tiles = new Tile [numberWords];

      // pick initial coordinates for the tiles and assign names
      for (int i=0; i < numberWords; i++)  {
         
	 tiles[i] = new Tile (wordList[i], wordMetrics);
         int tileX = boardWidth/2;
         int tileY = boardHeight/2;
	 while ((tileX + tiles[i].width > boardWidth / 4) &&
		(tileX < boardWidth * 3 / 4) && 
		(tileY + tiles[i].height > boardHeight / 3) &&
		(tileY < boardHeight * 2 / 3))  {
	   tileX = (int)(Math.random () * (float) (boardWidth - tiles[i].width));
	   tileY = (int)(Math.random () * (float) (boardHeight - tiles[i].height));
	 }
	 tiles[i].X = tileX;
	 tiles[i].Y = tileY;
      }

      tiles[0].X = boardWidth / 2;
      tiles[0].Y = boardHeight / 2 - 10;
      tiles[1].X = boardWidth / 2 + 20;      
      tiles[1].Y = boardHeight / 2 + 20;
   }


////////////////////////////////////////////////////////////////////////////

   public void paintApplet (Graphics g, Rectangle clip)  {
      if (clip.x == Integer.MIN_VALUE)
      	clip = new Rectangle (0, 0, size ().width, size ().height);

      // set up the playing rectangle
      g.setColor (new Color (99,167,167)); 
      g.fill3DRect (0, 0, boardWidth, boardHeight, true);
      // set the font in the graphics context
      g.setFont (wordFont);

      // draw the tiles (from the back of the list to the front)
      for (int i = numberWords - 1; i >= 0; i--)  {
         // only redraw the tile if it falls within the clipping region
         if (tiles[i].within_clip(clip.x, clip.y, clip.width, clip.height))  
	    tiles[i].drawTile(g);
      }
   } // end of paintApplet
 

/////////////////////////////////////////////////////////////////////////////

   public void paint (Graphics g) {
     if (offScreen != null) { 
       // double-buffering available
       paintApplet (offScreen, g.getClipRect ());
       g.drawImage (offScreenImage, 0, 0, this);
     } 
     else {
       // no double-buffering
       paintApplet (g, g.getClipRect ());
     }
   } // end of paint

///////////////////////////////////////////////////////////////////////////////
        
   public void destroy() {
     if (offScreen != null) {
       offScreen.dispose();
       // im.dispose();
     }
   } // end of destroy

/////////////////////////////////////////////////////////////////////////////  

   public void update(Graphics g) {

      // Paint the applet
      paint(g);

   }

////////////////////////////////////////////////////////////////////////////

    public boolean mouseDown(java.awt.Event event, int x, int y) {
       
      // current tile by index of the tiles array
      int currentTile = 0;
      
      // for swapping
      Tile temp;

      // check to see which one was clicked in
      for (int i=numberWords - 1; i >= 0; i--)  {
         if (tiles[i].mouse_within(x, y))  {
	    currentTile = i;
	    getAppletContext().showStatus(tiles[currentTile].word);
	    activeTile = true;
	 }
       } // end of for

      // put in the front of the list to ensure that it is redrawn
      // to be on top of the others
      if (activeTile) {
         temp = tiles[currentTile];
         for (int j = currentTile; j > 0; j--) {
            tiles[j] = tiles[j-1];
	 } // end for
         tiles [0] = temp;
      } // end of if there is a tile active
      repaint (tiles[0].X, tiles[0].Y, tiles[0].width, tiles[0].height);
      return true;
    } // end of mouseDown

////////////////////////////////////////////////////////////////////////////

   public boolean mouseDrag(java.awt.Event event, int x, int y) {
       
      getAppletContext().showStatus(tiles[0].word);
      
      if  (activeTile)  {
      	 repaint (tiles[0].X, tiles[0].Y, tiles[0].width, tiles[0].height);
         tiles[0].X = Math.max (1, Math.min (x - tiles[0].dx, boardWidth - 1 - tiles[0].width));
         tiles[0].Y = Math.max (1, Math.min (y - tiles[0].dy, boardHeight - 1 - tiles[0].height));
      	 repaint (tiles[0].X, tiles[0].Y, tiles[0].width, tiles[0].height);

      }  // end of if there is a tile active
	 return true;
   }

////////////////////////////////////////////////////////////////////////////

   public boolean mouseUp(java.awt.Event event, int x, int y) {
      activeTile = false;
      return true;
   }

/////////////////////////////////////////////////////////////////////////////
} //end of Poetry

class Tile {

  static final int padX = 6, padY = 4;
  
   // the coordinates for the upper left corner of the tile
   public int X = 0;
   public int Y = 0;

   // offset 
   public int dx;
   public int dy;

   // the width and height of the tile
   int width;
   int height;
   int ascent;
   
   // the word for this tile
   String word;
      
/////////////////////////////////////////////////////////////////////////////////////////////

   // Tile constructor
   Tile (String s, FontMetrics fm)  {

      // the word for this tile
      word = s;
      
      // find the total height of the tile; i have added 3 pixels to the top and bottom,
      // this may need adjustment
      height = fm.getHeight () + padY;
      ascent = fm.getAscent ();

      // find out how long the tile needs to be, given the word; again, i have added padding
      // of 3 pixels for each side
      width  = (fm.stringWidth (word) + padX);
   
   } // end of Tile constructor

//////////////////////////////////////////////////////////////////////////////////////////////

   // is the current mouse position within the tile's bounds?
   public boolean mouse_within (int x_coord, int y_coord)  {
       
     boolean within = false; 
     
     if (x_coord >= X  && (x_coord <= (X + width)) && y_coord >= Y && (y_coord <= (Y + height)))
     within = true;
     
     // set the offset
     dx=(x_coord - X);
     dy=(y_coord - Y);

     // true if current x and y position is within the bounds of the tile
     return (within);
   
   } // end of mouse_within

//////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean within_clip (int clipx, int clipy, int clipwidth, int clipheight)  {

      boolean within = false;

      
      // if ((l+w > LHS) && (l < RHS) && (b+h > THS) && (b < BHS))
      if (((X + width) > clipx) && (X < (clipx + clipwidth)) && ((Y + height) > clipy)
         && (Y < (clipy + clipheight)))
	    within = true;

      return (within);

   } // end of within_clip


//////////////////////////////////////////////////////////////////////////////////////////////

   public void drawTile (Graphics g) {
      
      // draw the background of the tile
      g.setColor (new Color (167,167,167));
      g.fill3DRect (X, Y, width, height, true);

      // draw the word
      g.setColor (new Color (0, 0, 0));
      g.drawString (word, X + padX / 2, Y + ascent + padY / 2);
   }  // end of drawTile

/////////////////////////////////////////////////////////////////////////////////////////////

} // end of class Tile