import java.awt.*;
import java.applet.*;
import java.net.*;

/**
 * <a name="_intro_">
 * Kali is the top level Applet class for Kali; i.e. this is where it
 * all begins.  The <a href="#init()"><b>init</b></a>() method of this
 * class creates the various objects which comprise Kali and lays out
 * the main window.
 * <p>
 * It generally works as follows:
 * <p>
 * <ul>
 *   <li>Create a <a href="KaliCanvas.html#_top_">KaliCanvas</a>
 *	 object; this is the object which
 *	 manages the various coordinate systems that Kali uses.
 *   <li>Create a <a href="Panorama.html#_top_">Panorama</a>
 * 	 object, and connect the KaliCanvas to it.
 *	 The Panorama object is where the math happens; it keeps
 *	 track of the current group, and applies the group actions
 *	 to draw individual line segments in the KaliCanvas.
 *   <li>Create a <a href="DrawPanel.html#_top_">DrawPanel</a>
 *	 object, and connect the Panorama and
 *	 KaliCanvas objects to it.  The DrawPanel object is the
 *	 actual drawing area; it handles mouse events related to
 *	 drawing, and maintains the list of segments to be drawn.
 *   <li>Create a new <a href="ControlPanel.html#_top_">ControlPanel</a>
 *	 object, and connect the Kali
 *	 object (applet id), DrawPanel, and Panorama objects to it.
 *   <li>Lay out the ControlPanel and DrawPanel in the window.
 * </ul>
 * <p>
 *
 * The other classes of interest are
 * <a href="SymmetryGroup.html#_top_">SymmetryGroup</a>, which represents
 * a group, and
 * <a href="SymmetryGroups.html#_top_">SymmetryGroups</a>, which holds a
 * list of all the groups that the program knows about.
 *
 * @see Panorama
 * @see DrawPanel
 * @see ControlPanel
 * @see KaliCanvas
 * @see SymmetryGroup
 * @see SymmetryGroups
 */
public class Kali extends Applet implements Constants {

  /**
   * The URL that we came from is store here for future
   * reference.
   */
  URL documentBase;

  /**
   * Flag indicating whether we should dislay "Loading image: ..."
   * message the the applet's status line while images are
   * being loaded.
   */
  boolean showImageLoadingStatus = true;

  /**
   * Load an image immediately.  Kali uses this to load an image
   * containing its button bitmaps from the server.  This method will
   * not return until the image is finished loading (The Applet
   * getImage() method always returns immediately, while the image
   * loads in another thread.  In our case, however, we want to wait
   * until the image has finished loading before continuing, because
   * the next thing we do is carve the image up into individual
   * buttons.  This all happens in the constructor for the
   * ControlPanel object.)
   */
  public Image getImageNow(String imagePath) {
    MediaTracker tracker = new MediaTracker(this);

    Image image = null;
    if (showImageLoadingStatus) {
      showStatus("Loading image: " + imagePath);
    }
    image = getImage(documentBase, imagePath);
    tracker.addImage(image, 0);
    try {
      image = getImage(documentBase, imagePath);
      tracker.addImage(image, 0);
      tracker.waitForID(0);
    }
    catch (InterruptedException e) {
    }
    if (tracker.isErrorID(0)) {
      showStatus("ERROR loading image: " + imagePath);
      System.out.println("ERROR loading image: " + imagePath);
    }
    if (showImageLoadingStatus) {
      showStatus("");
    }
    return image;
  }  

  /**
   * Initialize the applet; this is where we create the objects that
   * the applet uses, connect them up to each other, and lay out the
   * window.  See the <a href="#_intro_">introduction to the
   * Kali class </a> above for more details on what happens here.
   */
  public void init() {
    documentBase = getDocumentBase();
    KaliCanvas kaliCanvas = new KaliCanvas();
    Panorama panorama = new Panorama(kaliCanvas);
    panorama.setGroup(GROUP_w22o);
    DrawPanel dp = new DrawPanel(panorama, kaliCanvas);
    ControlPanel cp = new ControlPanel(this, dp, panorama);

    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    setLayout(gridbag);
    c.insets = new Insets(6,6,4,6);		// top,left,bottom,right
    c.fill = GridBagConstraints.VERTICAL;
    gridbag.setConstraints(cp, c);
    add(cp);
    c.insets = new Insets(6,4,6,6);		// top,left,bottom,right
    c.gridwidth = GridBagConstraints.REMAINDER;
    c.fill = GridBagConstraints.BOTH;
    c.weightx = 1.0;
    c.weighty = 1.0;
    gridbag.setConstraints(dp, c);
    add(dp);
  }

  public void redraw() {
    repaint();
  }
  
  public boolean handleEvent(Event e) {
    switch (e.id) {
    case Event.WINDOW_DESTROY:
      System.exit(0);
      return true;
    default:
      return false;
    }
  }
  
  public static void main(String args[]) {
    Frame f = new Frame("Kali");
    Kali kali = new Kali();
    kali.init();
    kali.start();
    
    f.add("Center", kali);
    f.resize(300, 300);
    f.show();
  }
}
