/* 
 * InputPanel.java
 *
 * by Kwan Hoi Ching Eddie
 * 
 * last revised: 06/06/1996
 *
 */

/* 
   Warning: this panel is not perfectly implemented.  To enhance
   the robustness of the applet, do more effort in parsing 
   function.
*/

import java.awt.*;
import java.applet.*;
import java.lang.*;
import java.util.*;

/* create a window frame for input. */
class InputFrame extends Frame {

  TextField text_area;
  Label valid_area;
  Label input_label;
  Button okButton, clearButton, dismissButton;

  InputPanel parent;
  DisplayPanel display;
  String title_str;
  int type;

  final int width = 450;
  final int height = 150;

  /* parse the declaration statement. */
  public ArrayInfo decParse(String str) {

    ArrayInfo info = new ArrayInfo();
    String token;

    try {

      StringTokenizer st = new StringTokenizer(str, " []");

      token = st.nextToken();
      if (token.equals("int"))
        info.type = ArrayVisual.INT;
      else if (token.equals("char"))
        info.type = ArrayVisual.CHAR;
      else if (token.equals("float"))
        info.type = ArrayVisual.FLOAT;
      else if (token.equals("double"))
        info.type = ArrayVisual.DOUBLE;
      else
        return null;
      
      info.name = st.nextToken();

      info.size1 = Integer.parseInt(st.nextToken());

      if (info.size1 > 10) return null;

      token = st.nextToken();
      if (token.equals(";")) {
        info.dim = 1;
        return info;
      } else {
        info.size2 = Integer.parseInt(token);
        if (info.size2 > 10) return null;
        info.dim = 2;
        if (!st.nextToken().equals(";")) return null;
        return info;
      }
    }
    catch (NoSuchElementException e) { return null; }
    catch (NumberFormatException e) { return null; }

  }

  /* parse the assignment statement. */
  public ElementInfo assParse(String str) {

    ElementInfo info = new ElementInfo();
    String token;

    try {

      StringTokenizer st = new StringTokenizer(str, " [];");

      info.name = st.nextToken();

      info.row1 = Integer.parseInt(st.nextToken());

      token = st.nextToken();
      if (token.equals("=")) {
        info.dim = 1;
      } else {
        info.column1 = info.row1;
        info.row1 = Integer.parseInt(token);
        info.dim = 2;
        if (!st.nextToken().equals("=")) return null;
      }

      token = st.nextToken();
      if (token.equals(info.name)) {
        if (info.dim == 1) {
          info.row2 = Integer.parseInt(st.nextToken());
        } else {
          info.column2 = Integer.parseInt(st.nextToken());
          info.row2 = Integer.parseInt(st.nextToken());
        }
        info.value = "";
      } else {
        if (!st.hasMoreTokens())
          info.value = token;
        else
          return null;
      }

      if (info.dim != display.getDim() ||
          info.row1 >= display.getSize(1) ||
          info.row2 >= display.getSize(1) ||
          info.column1 >= display.getSize(2) ||
          info.column2 >= display.getSize(2) ||
          !info.name.equals(display.getName()))
        return null;
      return info;
    }
    catch (NoSuchElementException e) { return null; }
    catch (NumberFormatException e) { return null; }
  }
 
  // constructor for InputFrame.
  public InputFrame(InputPanel p, String t, int type, DisplayPanel d) {
 
    super(t);

    parent = p;
    title_str = t;
    this.type = type;
    display = d;

    input_label = new Label(title_str+":");
    text_area = new TextField(25);
    valid_area = new Label("                             ");
    okButton = new Button("Okay");
    clearButton = new Button("clear");
    dismissButton = new Button("Dismiss");

    setLayout(new GridLayout(2, 1));

    Panel p1 = new Panel();
    p1.setLayout(new FlowLayout(FlowLayout.LEFT));
    p1.add(input_label);
    p1.add(text_area);

    Panel p2 = new Panel();
    p2.setLayout(new FlowLayout(FlowLayout.LEFT));
    p2.add(okButton);
    p2.add(clearButton);
    p2.add(dismissButton);
    p2.add(valid_area);

    add(p1);
    add(p2);

    this.pack();
    resize(width, height);
    this.show();
  }

  // capture the action on the InputFrame. 
  public boolean action(Event e, Object arg) {

    ArrayInfo ai;
    ElementInfo ei;
 
    if (e.target == okButton) {

      switch(type) {
        case InputPanel.DECLARATION:
          ai = decParse(text_area.getText()) ;
          if (ai != null) {
            valid_area.setText("");
            display.NameChange(ai.name);
            display.DimensionChange(ai.dim);
            if (ai.dim == 1) {
              display.SizeChange(1, ai.size1);
            } else if (ai.dim == 2) {
              display.SizeChange(1, ai.size2);
              display.SizeChange(2, ai.size1);
            }
            display.TypeChange(ai.type); 
          } else {
            valid_area.setText("Error in "+title_str);
          }
          break;    

        case InputPanel.ASSIGNMENT:
          ei = assParse(text_area.getText()) ;
          if (ei != null) {
            valid_area.setText("");
            display.Assignment(ei);
    
          } else {
            valid_area.setText("Error in "+title_str);
          }
          break;

        default:
          break;
      }
      return true;

    } else if (e.target == clearButton) {
      text_area.setText("");
      
    } else if (e.target == dismissButton) {
      parent.enable();
      this.hide();
      this.dispose();

      return true;
    }
    
    return false;
  }

}

/* input panel at the bottom of the display. */
public class InputPanel extends Panel {

  DisplayPanel display;
  Button d_button, a_button;
  String d_str = "Declaration";
  String a_str = "Assignment";

  public final static int DECLARATION = 0;
  public final static int ASSIGNMENT = 1;

  public InputPanel(DisplayPanel d) {

    d_button = new Button(d_str);
    a_button = new Button(a_str);
    
    display = d;

    setLayout(new FlowLayout(FlowLayout.LEFT));
    add(d_button);
    add(a_button);
  }

  public boolean action(Event e, Object arg) {
 
    // if user's choice is "declaration".
    if (e.target == d_button) {

      this.disable();
      new InputFrame(this, "Declaration", DECLARATION, display);
      return true;

    // if user's choice is "assignment".
    } else if (e.target == a_button) {

      this.disable();
      new InputFrame(this, "Assignment", ASSIGNMENT, display);
      return true;
    }
   
    return false;
  }

}

