/*--------------------------------------------------------------------------+
|                                                                           |
|   A simple figure editor                                                  |
|                                                                           |
|   This code at http://aleph0.clarku.edu/~djoyce/cs126/Figure/Editor.java  |
|                                                                           |
+--------------------------------------------------------------------------*/

import java.awt.*;
import java.applet.Applet;

public class Editor extends Applet {

  Panel controlPanel;               // the panel of buttons
  boolean clear = false;            // switch requesting clear
  Color col;                        // current drawing color

  int nFigures;                     // the current number of figures
  int selected;                     // currently selected figure
  Figure fig[];                     // the array of figures

  int x1,y1,x2,y2;                  // mouse coordinates
  
  Graphics gContext;                // offscreen graphics context
  Image buffer;                     // offscreen buffer
  
  CheckboxGroup programMode;
  Checkbox drawLine,drawRect,fillRect,drawOval,fillOval;
  Checkbox dragBox,deleteBox;
  Choice colorChoice;
  
  final String colorName[] = {"Black","Blue","Cyan","Gray","Green",
    "Magenta","Orange","Pink","Red","White","Yellow"};
  final Color colorConst[] = {Color.black,Color.blue,Color.cyan,
    Color.gray,Color.green,Color.magenta,Color.orange,Color.pink,
    Color.red,Color.white,Color.yellow};
    
  public void init() {
    colorChoice = new Choice();
    for (int i=0; i<colorName.length; ++i)
      colorChoice.addItem(colorName[i]);
    
    programMode = new CheckboxGroup();

    controlPanel = new Panel();
    controlPanel.setLayout(new GridLayout(9,1,5,5));
    controlPanel.add (drawLine = new Checkbox("drawLine",programMode,true));
    controlPanel.add (drawRect = new Checkbox("drawRect",programMode,false));
    controlPanel.add (fillRect = new Checkbox("fillRect",programMode,false));
    controlPanel.add (drawOval = new Checkbox("drawOval",programMode,false));
    controlPanel.add (fillOval = new Checkbox("fillOval",programMode,false));
    controlPanel.add (dragBox = new Checkbox("Drag",programMode,false));
    controlPanel.add (deleteBox = new Checkbox("Delete",programMode,false));
    controlPanel.add (colorChoice);
    
    setLayout(new BorderLayout(5,5));
    add("West",controlPanel);
    col = Color.black;
    nFigures = 0;
    selected = -2;
    fig = new Figure[100];
    buffer = createImage(size().width,size().height);
    gContext = buffer.getGraphics();
  }
  
  public void paint (Graphics g) { // draw all the figures
    gContext.clearRect(0,0,size().width,size().height);
    for (int i=0; i < nFigures; ++i)
      fig[i].draw(gContext);
    g.drawImage(buffer,0,0,this);
  }

  public boolean action (Event evt, Object arg) {
    if (evt.target instanceof Checkbox)
      return true;
    else if (evt.target instanceof Choice) {
      String selectedName = colorChoice.getSelectedItem();
      for (int i=0; i<colorName.length; ++i)
        if (selectedName.equals(colorName[i]))
          col = colorConst[i];
      return true;
    }
    return false;
  }
  
  public boolean mouseDown (Event e, int x, int y) {
    x1 = x; y1 = y;
    selected = -2;
    if (dragBox.getState() || deleteBox.getState()) 
      selectFigure(x,y);
    return true;
  }
  
  public boolean mouseDrag (Event e, int x, int y) {
    x2 = x; y2=y;
    if (deleteBox.getState()) return true;
    if (dragBox.getState()) {
      if (selected == -2) return true;
      fig[selected].drag(x-x1,y-y1);
      x1 = x; y1 = y;
    } else {    // create a figure
      if (selected == nFigures-1) --nFigures;
      makeFigure();
      selected = nFigures-1;
    }
    repaint();
    return true;
  }
  
  public boolean mouseUp (Event e, int x, int y) {
    x2 = x; y2 = y;
    if (deleteBox.getState() || dragBox.getState()) {
      if (selected == -2) return true;
      if (deleteBox.getState()) 
        deleteFigure(selected);
      else 
        fig[selected].drag(x2-x1,y2-y1);
    }
    else {     // create a figure
      if (selected == nFigures-1) --nFigures;
      makeFigure();
    }
    selected = -2;
    repaint();
    return true;
  }
  
  void selectFigure(int x, int y) {
    for (int i=nFigures-1; i>=0; --i)
      if (fig[i].inFigure(x,y)) {
        selected = i;
        return;
      }
    selected = -2;
  }

  void deleteFigure(int i) {
    while (i < nFigures)
        fig[i]=fig[++i];
    --nFigures;
  }
  
  void makeFigure() {
    if (drawLine.getState())
      fig[nFigures] = new LineFigure(x1,y1,x2,y2,col);
    else if (drawRect.getState())
      fig[nFigures] = new RectFigure(x1,y1,x2,y2,false,col);
    else if (fillRect.getState())
      fig[nFigures] = new RectFigure(x1,y1,x2,y2,true,col);
    else if (drawOval.getState())
      fig[nFigures] = new OvalFigure(x1,y1,x2,y2,false,col);
    else if (fillOval.getState())
      fig[nFigures] = new OvalFigure(x1,y1,x2,y2,true,col);
    else {
      System.out.println("No shape selected.");
      return;
    }
    nFigures++;
} }
