// DisplayFrame.java

package lab06;

import java.awt.*;
import javax.swing.*;

/**
 * This class is the toplevel application window for Lab 06.
 * 
 * @author J.K. Daugherty
 */
public class DisplayFrame extends javax.swing.JFrame {

    private List list;
    private DisplayPanel display;
    
    public DisplayFrame() {
        list = new List();
        display = new DisplayPanel (list);
        
        initComponents();
        setSize (850, 500);
        setLocationRelativeTo (null);
        setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        setTitle("Lab06: List Tester");
        add (display, java.awt.BorderLayout.CENTER);
    }
    
    private void initComponents() {
        controlPanel = new javax.swing.JPanel();
        topControlPanel = new javax.swing.JPanel();
        bottomControlPanel = new javax.swing.JPanel();
        fldAddValue = new javax.swing.JTextField();
        fldAddIndex = new javax.swing.JTextField();
        btnAdd = new javax.swing.JButton();
        btnSet = new javax.swing.JButton();
        fldReplacedValue = new javax.swing.JTextField();
        btnAppend = new javax.swing.JButton();
        fldRemoveValue = new javax.swing.JTextField();
        fldRemoveIndex = new javax.swing.JTextField();
        btnRemove = new javax.swing.JButton();
        btnGet = new javax.swing.JButton();
        btnTrim = new javax.swing.JButton();
        btnClear = new javax.swing.JButton();
        btnReset = new javax.swing.JButton();
        btnExit = new javax.swing.JButton();
        statusPanel = new javax.swing.JPanel();
        lblItemCount = new javax.swing.JLabel();
        fldItemCount = new javax.swing.JTextField();
        fldItemCount.setText("" + list.size());
        lblCapacity = new javax.swing.JLabel();
        fldCapacity = new javax.swing.JTextField();
        fldCapacity.setText("" + list.getCapacity());
        lblNewCapacity = new javax.swing.JLabel();
        fldNewCapacity = new javax.swing.JTextField();
        btnApply = new javax.swing.JButton();

        topControlPanel.setBackground(Color.WHITE);
        bottomControlPanel.setBackground(Color.WHITE);

        topControlPanel.add (new JLabel("Value:"));

        fldAddValue.setColumns(5);
        fldAddValue.setToolTipText("Value to add");
        fldAddValue.setPreferredSize(new java.awt.Dimension(66, 28));
        fldAddValue.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fldAddValueActionPerformed(evt);
            }
        });
        topControlPanel.add(fldAddValue);

        btnAppend.setText("Add To Rear");
        btnAppend.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAppendActionPerformed(evt);
            }
        });
        topControlPanel.add(btnAppend);

        topControlPanel.add (new JLabel("Index:"));

        fldAddIndex.setColumns(3);
        fldAddIndex.setText("0");
        fldAddIndex.setHorizontalAlignment(JTextField.RIGHT);
        fldAddIndex.setToolTipText("Index of value to add/set");
        fldAddIndex.setPreferredSize(new java.awt.Dimension(66, 28));
        fldAddIndex.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fldAddIndexActionPerformed(evt);
            }
        });
        topControlPanel.add(fldAddIndex);

        btnAdd.setText("Add");
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });
        topControlPanel.add(btnAdd);

        btnSet.setText("Set");
        btnSet.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSetActionPerformed(evt);
            }
        });
        topControlPanel.add(btnSet);

        fldReplacedValue.setColumns(5);
        fldReplacedValue.setToolTipText("Value replaced by Set action");
        fldReplacedValue.setEditable(false);
        fldReplacedValue.setPreferredSize(new java.awt.Dimension(66, 28));
        topControlPanel.add(fldReplacedValue);
        
        topControlPanel.add (new JLabel("        "));
        topControlPanel.add (new JLabel("Index:"));

        fldRemoveIndex.setColumns(3);
        fldRemoveIndex.setText("0");
        fldRemoveIndex.setHorizontalAlignment(JTextField.RIGHT);
        fldRemoveIndex.setToolTipText("Index of value to remove/get");
        fldRemoveIndex.setEditable(true);
        fldRemoveIndex.setPreferredSize(new java.awt.Dimension(66, 28));
        topControlPanel.add(fldRemoveIndex);

        btnRemove.setText("Remove");
        btnRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRemoveActionPerformed(evt);
            }
        });
        topControlPanel.add(btnRemove);

        btnGet.setText("Get");
        btnGet.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGetActionPerformed(evt);
            }
        });
        topControlPanel.add(btnGet);

        fldRemoveValue.setColumns(5);
        fldRemoveValue.setEditable(false);
        fldRemoveValue.setPreferredSize(new java.awt.Dimension(66, 28));
        topControlPanel.add(fldRemoveValue);

        btnTrim.setText("Trim");
        btnTrim.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTrimActionPerformed(evt);
            }
        });
        bottomControlPanel.add(btnTrim);

        btnClear.setText("Clear");
        btnClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnClearActionPerformed(evt);
            }
        });
        bottomControlPanel.add(btnClear);

        btnReset.setText("Reset");
        btnReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnResetActionPerformed(evt);
            }
        });
        bottomControlPanel.add(btnReset);

        bottomControlPanel.setBackground(Color.WHITE);
        btnExit.setText("Exit");
        btnExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnExitActionPerformed(evt);
            }
        });
        bottomControlPanel.add(btnExit);
        
        controlPanel.setLayout (new GridLayout(2,1));
        controlPanel.add(topControlPanel);
        controlPanel.add(bottomControlPanel);
        add(controlPanel, java.awt.BorderLayout.SOUTH);

        statusPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 10, 5));

        statusPanel.setBackground(new java.awt.Color(255, 255, 255));
        lblItemCount.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblItemCount.setText("Current size:");
        statusPanel.add(lblItemCount);

        fldItemCount.setColumns(2);
        fldItemCount.setEditable(false);
        fldItemCount.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        fldItemCount.setPreferredSize(new java.awt.Dimension(33, 28));
        statusPanel.add(fldItemCount);

        lblCapacity.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblCapacity.setText("Current capacity:");
        statusPanel.add(lblCapacity);

        fldCapacity.setColumns(2);
        fldCapacity.setEditable(false);
        fldCapacity.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        fldCapacity.setPreferredSize(new java.awt.Dimension(33, 28));
        statusPanel.add(fldCapacity);

        lblNewCapacity.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lblNewCapacity.setText("New capacity:");
        statusPanel.add(lblNewCapacity);

        fldNewCapacity.setColumns(2);
        fldNewCapacity.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        fldNewCapacity.setPreferredSize(new java.awt.Dimension(33, 28));
        statusPanel.add(fldNewCapacity);

        btnApply.setText("Apply");
        btnApply.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnApplyActionPerformed(evt);
            }
        });
        statusPanel.add(btnApply);

        add(statusPanel, java.awt.BorderLayout.NORTH);
    }

    private void btnApplyActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            int newCapacity = Integer.parseInt (fldNewCapacity.getText());
            list.setCapacity (newCapacity);
            fldCapacity.setText("" + list.getCapacity());
	    display.repaint();
        }
        catch (NumberFormatException e) {
            JOptionPane.showMessageDialog (this,
                "Invalid integer syntax. Please retype\n" +
                    " the value for the new capacity.",
                "Invalid Integer",
                JOptionPane.ERROR_MESSAGE);
        }
        catch (IllegalStateException e) {
            JOptionPane.showMessageDialog (this,
                "The capacity cannot be less than\n" +
                "the current number of stored items.\n",
                "Insufficient Capacity",
                JOptionPane.ERROR_MESSAGE);
        }
    }

    private void fldAddValueActionPerformed(java.awt.event.ActionEvent evt) {
        appendItem();
    }

    private void fldAddIndexActionPerformed(java.awt.event.ActionEvent evt) {
        addItem();
    }

    private void btnTrimActionPerformed(java.awt.event.ActionEvent evt) {
        list.trim();
        fldCapacity.setText("" + list.getCapacity());
        display.repaint();
    }

    private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {
        list.clear();
        fldItemCount.setText("" + list.size());
        fldCapacity.setText("" + list.getCapacity());
        fldAddValue.setText("");
        fldAddIndex.setText("0");
        fldRemoveValue.setText("");
        fldRemoveIndex.setText("0");
        fldNewCapacity.setText("");
        display.repaint();
    }

    private void btnResetActionPerformed(java.awt.event.ActionEvent evt) {
        list.reset();
        fldItemCount.setText("" + list.size());
        fldCapacity.setText("" + list.getCapacity());
        fldAddValue.setText("");
        fldAddIndex.setText("0");
        fldRemoveValue.setText("");
        fldRemoveIndex.setText("0");
        fldNewCapacity.setText("");
        display.repaint();
    }

    private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {
        dispose();
        System.exit(0);
    }

    private void btnRemoveActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            int index = Integer.parseInt (fldRemoveIndex.getText());
            fldRemoveValue.setText ((String) list.remove(index));
            fldItemCount.setText("" + list.size());
            display.repaint();
        }
        catch (NumberFormatException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Invalid Integer Format",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");            
        }
        catch (IndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Remove Error",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");
        }
    }

    private void btnGetActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            int index = Integer.parseInt (fldRemoveIndex.getText());
            Object temp = list.get(index);
            fldRemoveValue.setText (temp.toString());
        }
        catch (NumberFormatException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Invalid Integer Format",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");            
        }
        catch (IndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Get Error",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");
        }
    }
    
    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {
        addItem();
    }
    
    private void btnAppendActionPerformed(java.awt.event.ActionEvent evt) {
        appendItem();
    }
    
    private void btnSetActionPerformed(java.awt.event.ActionEvent evt) {
        setItem();
    }
    
    private void setItem () {
        try {
            int index = Integer.parseInt (fldAddIndex.getText());
            String value = fldAddValue.getText();

            fldReplacedValue.setText (list.set(index, value).toString());

            fldAddValue.grabFocus();
            fldAddValue.setSelectionStart(0);
            fldAddValue.setSelectionEnd (fldAddValue.getText().length());
            display.repaint();
        }
        catch (NumberFormatException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Invalid Integer Format",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");            
        }
        catch (IndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Set Error",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");
        }
    }
    
    private void addItem () {
        try {
            int index = Integer.parseInt (fldAddIndex.getText());
            String value = fldAddValue.getText();

            list.add (index, value);

            fldAddValue.grabFocus();
            fldAddValue.setSelectionStart(0);
            fldAddValue.setSelectionEnd (fldAddValue.getText().length());
            fldItemCount.setText("" + list.size());
            fldCapacity.setText("" + list.getCapacity());
            display.repaint();
        }
        catch (NumberFormatException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Invalid Integer Format",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");            
        }
        catch (IndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Add Error",
                JOptionPane.ERROR_MESSAGE);
            fldRemoveValue.setText("");
        }
    }

    private void appendItem () {
        try {
            list.add (fldAddValue.getText());

            fldAddValue.grabFocus();
            fldAddValue.setSelectionStart(0);
            fldAddValue.setSelectionEnd (fldAddValue.getText().length());
            fldAddIndex.setText("" + list.size());
            fldItemCount.setText("" + list.size());
            fldCapacity.setText("" + list.getCapacity());
            display.repaint();
        }
        catch (IllegalStateException e) {
            JOptionPane.showMessageDialog (this,
                e.getMessage(), "Append Error",
                JOptionPane.ERROR_MESSAGE);
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DisplayFrame().setVisible(true);
            }
        });
    }
    
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnAppend;
    private javax.swing.JButton btnSet;
    private javax.swing.JButton btnApply;
    private javax.swing.JButton btnExit;
    private javax.swing.JButton btnRemove;
    private javax.swing.JButton btnGet;
    private javax.swing.JButton btnTrim;
    private javax.swing.JButton btnClear;
    private javax.swing.JButton btnReset;
    private javax.swing.JTextField fldAddValue;
    private javax.swing.JTextField fldAddIndex;
    private javax.swing.JTextField fldReplacedValue;
    private javax.swing.JTextField fldCapacity;
    private javax.swing.JTextField fldItemCount;
    private javax.swing.JTextField fldNewCapacity;
    private javax.swing.JTextField fldRemoveValue;
    private javax.swing.JTextField fldRemoveIndex;
    private javax.swing.JPanel controlPanel;
    private javax.swing.JPanel topControlPanel;
    private javax.swing.JPanel bottomControlPanel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JLabel lblCapacity;
    private javax.swing.JLabel lblItemCount;
    private javax.swing.JLabel lblNewCapacity;
}
