import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;


/* This class manages a window with up to 7 int fields (numbered 0, ..., 6), 7
   double fields, and 7 string fields, and a "ready" button. The user is
   expected to type values in fields and then click the "ready" button. When
   this button is clicked, method buttonPressed is called to process the values
   in the fields and deliver some output, possibly in the fields in the window.

   Thus, the window is a general GUI, which can be used in a number of
   situations.

   To use this class, one needs to write a class X that

   (1) Extends this one.
   (2) Contains a method main with commands
         X d= new X(3,0,0);
         d.showWindow();
       (See the Constructor in this class for the meanings of the parameters.)
   (3) Contains a constructor
         public X(int i, int d, int s)
            {super(i, d, s);}
   (4) Contains a method
         Object buttonPressed() { ... }

   As mentioned previously, method buttonPressed is called when the "ready"
   button is pressed. In this method, place any code you like to read the
   values of the fields, calculate, and store values in the fields. To read the
   fields, use methods getIntField, getDoubleField, and getStringField. To
   store values in the fields, use methods setIntField, setDoubleField, and
   setStringField.

   */
   


public abstract class JLiveWindow {
// constants
// TOTAL_MAX_FIELDS: max number of fields of one type that is allowed
// MAX_FIELDS:       actual max number of fields used of one type.
private static final int TOTAL_MAX_FIELDS= 7;
private static int MAX_FIELDS;
private static final int MAX_FIELD_LENGTH= 20;
private static final int ROW_SEPARATION= 10;
private static final int COLUMN_SEPARATION= 15;

// fields
private TextField[] intFields;     // the fields that can contain ints
private TextField[] doubleFields;  // the fields that can contain doubles
private TextField[] stringFields;  // the fields that can contain text
private int numInts;               // number of int fields
private int numDoubles;            // number of double fields
private int numStrings;            // number of text fields

// These variables are used to provide the choicebox of locales
Locale locale= Locale.getDefault();
Locale[] locales= Calendar.getAvailableLocales();  // array of all locales
Choice choiceBox;

// My window
private Frame frame = new Frame("JLiveWindow");

// Constructor: a GUI window with
//     max( min(i,MAX_FIELDS), 0) int fields,
//     max( min(d,MAX_FIELDS), 0) double fields,
//     max( min(s,MAX_FIELDS), 0) String fields,
//     and a "ready" button
public JLiveWindow(int i, int d, int s) {
    numInts= Math.max( Math.min(i,TOTAL_MAX_FIELDS), 0);
    numDoubles= Math.max( Math.min(d,TOTAL_MAX_FIELDS), 0);
    numStrings= Math.max( Math.min(s,TOTAL_MAX_FIELDS), 0);
    MAX_FIELDS= Math.max( Math.max(numInts,numDoubles), numStrings );
        
    intFields= new TextField[MAX_FIELDS];
    doubleFields= new TextField[MAX_FIELDS];
    stringFields= new TextField[MAX_FIELDS];
        
    createFields();

    // Tell the program to exit upon closure of this window
	    frame.addWindowListener(new WindowAdapter() {
    	    public void windowClosing(WindowEvent e) {
        	    System.exit(0);}});

    // Add the Panel of fields and the button to this window
        choiceBox= createChoiceBox();
        frame.add("North", choiceBox);
    	frame.add("Center", createPanel());
      	frame.add("South", createActionButton());
}

// Create elements of arrays intFields, doubleFields, and stringFields
private void createFields() {
    for(int i= 0; i<MAX_FIELDS; i++) {
        intFields[i]= new TextField(MAX_FIELD_LENGTH);
        doubleFields[i]= new TextField(MAX_FIELD_LENGTH);
        stringFields[i]= new TextField(MAX_FIELD_LENGTH);
    }
}

// Create and return the panel of fields that goes in this window
private Panel createPanel() {
    Panel panel= new Panel();
    panel.setLayout(new GridLayout(1, 3, COLUMN_SEPARATION, 0));
    if (numInts > 0)
        panel.add(createFieldsPanel(numInts,    intFields,    "Integer fields"));
    if (numDoubles > 0)
        panel.add(createFieldsPanel(numDoubles, doubleFields, "Double fields"));
    if (numStrings > 0)
        panel.add(createFieldsPanel(numStrings, stringFields, "String fields"));
    return panel;
}

// Create and return a Panel with visible elements a[0..n-1], invisible
// elements a[n..MAX_FIELDS] (to make the vertical sizes nice), and with
// title t above them.
// Pre: n>0
private Panel createFieldsPanel(int n, TextField[] a, String t) {
    Panel panel= new Panel();
    panel.setLayout(new GridLayout(MAX_FIELDS+1, 1, 0, ROW_SEPARATION));
    if (n>0)
        panel.add(new Label(t, Label.CENTER));
    for(int i= 0; i<n; i++) {
        panel.add(a[i]);
    }
    // Add the invisible elements.
    	for(int i= n+1; i<MAX_FIELDS; i++) {
        	panel.add(a[i]);
        	a[i].setVisible(false);
    	}
    return panel;
}

// Create and return a button with title "Ready"
private Button createActionButton() {
    Button button= new Button("Ready!");
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            buttonPressed();
        }});
    return button;
}

// Create and return the choiceBox to contain locales
private Choice createChoiceBox() {
  Choice cb= new Choice();
  int i;
  // Add the locales to cb
     for (i= 0; i != locales.length; i++) {
         cb.addItem(locales[i].getDisplayName());
     }
  // Set the selected item to the default
     for (i= 0; i != locales.length; i++) {
         if (locale.equals(locales[i]))
         	cb.select(i);
     }

  return cb;
}

// Pack and show this window
public void showWindow() {
    frame.pack();
    frame.setVisible(true);
}

// Process click of button titled "Ready!"
abstract Object buttonPressed();

// Return the integer in int field number f, or 0 if either f is not
// valid or the field doesn't contain an integer.
public int getIntField(int f) {
    try {
        return Integer.parseInt( intFields[f].getText() );
    } catch (ArrayIndexOutOfBoundsException e) {
        return 0;
    } catch (NumberFormatException e) {
        intFields[f].setText("" + intFields[f].getText() +": NOT AN INTEGER, 0 used");
        return 0;
    }
}

// Set int field number f to m.  No effect if f is not valid.
public void setIntField(int f, int m) {
    try {
        intFields[f].setText("" + m);
    } catch (ArrayIndexOutOfBoundsException e) {
        return;
    }
}

// Return the double in double field number f, or 0 if either f is not
// valid or the field doesn't contain a double.
public double getDoubleField(int f) {
    try {
        return Double.valueOf( doubleFields[f].getText() ).doubleValue();
    } catch (ArrayIndexOutOfBoundsException e) {        
        return 0;
    } catch (NumberFormatException e) {     
        doubleFields[f].setText("" + doubleFields[f].getText() +": NOT A DOUBLE, 0 used");
        return 0;
    }
}

// Set double field number f to d.  No effect if f is not valid.
public void setDoubleField(int f, double d) {
    try {
        doubleFields[f].setText("" + d);
    } catch (ArrayIndexOutOfBoundsException e) {
        return;
    }
}

// Return the string in string field number f, or "" if f is not valid.
public String getStringField(int f) {
    try {
        return stringFields[f].getText();
    } catch (ArrayIndexOutOfBoundsException e) {
        return "";
    }
}

// = the locale that was selected from the choice box (the default, if none)
public Locale getLocale() {
   return locales[choiceBox.getSelectedIndex()];
}

// Set string field number f to s.  No effect if f is not valid.
public void setStringField(int f, String s) {
    try {
        stringFields[f].setText("" + s);
    } catch (ArrayIndexOutOfBoundsException e) {
        return;
    }
}



}
