// DisplayFrame.java -- for Lab 09

package lab09;

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

import lab07.Queue;

/**
 *
 * @author J.K. Daugherty
 */
public class DisplayFrame extends JFrame {

    private BinaryTree bintree = new BinaryTree();
    private DisplayPanel display = new DisplayPanel (bintree);
    
    private JMenuBar menuBar;
    
    private JMenu filesMenu;
    private JMenuItem resetMenuItem;
    private JMenuItem exitMenuItem;
    
    private JMenu listMenu;
    private JMenuItem ascendingMenuItem;
    private JMenuItem descendingMenuItem;

    private JMenu viewMenu;
    private JMenuItem propertiesMenuItem;

    private JPanel controlPanel = new JPanel();
    private JPanel statusPanel = new JPanel();

    private JButton btnExit;
    private JButton btnInsert;
    private JButton btnReset;
    private JButton btnSearch;
    private JTextField fldInsert;
    private JTextField fldSize;
    private JTextField fldOccurrences;
    private JTextField fldSearch;
    private JLabel lblOccurrences;
    private JLabel lblFiller;
    private JLabel lblSize;

    public DisplayFrame() {
        initComponents();
        add (display, BorderLayout.CENTER);
    }
    
    public void setInitialFocus() {
        fldInsert.requestFocus();
    }

    private void initComponents() {
        setSize (750, 500);
        setLocationRelativeTo (null);
        setTitle ("Lab09: Binary Trees and Recursion");
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        menuBar = new JMenuBar();

        filesMenu = new JMenu();
        resetMenuItem = new JMenuItem();
        exitMenuItem = new JMenuItem();

        listMenu = new JMenu();
        ascendingMenuItem = new JMenuItem();
        descendingMenuItem = new JMenuItem();

        viewMenu = new JMenu();
        propertiesMenuItem = new JMenuItem();

        resetMenuItem.setText("Reset");
        resetMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                resetMenuItemActionPerformed(evt);
            }
        });

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });

        filesMenu.setText("Files");
        filesMenu.add(resetMenuItem);
        filesMenu.add(exitMenuItem);

        ascendingMenuItem.setText("Ascending");
        ascendingMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                ascendingMenuItemActionPerformed(evt);
            }
        });

        descendingMenuItem.setText("Descending");
        descendingMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                descendingMenuItemActionPerformed(evt);
            }
        });

        listMenu.setText("List");
        listMenu.add(ascendingMenuItem);
        listMenu.add(descendingMenuItem);

        propertiesMenuItem.setText("Properties");
        propertiesMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                propertiesMenuItemActionPerformed(evt);
            }
        });

        viewMenu.setText("View");
        viewMenu.add(propertiesMenuItem);

        menuBar.add(filesMenu);
        menuBar.add(listMenu);
        menuBar.add(viewMenu);

        setJMenuBar (menuBar);

        lblOccurrences = new JLabel();
        fldOccurrences = new JTextField();
        lblFiller = new JLabel();
        btnReset = new JButton();
        btnExit = new JButton();
        lblSize = new JLabel();
        fldSize = new JTextField();
        fldSize.setText("" + bintree.size());

        controlPanel.setBackground(Color.WHITE);

        fldInsert = new JTextField();
        fldInsert.setColumns(5);
        fldInsert.setToolTipText("Enter value to be inserted");
        fldInsert.setPreferredSize(new java.awt.Dimension(66, 28));
        fldInsert.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                fldInsertActionPerformed(evt);
            }
        });
        controlPanel.add(fldInsert);

        btnInsert = new JButton();
        btnInsert.setText("Insert");
        btnInsert.setToolTipText("Insert specified value into ordered binary tree");
        btnInsert.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                btnInsertActionPerformed(evt);
            }
        });
        controlPanel.add(btnInsert);

        fldSearch = new JTextField();
        fldSearch.setColumns(5);
        fldSearch.setToolTipText("Enter value to search for");
        fldSearch.setPreferredSize(new java.awt.Dimension(66, 28));
        fldSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                fldSearchActionPerformed(evt);
            }
        });
        controlPanel.add(fldSearch);

        btnSearch = new JButton();
        btnSearch.setText("Search");
        btnSearch.setToolTipText("Search for specified value");
        btnSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                btnSearchActionPerformed(evt);
            }
        });
        controlPanel.add(btnSearch);

        lblOccurrences.setBackground(Color.WHITE);
        lblOccurrences.setText("Occurrences:");
        controlPanel.add(lblOccurrences);

        fldOccurrences.setColumns(2);
        fldOccurrences.setEditable(false);
        fldOccurrences.setToolTipText("Occurrences of search value (0 if not found)");
        controlPanel.add(fldOccurrences);

        lblFiller.setPreferredSize(new java.awt.Dimension(30, 28));
        controlPanel.add (lblFiller);

        btnReset.setText("Reset");
        btnReset.setToolTipText("Remove all nodes");
        btnReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                btnResetActionPerformed(evt);
            }
        });
        controlPanel.add(btnReset);

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

        add(controlPanel, BorderLayout.SOUTH);

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

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

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

        add(statusPanel, BorderLayout.NORTH);
    }

    public BinaryTree getBinaryTree () {
        return bintree;
    }
    
    private void propertiesMenuItemActionPerformed(ActionEvent evt) {
        PropertiesDialog dlg = new PropertiesDialog (this, true);
        dlg.setVisible (true);
    }

    private void descendingMenuItemActionPerformed(ActionEvent evt) {
        Queue queue = bintree.listDescending();
        if (queue.isEmpty()) {
           JOptionPane.showMessageDialog (null, "Binary tree is empty", "Empty",
                    JOptionPane.ERROR_MESSAGE);
           return;
        }

        ListDialog dlg =
            new ListDialog (this, "Descending Order", true);
        String text = "";
        while (!queue.isEmpty()) {
            text += queue.remove().toString() + "\n";
        }
        dlg.setText (text);
        dlg.setVisible (true);
    }

    private void ascendingMenuItemActionPerformed(ActionEvent evt) {
        Queue queue = bintree.listAscending();
        if (queue.isEmpty()) {
            JOptionPane.showMessageDialog (null, "Binary tree is empty", "Empty",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }

        ListDialog dlg = new ListDialog (this, "Ascending Order", true);
        String text = "";
        while (!queue.isEmpty()) {
            text += queue.remove().toString() + "\n";
        }
        dlg.setText (text);
        dlg.setVisible (true);
    }

    private void exitMenuItemActionPerformed(ActionEvent evt) {
        dispose();
    }

    private void resetMenuItemActionPerformed(ActionEvent evt) {
        reset();
    }

    private void fldSearchActionPerformed(ActionEvent evt) {
        searchValue();
    }

    private void fldInsertActionPerformed(ActionEvent evt) {
        insertValue();
    }

    private void btnResetActionPerformed(ActionEvent evt) {
        bintree.removeAll();
        fldSize.setText("" + bintree.size());
        fldInsert.setText("");
        fldSearch.setText("");
        fldOccurrences.setText("");
        display.repaint();
    }

    private void btnExitActionPerformed(ActionEvent evt) {
        dispose();
    }

    private void btnSearchActionPerformed(ActionEvent evt) {
        searchValue();
    }

    private void btnInsertActionPerformed(ActionEvent evt) {
        insertValue();
    }
    
    private void insertValue () {
        bintree.insert (fldInsert.getText());
        fldInsert.grabFocus();
        fldInsert.setSelectionStart(0);
        fldInsert.setSelectionEnd (fldInsert.getText().length());
        fldSearch.setText("");
        fldOccurrences.setText("");
        fldSize.setText("" + bintree.size());
        display.repaint();
    }

    private void searchValue () {
        fldInsert.setText("");
        fldSearch.grabFocus();
        fldSearch.setSelectionStart(0);
        fldSearch.setSelectionEnd (fldSearch.getText().length());

        if (bintree.isEmpty()) {
            JOptionPane.showMessageDialog (this,
                    "Binary tree is empty", "Empty",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }

        String searchValue = fldSearch.getText();
        int occurrences = bintree.getOccurrences (searchValue);
        fldOccurrences.setText("" + occurrences);
    }

    private void reset () {
        bintree.removeAll();
        fldSize.setText("" + bintree.size());
        fldInsert.setText("");
        fldSearch.setText("");
        fldOccurrences.setText("");
        display.repaint();
    }
    
}
