// DisplayFrame.java

package lab04;

import javax.swing.JOptionPane;

/**
 * This class is the toplevel application window for Lab04.

 * @author J.K. Daugherty
 */
public class DisplayFrame extends javax.swing.JFrame {
    private Stack stack;
    private DisplayPanel displayPanel;
    
    public DisplayFrame() {
        stack = new Stack();
        displayPanel = new DisplayPanel (stack);

        setSize (550, 600);
        setLocationRelativeTo (null);
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Lab04: Stack Tester");

        initComponents();
        add (displayPanel, java.awt.BorderLayout.CENTER);
    }
    
    private void initComponents() {
        controlPanel = new javax.swing.JPanel();
        fldPush = new javax.swing.JTextField();
        btnPush = new javax.swing.JButton();
        fldPop = new javax.swing.JTextField();
        btnPop = new javax.swing.JButton();
        btnTrim = new javax.swing.JButton();
        btnClear = new javax.swing.JButton();
        btnReset = new javax.swing.JButton();
        btnExit = new javax.swing.JButton();
        titlePanel = new javax.swing.JPanel();
        lblItemCount = new javax.swing.JLabel();
        fldItemCount = new javax.swing.JTextField();
        lblCurCapacity = new javax.swing.JLabel();
        fldCurCapacity = new javax.swing.JTextField();
        fldCurCapacity.setText("" + stack.getCapacity());
        lblSetNewCapacity = new javax.swing.JLabel();
        fldNewCapacity = new javax.swing.JTextField();
        fldNewCapacity.setText("");
        btnApply = new javax.swing.JButton();

        controlPanel.setBackground(new java.awt.Color(255, 255, 255));
        fldPush.setColumns(5);
        fldPush.setToolTipText(
                "Enter a String value to push onto the stack");
        fldPush.setPreferredSize(new java.awt.Dimension(66, 28));
        fldPush.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fldPushActionPerformed(evt);
            }
        });

        controlPanel.add(fldPush);

        btnPush.setText("Push");
        btnPush.setToolTipText("Push the String onto the stack");
        btnPush.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPushActionPerformed(evt);
            }
        });

        controlPanel.add(btnPush);

        fldPop.setColumns(5);
        fldPop.setEditable(false);
        fldPop.setToolTipText("Value most recently popped from the stack");
        fldPop.setPreferredSize(new java.awt.Dimension(66, 28));
        controlPanel.add(fldPop);

        btnPop.setText("Pop");
        btnPop.setToolTipText("Pop the topmost value from the stack");
        btnPop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPopActionPerformed(evt);
            }
        });

        controlPanel.add(btnPop);

        btnTrim.setText("Trim");
        btnTrim.setToolTipText("Adjusts capacity to match current size");
        btnTrim.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTrimActionPerformed(evt);
            }
        });

        controlPanel.add(btnTrim);

        btnClear.setText("Clear");
        btnClear.setToolTipText("Removes all values from the stack");
        btnClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnClearActionPerformed(evt);
            }
        });

        controlPanel.add(btnClear);

        btnReset.setText("Reset");
        btnReset.setToolTipText("Clears and resets to the initial capacity");
        btnReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnResetActionPerformed(evt);
            }
        });

        controlPanel.add(btnReset);

        btnExit.setText("Exit");
        btnExit.setToolTipText("Exits this application");
        btnExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnExitActionPerformed(evt);
            }
        });

        controlPanel.add(btnExit);

        add(controlPanel, java.awt.BorderLayout.SOUTH);

        titlePanel.setBackground(new java.awt.Color(255, 255, 255));
        lblItemCount.setText("Item count:");
        titlePanel.add(lblItemCount);

        fldItemCount.setColumns(2);
        fldItemCount.setEditable(false);
        fldItemCount.setFont(
                new java.awt.Font("Microsoft Sans Serif", 1, 13));
        fldItemCount.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        fldItemCount.setText("0");
        fldItemCount.setPreferredSize(new java.awt.Dimension(35, 20));
        titlePanel.add(fldItemCount);

        lblCurCapacity.setText("  Current capacity:");
        titlePanel.add(lblCurCapacity);

        fldCurCapacity.setColumns(2);
        fldCurCapacity.setEditable(false);
        fldCurCapacity.setFont(
                new java.awt.Font("Microsoft Sans Serif", 1, 13));
        fldCurCapacity.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        titlePanel.add(fldCurCapacity);

        lblSetNewCapacity.setText("    New capacity:");
        titlePanel.add(lblSetNewCapacity);

        fldNewCapacity.setColumns(2);
        fldNewCapacity.setFont(
                new java.awt.Font("Microsoft Sans Serif", 1, 13));
        fldNewCapacity.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        titlePanel.add(fldNewCapacity);

        btnApply.setText("Apply");
        btnApply.setToolTipText("Set capacity to specified new value");
        btnApply.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnApplyActionPerformed(evt);
            }
        });

        titlePanel.add(btnApply);

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

    private void fldPushActionPerformed(java.awt.event.ActionEvent evt) {
        pushValue();
    }

    private void btnResetActionPerformed(java.awt.event.ActionEvent evt) {
        stack.reset();
        fldItemCount.setText ("" + stack.getItemCount());
        fldCurCapacity.setText ("" + stack.getCapacity());
        fldPush.setText ("");
        fldPop.setText ("");
        displayPanel.repaint();

    }

    private void btnApplyActionPerformed(java.awt.event.ActionEvent evt) {
        int newCapacity = stack.getCapacity();

        // Attempt to parse new value, make sure it is a valid integer...
        try {
            newCapacity = Integer.parseInt (fldNewCapacity.getText());
        }
        catch (NumberFormatException e) {
            String message = 
                "Invalid integer syntax. Please retype\n"
                + " the value for the new stack capacity.\n";
            JOptionPane.showMessageDialog (this, message);
            return;
        }

        // The new capacity must be enough to hold all currently stored values

        if (newCapacity < stack.getItemCount()) {
            String message = 
                "The stack capacity cannot be less than\n" +
                "the current number of stored items.\n";
            JOptionPane.showMessageDialog (this, message);
            return;
        }
        
        // Even if the stack is empty, this app will always require
        // that the capacity is strictly positive (i.e., at least 1)

        if (newCapacity < 1) {
            String message = 
                "The stack capacity must be 1 or greater.\n";
            JOptionPane.showMessageDialog (this, message);
            return;
        }
        
        stack.setCapacity (newCapacity);
        displayPanel.repaint();
        fldCurCapacity.setText ("" + stack.getCapacity());
        fldNewCapacity.setText ("");
    }//GEN-LAST:event_btnApplyActionPerformed

    private void btnTrimActionPerformed(java.awt.event.ActionEvent evt) {
	stack.trim();
        displayPanel.repaint();
        fldCurCapacity.setText ("" + stack.getCapacity());

    }

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

    private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {
        stack.clear();
        fldItemCount.setText ("" + stack.getItemCount());
        fldPop.setText ("");
        displayPanel.repaint();
    }

    private void btnPopActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            String temp = (String) stack.pop();
            fldPop.setText (temp);
            fldItemCount.setText ("" + stack.getItemCount());
            displayPanel.repaint();
        }
        catch (IllegalStateException e) {
            fldPop.setText ("");
            String message = 
                "The stack is empty, cannot pop a value.\n";
            JOptionPane.showMessageDialog (this, message);
        }
    }

    private void btnPushActionPerformed(java.awt.event.ActionEvent evt) {
        pushValue();
    }
    
    private void pushValue() {
        stack.push (fldPush.getText());
        displayPanel.repaint();
        fldPush.setText("");
        fldItemCount.setText ("" + stack.getItemCount());        
        fldCurCapacity.setText ("" + stack.getCapacity());
    }

    // Note: this main() is not used in current version of Lab04
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new DisplayFrame().setVisible(true);
            }
        });
    }
    
    private javax.swing.JButton btnApply;
    private javax.swing.JButton btnClear;
    private javax.swing.JButton btnExit;
    private javax.swing.JButton btnPop;
    private javax.swing.JButton btnPush;
    private javax.swing.JButton btnReset;
    private javax.swing.JButton btnTrim;
    private javax.swing.JPanel controlPanel;
    private javax.swing.JTextField fldCurCapacity;
    private javax.swing.JTextField fldItemCount;
    private javax.swing.JTextField fldNewCapacity;
    private javax.swing.JTextField fldPop;
    private javax.swing.JTextField fldPush;
    private javax.swing.JLabel lblCurCapacity;
    private javax.swing.JLabel lblItemCount;
    private javax.swing.JLabel lblSetNewCapacity;
    private javax.swing.JPanel titlePanel;
}
