package proj1b;

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

/*
 * Two classes: proj1b is the applet itself. pr1 is the playfield class
 * which is drawn on the upper portion of the applet field.
 * 
 * Commented out code was used in debugging. Several potential extensions
 * are pointed out, although goodness knows if they will be implemented.
 * Note that the Java 1.0 mouse-response interface is used here for 
 * simplicity.
 */
public class proj1b extends Applet implements ItemListener, ActionListener {
   pr1 pr1ptr;
   Choice c1;
   Button b1;
   GridBagLayout gridbag;
   GridBagConstraints c;

   /**
    * Init initializes the applet. Note that the pr1 object contained in 
    * the applet is first made, then initialized after it is inserted
    * into the applet. The pr1 initialization requires information which
    * is available only after it is inserted.
    */
   public void init() 
   {
      // Set the layout manager
      gridbag = new GridBagLayout();
      c = new GridBagConstraints();
      setLayout(gridbag);

      pr1ptr = new pr1(this);

      c.weighty   = 1;
      c.gridwidth = GridBagConstraints.REMAINDER;
      c.fill      = GridBagConstraints.BOTH;
      gridbag.setConstraints(pr1ptr, c);
      add(pr1ptr);

      c.weighty   = 0;
      c.weightx   = 1;

      c1 = new Choice();
      c1.add("Static");
      c1.add("Avoid");
      //c1.add("Approach");
      c1.addItemListener(this);
      c.gridwidth = GridBagConstraints.RELATIVE;
      c.fill      = GridBagConstraints.HORIZONTAL;
      gridbag.setConstraints(c1,c);
      add(c1);

      b1 = new Button("Reset");
      b1.setActionCommand("Reset");
      b1.addActionListener(this);
      c.gridwidth = GridBagConstraints.REMAINDER;
      gridbag.setConstraints(b1,c);
      add(b1);

      pr1ptr.setup();
   }

   /**
    * For the ItemListener implementation
    * Listen for the changed state. Unfortunately, the called function
    * is empty (time constraints, code would be beyond specs).
    */
   public void itemStateChanged(ItemEvent e) {
      // since only one Choice exists, we always know which one it is
      String mode = c1.getSelectedItem();
      pr1ptr.setMode(mode);
   }

   /**
    * For the ActionListener implementation
    * Listen for the button press. When it is pressed, reset the state
    * of the image.
    */
   public void actionPerformed(ActionEvent e) {
      String cmd = e.getActionCommand();

      if(cmd == "Reset") {
// System.out.println("Reset call ");
         pr1ptr.reset();
      }
   }
}

/**
 * pr1 is the object which contains the Playfield, which in turn stores
 * all of the sprites.
 * This class does the drawing of the Playfield, and responds to mouse
 * presses.
 */
class pr1 extends Canvas {
   Playfield area;
   proj1b parent;

   int count;             // number of times painted screen
   int countUpdates;      // number of times update

   int xSize, ySize;

   /**
    * For future use:
    * Set the mode of the objects on screen
    * Either inactive, or running away from each other, or towards
    */
   public void setMode(String s)
   {
      parent.showStatus("Mode changing not implemented (" + s + 
			") request noted.");
   }

   /**
    * Reset the sprites on the playfield and repaint. When changing,
    * update loadSprites() below.
    * Extension would implement an array of sprites.
    */
   public void reset()
   {
      area.removeSprite(0);
      area.removeSprite(1);
      loadSprites();
      repaint();
   }

   /**
    * Load the sprites to be displayed. When changing, update reset()
    * above.
    * Extension would implement variable numbers / scalings of sprites.
    */
   public void loadSprites()
   {
      Image img; 

      img = parent.getImage(parent.getDocumentBase(), "rab.gif");
      if (img == null) return;

      int w = 0, h = 0;
      try {
	 PixelGrabber gr = new PixelGrabber(img, 0, 0, -1, -1, true);
	 if (gr.grabPixels()) {
	    w = gr.getWidth();
	    h = gr.getHeight();
            area.addSprite(img.getScaledInstance(w/2,h/2,Image.SCALE_FAST), 
			   0, 50, 50);
         }
      }
      catch (InterruptedException e) {}

      img = parent.getImage(parent.getDocumentBase(), "mousie.gif");
      if (img == null) return;
      area.addSprite(img, 1, 80, 100);
   }

   /**
    * Load a background image. If no name is provided, default to
    * the Matisse background of the lily pads.
    */
   public void setBackground(String s) {
      if (s == null || s.length() < 1) s = new String("lilies.jpg");
// System.out.println("Got sting " + s);

      Image img = parent.getImage(parent.getDocumentBase(), s);
      if (img == null) return;
// System.out.println("Got an image");

      // Get the window size then scale the background accordingly
      Dimension d  = parent.getSize();
      // use in future a parameter : Integer.parseInt(numString);
      //                 String filename = getParameter("image");
      area.setBackground(img.getScaledInstance(d.width, d.height, 
					       Image.SCALE_FAST));
// System.out.println("Got sized to " + d.height + " " + d.width);
// System.out.println("Size of image became " + area.size());
   }

   /**
    * Constructor, which places pointer back up to applet
    * initializing has to be done later!
    */
   public pr1(proj1b p)
   {
      parent = p;
      area = new Playfield(4);
      xSize = ySize = 0;
   }

   /**
    * Sets up the object. This function needs to be called after
    * this object is placed in the applet window.
    */
   public void setup()
   {
      setBackground("");

      loadSprites();

      count = 1;
      countUpdates = 1;
   }

   /**
    * Paint the playfield. If the dimensions of the window has changed,
    * then reset the size of the image and repaint everything.
    * Otherwise, just display the image of the playfield.
    */
   public void paint(Graphics g)
   {
      Dimension d  = parent.getSize();
// System.out.println("Paint function called, " + count + "h,w" + d.height + " " + d.width);
      if(xSize != d.width || ySize != d.height) {
	 xSize = d.width;
	 ySize = d.height;
	 area.undraw();
	 setBackground("");
	 area.draw();
      }
      // changed this to parent...?
      Image output = area.toImage(parent);
      g.drawImage(output, 0, 0, parent);
   // g.drawImage(output, 2, 2, d.width-4, d.height-4, this);
   // g.drawRect(0,0,d.width,d.height);
     //  parent.showStatus("Paint called " + count + " time" + 
     //                    ((count > 1) ? "s" : ""));
       count += 1;
   }

   // this overrides the update function
   // so that there is little flicker
   public void update(Graphics g) { 
      paint(g); 
// System.out.println("Update " + countUpdates++, 250, 250);
// System.out.println("UPDATE");
   }

   // Keep track of the previous position. Not needed at this point.
   int lastx, lasty;

   /**
    * Respond to the mouse being down. Select / Deselect the sprite
    * under the mouse at this time.
    */
   public boolean mouseDown(Event e, int x, int y) {   // not Java 1.1
      if(area.mouseSelect(x,y)) {
         repaint();
// System.out.println("post paint, did it get called?");
	 lastx = x;
	 lasty = y;
	 return true;
      } else 
	 return false;
   }

   /**
    * Drag the mouse -- drag the sprite. Move sprites across the screen.
    */
   public boolean mouseDrag(Event e, int x, int y) {   // not Java 1.1
// parent.showStatus("X " + x + " Y " + y + " LX " + lastx + " LY " + lasty
// +(area.mouseMove(x,y)?"SEL":"NOT"));
// System.out.println("curr sprite " + area.currSprite);
      if(area.mouseMove(x,y)) {
// System.out.println("GOt IN ");
	 repaint();
// System.out.println("post paint, did it get called?");
	 lastx = x;
	 lasty = y;
	 return true;
      } else
	 return false;
   }

   /**
    * Respond to the mouse being un-clicked. Just eat up the event.
    */
   public boolean mouseUp(Event e, int x, int y) {   // not Java 1.1
// parent.showStatus("Mouse Up ");
      return true;
   }
}
