/**
 * SpaceFill.java
 * @author Frank Ruskey
 * @version 1.0
 * @revised Johannes Martin
 * @version 1.1
 */
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

/** 
 * Class SpaceFill provides the main window for the program.
 */
public class SpaceFill extends Frame implements ActionListener {
  protected Canvas drawingCanvas; // the canvas onto which we draw
  protected Choice curveChoice;   // handle to the curve type list box
  protected Choice modeChoice;    // handle to the mode list box
  protected Choice speedChoice;   // handle to the speed list box
  protected Choice depthChoice;   // handle to the depth list box

  /**
   * Create a frame with a canvas to draw on, list boxes to select 
   * options from, and a button to start the drawing routine.
   */
  public SpaceFill () {
    super("Project 1 --- Space Filling Curves");
    System.out.println( "****** SpaceFill() started ******" );

    // create some list boxes and a button
    curveChoice = new Choice();
    curveChoice.addItem("Hilbert");
    curveChoice.addItem("Sierpinski");

    modeChoice = new Choice();
    modeChoice.addItem("all");
    modeChoice.addItem("exact");
    
    speedChoice = new Choice();
    speedChoice.addItem("fast");
    speedChoice.addItem("slow");	
    
    depthChoice = new Choice();
    for (int i = 1; i < 9; i++)
      depthChoice.addItem("" + i);
    
    Button goButton = new Button( "Draw It!" );
    goButton.addActionListener(this);

    // put the list boxes and the button into a panel
    Panel commandPanel = new Panel();
    commandPanel.setLayout(new GridLayout(15, 1, 5, 5));
    commandPanel.add(curveChoice);
    commandPanel.add(modeChoice);
    commandPanel.add(speedChoice);
    commandPanel.add(depthChoice);
    commandPanel.add(goButton);

    // create the canvas to draw on
    drawingCanvas = new Canvas();
    drawingCanvas.setSize(512, 512);
    
    // put the canvas and the panel into the window
    this.setLayout(new BorderLayout());
    add("Center", drawingCanvas);
    add("East", commandPanel);

    // enable window events (so we get notified when someone tries to
    // close the program)
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);

    // layout all components, show the window and redraw it
    pack();
    show();
    repaint();

    System.out.println( "###### SpaceFill() finished ######" );
  }

  /**
   * Clear the drawing canvas.
   */
  private void clearCanvas() {
    Dimension size    = drawingCanvas.getSize();
    Graphics graphics = drawingCanvas.getGraphics();
    graphics.setColor(drawingCanvas.getBackground());
    graphics.fillRect(0, 0, size.width, size.height);
  }
    
  /**
   * Redraw the screen when necessary.
   */
  public void paint ( Graphics g ) {
    System.out.println( "****** paint() started ******" );
    clearCanvas();
    g = drawingCanvas.getGraphics();
    g.setColor( Color.yellow );
    g.fillRect( 90, 80, 300, 30 );
    g.setColor( Color.black );
    g.drawString( "Select parameters and press button", 100, 100);
    System.out.println( "###### paint() finished ######" );
  }
  
  /** 
   * Process events generated for this window. In particular,
   * terminate the program when the user tries to close the window.
   */
  public void processEvent( AWTEvent theEvent ) {
    if (theEvent.getID() == WindowEvent.WINDOW_CLOSING) {
      dispose();
      System.exit(0);
    }
    super.processEvent(theEvent);
  }

  /**
   * Process the event generated by the user clicking the <em>Draw It!</em>
   * button. Create a new DrawableCurve object and draw it.
   *
   * @param event the event that caused the invocation of this method.
   */
  public void actionPerformed( ActionEvent event ) {
    clearCanvas();
    
    DrawableCurve thisCurve = null;
    switch (curveChoice.getSelectedIndex()) {
    case 0:
      thisCurve = new DrawableHilbert();
      break;
    case 1:
      thisCurve = new DrawableSierpinski();
      break;
    }
    
    boolean   showAll     = modeChoice.getSelectedIndex() == 0;
    boolean   goFast      = speedChoice.getSelectedIndex() == 0;
    int       depth       = depthChoice.getSelectedIndex() + 1;
    
    Dimension canvasSize  = drawingCanvas.getSize();
    thisCurve.drawTheCurves(depth, showAll, goFast, 
			    Math.min(canvasSize.width, canvasSize.height),
			    drawingCanvas.getGraphics());
  }

  /**
   * Create a new SpaceFill() object (i.e. a new main window).
   */
  public static void main(String[] args) {
    new SpaceFill();
  }
}
