/*
  file:         FridgeCode.java
  purpose:      implementation of thinkgeek's fridge code
  created:      pasha nov 18-20 2000
  modified:     pasha nov 25-26 2000
  modification: 1. FridgeWord not extends Component
                2. initial positioning in several rows
		3. in FridgeWord, paint() turned from public to protected
		4. new constructor for FridgeWord
		5. no wildcrads in some import's
  notes:        heavily borrowed from Graph.java from sun's jdk demo applets
  pending:      1. dynamic allocation of word[] size
                2. mouse behaviour under netscape is sluggish;
                maybe run repainting under different thread?
		3. compose predefined phrases with motion showing?
*/


import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.StringTokenizer;


class FridgeWord //extends Component
{
    int x, y;               // coordinates of the center
    int width;              // width of the word rectangle
    static int height = 0;  // height of the word rectangle
    private static int fmAscent = 0;
    String word;

    FridgeWord (String s, FontMetrics fm)
    {
	word = s;
	width = fm.stringWidth (word) + 10;
	if (height == 0)
	    {
		height = fm.getHeight() + 4;
	    }
	if (fmAscent == 0)
	    {
		fmAscent = fm.getAscent();
	    }
    }

    void paint (Graphics g)
    {
	g.setColor (Color.white);
	g.fillRect (x - width/2, y - height/2, width, height);
	g.setColor (Color.black);
	g.drawRect (x - width/2, y - height/2, width - 1, height - 1);
	g.drawString (word, x - (width - 10)/2, (y - (height - 4)/2) + fmAscent);
    }
} // end of class FridgeWord




public class FridgeCode extends Applet implements MouseListener, MouseMotionListener
{
    FridgeWord word[] = new FridgeWord[500];
    boolean picked = false;   // whether one of the words (which is always the last 
                              // element of array) is picked by mouse
    int NUM_OF_WORDS = 0;

    Image    doublebufferImage    = null;
    Graphics doublebufferGraphics = null;
    int width, height;   // applet's width and height


    public void init ()
    {
	//super.init();

	Dimension d = getSize();
	width  = d.width;
	height = d.height;
	doublebufferImage    = createImage (width, height);
	doublebufferGraphics = doublebufferImage.getGraphics();

	int count = 0;
	int line_length = 0;
	int line = 0;
	for (
	     StringTokenizer t = new StringTokenizer (getParameter("words"), ","); 
	     t.hasMoreTokens();
	     
	     ) 
	    {
		word[count] = new FridgeWord (t.nextToken(), 
					      getGraphics().getFontMetrics());
		line_length += word[count].width;
		if (line_length > width)
		    {
			line++;
			line_length = word[count].width;
		    }

		word[count].x = line_length - (word[count].width)/2;
		word[count].y = (int)((line + 0.5)* word[count].height);
		//add (word[count]);
		
		count++;
	    }
	NUM_OF_WORDS = count;

	addMouseListener (this);
    }

    /*
    public void start () {}
    public void stop () {}
    public void destroy () {}
    */

    public void paint (Graphics g)
    {
	doublebufferGraphics.setColor (getBackground());
	doublebufferGraphics.fillRect (0, 0, width, height);
	
	for (int i=0; i < NUM_OF_WORDS; i++)
	    {
		word[i].paint (doublebufferGraphics);
	    }

	g.drawImage (doublebufferImage, 0, 0, null);
    }
    
    // this, together with doublebuffering, eliminates flickering
    public void update (Graphics g)
    {
	paint (g);
    }


    public void mousePressed (MouseEvent e) 
    {
	int x = e.getX();
	int y = e.getY();
	for (int i = NUM_OF_WORDS-1; i >= 0; i--) 
	    {
		// check whether we clicked inside this word
		if (
		    (word[i].x >= x - word[i].width/2 ) && 
		    (word[i].x <= x + word[i].width/2 ) &&
		    (word[i].y >= y - word[i].height/2) && 
		    (word[i].y <= y + word[i].height/2)
		    )
		    {
			pick (i);
			addMouseMotionListener (this);
			repaint();   // to display picked word on top
			e.consume();
			return;
		    }
	    }
    } // end of mousePressed()


    // rearrange the array with picked word last
    private void pick (int p)
    {
	if ((p < 0) || (p >= NUM_OF_WORDS))
	    {
		System.err.println ("pick index in the wrong range");
		System.exit (-1);
	    }

	FridgeWord pickedWord = word[p];
	for (int i=p; i < NUM_OF_WORDS-1; i++)
	    {
		word[i] = word[i+1];
	    }
	word[NUM_OF_WORDS-1] = pickedWord;
	picked = true;
    }


    public void mouseReleased (MouseEvent e) 
    {
        removeMouseMotionListener (this);
        if (picked) 
	    {
		picked = false;
	    }
	e.consume();
    }

    public void mouseDragged (MouseEvent e) 
    {
	if (picked)
	    {
		word[NUM_OF_WORDS-1].x = e.getX();
		word[NUM_OF_WORDS-1].y = e.getY();
		repaint();
	    }
	e.consume();
    }
    

    public void mouseEntered (MouseEvent e) {}
    public void mouseMoved   (MouseEvent e) {}
    public void mouseClicked (MouseEvent e) {}
    public void mouseExited  (MouseEvent e) {}

} // end of class FrideCode


// end of FridgeCode.java

