/**
 *  File: GUI.java
 *
 *  Contains the GUI implementation to drive AddEmUp.
 *
 *  Author: Bary W Pollack
 *  Date:   Jan. 7, 2007
**/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 *	The GUI class creats and maintains the GUI
**/
public class GUI extends JFrame {

	private Data data;						// for access to the data object

	private JPanel jpOuterPanel;			// for outermost frame
	private JPanel jpInstructsPanel;		// for the instructions
	private JPanel currentDataPanel;		// for the current data header

	private JLabel jlCurrentDataTitle;		// for the current data header
	private JLabel jlCurrentDataContents;	// for the data contents

	private JTextField jtfValue;			// for value to be inserted

	/**
	 * 	Create the actual visible GUI
	**/
    GUI(Data data) {
        super("*** AddEmUp ***");
        this.data = data;	// save access to the data object

		// Set up the outer panel, into which all else will be put
        JPanel jp;
        jpOuterPanel = new JPanel();
        jpOuterPanel.setLayout(new BoxLayout(jpOuterPanel, BoxLayout.Y_AXIS));

		// Set up the title line
        jpInstructsPanel = new JPanel();
        jpInstructsPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
        JLabel jLabel = new JLabel("Enter data values (reals)...");
        jpInstructsPanel.add(jLabel);
        jpOuterPanel.add(jpInstructsPanel);

		// Set up the "Current data" line
        jp = new JPanel();
        jp.setLayout(new FlowLayout(FlowLayout.LEFT));
        jlCurrentDataTitle = new JLabel();
        jp.add(jlCurrentDataTitle);
        jpOuterPanel.add(jp);

		// Set up the data contents display line
		jp = new JPanel();
        jp.setLayout(new FlowLayout(FlowLayout.CENTER));
        jlCurrentDataContents = new JLabel();
        jp.add(jlCurrentDataContents);
        jpOuterPanel.add(jp);

		// Set up the text field for data acquisition
		jp = new JPanel();
		jp.add(new JLabel("  Value to insert:"));
		jp.setLayout(new FlowLayout(FlowLayout.CENTER));
		jtfValue = new JTextField(6);
		jtfValue.addActionListener(new EnterKeyHandler());
		jp.add(jtfValue);
		jpOuterPanel.add(jp);

		// Set up the Quit button
		jp = new JPanel();
		jp.setLayout(new FlowLayout(FlowLayout.CENTER));
		JButton jbQuit = new JButton("  Quit  ");
		jbQuit.addActionListener(new QuitButtonHandler());
		jp.add(jbQuit);
        jpOuterPanel.add(jp);

		// Initialize/update all components
        updateFields();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(200, 200, 350, 180);   // set frame location and size

		// Set up the outer panel; turn it on
        setContentPane(jpOuterPanel);
        setResizable(false);
        setVisible(true);
    } // end GUI constructor


	/**
	 *  The updateFields method updates the various dynamic display fields in the GUI
	**/
    private void updateFields() {
	    // Handle the "Current data" line
	    data.calculate();
        String sTitle = String.format("  Current data (%d items)          Average = %.3f",
        								data.getCount(), data.getAverage());
		jlCurrentDataTitle.setText(sTitle);

		// Handle the data display
		int nCount = data.getCount();
		String sContents = (nCount <= 0) ? "<empty>" : "";
		String sValue;
		for (int i = 0; i < nCount; i++) {
			sValue = String.format(" %.1f ", data.getValue(i));
			sContents += sValue;
		}
		jlCurrentDataContents.setText(sContents);

		// Handle the input TextField
		jtfValue.setText("");
		jtfValue.requestFocus();
    } // end updateFields()


	/**
	 *  Handle the Enter (Return) key
	**/
    class EnterKeyHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
	        boolean bGoodData = true;
			String sValue = jtfValue.getText().trim();
			// Only enter data for non-blank inputs
			if (sValue.length() > 0) {
				if (data.getCount() >= data.MAX_NUMBER) {
					// Array capacity has been exceeded; complain...
					java.awt.Toolkit.getDefaultToolkit().beep();
					JOptionPane.showMessageDialog(null, 
								"Maximum number of values is " + data.MAX_NUMBER, 
								"Array capacity exceeded", 
								JOptionPane.ERROR_MESSAGE);
					bGoodData = false;
				} else {
					try {
						// Attempt to enter value into array
						data.insert(Double.parseDouble(sValue));
					} catch (NumberFormatException nfe) {
						// Lousy numeric value; complain...
						java.awt.Toolkit.getDefaultToolkit().beep();
						JOptionPane.showMessageDialog(null, 
									"Improper value: " + sValue, 
									"Bad Input", 
									JOptionPane.ERROR_MESSAGE);
						bGoodData = false;
					}
				}
				// Only sort and update if data truly was entered
				if (bGoodData) {
					data.sort();
					updateFields();
				}
			} // end if > 0
        }
    } // end EnterKeyHandler class


	/**
	 *  Handle the Quit button
	**/
    class QuitButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
	        dispose();
            System.exit(0);
        }
    } // end QuitButtonHandler class

} // end GUI class
