// Written by Dr. Deborah Hwang for CS 350
// Pizza Parlor Order Form Java application, version 2
// Combo boxes, lists, dialogs, file output

import javax.swing.*;
import javax.swing.event.*;  // ListSelectionListener
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class PizzaApp2 extends JPanel // application is a JPanel
{  
   // The components that are named for entire application
   JFrame frame;   // outer frame
   JTextField nameField;
   JTextArea addressField;
   JTextArea debugArea;
   JComboBox sizeList;
   JList toppingsList;

   final String[] toppings = {"Italian Sausage", "Hamburger", "Pepperoni",
			      "Onions", "Green Peppers", "Mushrooms"};

   public PizzaApp2 (JFrame frame) // constructor
   {
      // initialize layout manager using superclass constructor
      // super class construction must always be first
      super (new BorderLayout());

      this.frame = frame;

      // Create the components

      // Create title panel with HTML decorated label
      JPanel titlePanel = new JPanel();
      titlePanel.add (new JLabel ("<html><font size=+2 color=\"purple\">" +
                                  "Purple Pizza Parlor</font></html>", 
                                  JLabel.CENTER));
      // Pad the title on top and bottom
      titlePanel.setBorder(BorderFactory.createEmptyBorder(10,0,10,0));

      // Create other panels
      JPanel namePanel = createNamePanel();
      JPanel addressPanel = createAddressPanel();
      JPanel sizePanel = createSizePanel();
      JPanel toppingsPanel = createToppingsPanel();
      JPanel buttonPanel = createButtonPanel();

      // Create center panel in a horizontal column
      JPanel centerPanel = new JPanel();
      centerPanel.setLayout (new BoxLayout (centerPanel, BoxLayout.PAGE_AXIS));
      centerPanel.add (namePanel);
      centerPanel.add (addressPanel);
      centerPanel.add (sizePanel);
      centerPanel.add (toppingsPanel);
      centerPanel.add (buttonPanel);


      // Create the debug area at bottom with vertical scrollbar
      debugArea = new JTextArea ("The status of your order is:\n", 10, 40);
      JScrollPane debugScrollPane = new JScrollPane (
         debugArea, 
         JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
         JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
      debugArea.setEditable (false);

      // Lay out the main panel
      add (titlePanel, BorderLayout.PAGE_START);
      add (centerPanel, BorderLayout.CENTER);
      add (debugScrollPane, BorderLayout.PAGE_END);
   }  // end constructor

   private JPanel createNamePanel ()
   {
      JPanel panel = new JPanel ();
      nameField = new JTextField(20);

      panel.add (new JLabel ("Name: "));
      panel.add (nameField);
      return panel;
   }  // end createNamePanel

   private JPanel createAddressPanel ()
   {
      JPanel panel = new JPanel ();
      addressField = new JTextArea(3, 20);

      panel.add (new JLabel ("Address: "));
      panel.add (addressField);
      return panel;
   }  // end createAddressPanel

   private JPanel createSizePanel ()
   {
      final String[] sizes = {"Small", "Medium", "Large", "Extra Large"};

      JPanel panel = new JPanel();
      sizeList = new JComboBox(sizes);

      // Make Large the default choice
      sizeList.setSelectedIndex (2);

      // Add listener
      sizeList.addActionListener(
         new ActionListener()  // anonymous inner class
         {
             public void actionPerformed (ActionEvent e)  // handler
             {
                JComboBox cb = (JComboBox) e.getSource();
		String size = (String) cb.getSelectedItem();
                debugArea.append (size + " has been chosen.\n");
                debugArea.setCaretPosition(
                   debugArea.getDocument().getLength());
             }  // end actionPerformed
         });  // end ActionListener

      panel.add (new JLabel ("Choose one: "));
      panel.add (sizeList);
      return panel;
   }  // end createSizePanel

   
   private JPanel createToppingsPanel()
   {
      JPanel panel = new JPanel ();

      toppingsList = new JList (toppings);

      // Add listener
      toppingsList.addListSelectionListener(
         new ListSelectionListener ()  // anonymous inner class
         {
               public void valueChanged (ListSelectionEvent e)  // handler
               {
		  if (!e.getValueIsAdjusting())  // user is done selecting
                  {
		     String text = null;
		     int[] indices = toppingsList.getSelectedIndices();
		     for (int i = 0; i < indices.length; i++)
		     {
			if (text == null)
			   text = toppings[indices[i]];
			else
			   text = text + ", " + toppings[indices[i]];
		     }  // end for
		     if (text == null)
			text = "No toppings are selected\n";
		     else
			text = text + " are selected\n";
		     debugArea.append (text);
		     debugArea.setCaretPosition(
			debugArea.getDocument().getLength());
		  }  // end if
               }  // end valueChanged
         }); // end ListSelectionListener

      panel.add (new JLabel ("Choose from: "));
      panel.add (toppingsList);
      return panel;
   }  // end createSizePanel

   private JPanel createButtonPanel()
   {
      JPanel panel = new JPanel();  // default layout is FlowLayout
      JButton submit = new JButton ("Submit");
      JButton reset = new JButton ("Reset");
      JButton quit = new JButton ("Quit");

      // Create an action listener
      ButtonListener buttonListener = new ButtonListener ();

      // Set action command and add listener to each button
      submit.setActionCommand("Submit");
      submit.setMnemonic(KeyEvent.VK_S);
      submit.addActionListener (buttonListener);

      reset.setActionCommand("Reset");
      reset.setMnemonic(KeyEvent.VK_R);
      reset.addActionListener (buttonListener);

      quit.setActionCommand("Quit");
      quit.setMnemonic(KeyEvent.VK_Q);
      quit.addActionListener (buttonListener);

      // Set default button (when Enter is pressed)
      frame.getRootPane().setDefaultButton(submit);
      
      // Lay out panel
      panel.add (submit);
      panel.add (reset);
      panel.add (quit);

      return panel;
   }  // end createButtonPanel


   public JMenuBar createMenuBar() 
   {
      JMenuBar menuBar;
      JMenu menu, submenu;
      JMenuItem menuItem;

      // Create an action listener
      ButtonListener buttonListener = new ButtonListener ();

      // Create the menu bar.
      menuBar = new JMenuBar();

      // Build the first menu.  Add it to menu bar.
      menu = new JMenu("Actions");
      menu.setMnemonic(KeyEvent.VK_A);
      menuBar.add(menu);

      // A group of JMenuItems, add them to menu
      menuItem = new JMenuItem("Submit");
      menuItem.setActionCommand("Submit");
      menuItem.addActionListener (buttonListener);
      menu.add(menuItem);

      menuItem = new JMenuItem("Reset");
      menuItem.setActionCommand("Reset");
      menuItem.addActionListener (buttonListener);
      menu.add(menuItem);

      menuItem = new JMenuItem("Quit");
      menuItem.setActionCommand("Quit");
      menuItem.addActionListener (buttonListener);
      menu.add(menuItem);

      // Build a submenu, add it to menu
      menu.addSeparator();
      submenu = new JMenu("A submenu");
      menuItem = new JMenuItem("An item in the submenu");
      submenu.add (menuItem);
      menuItem = new JMenuItem("Another item in the submenu");
      submenu.add (menuItem);
      menu.add(submenu);

      // Build second menu in the menu bar.
      menu = new JMenu("About");
      menu.setMnemonic(KeyEvent.VK_B);
      menuBar.add(menu);

      return menuBar;
   }  // createMenuBar

   // Named inner class so buttons and menu can share same listener
   class ButtonListener implements ActionListener
   {
	 public void actionPerformed (ActionEvent e) // handler
	 {
	    String command = e.getActionCommand();
	    if (command == "Submit")
	    {
	       // error check
	       if (nameField.getText().equals(""))
	       {
		  JOptionPane.showMessageDialog(
		     frame,
		     "Name field must be filled in.",
		     "Name field missing",
		     JOptionPane.ERROR_MESSAGE);
		  return;
	       }  // if name missing
	       if (addressField.getText().equals(""))
	       {
		  JOptionPane.showMessageDialog(
		     frame,
		     "Address field must be filled in.",
		     "Address field missing",
		     JOptionPane.ERROR_MESSAGE);
		  return;
	       }  // if address missing
	       
	       // open and write to file
	       PrintWriter outputStream = null;
	       try 
	       {
		  outputStream = 
		     new PrintWriter(
			new FileWriter(
			   "output/orders.txt", true));  // for append
		  outputStream.println("Name: " + nameField.getText());
		  outputStream.println("Address:\n" + 
				       addressField.getText());
		  outputStream.println("Size: " + 
				       sizeList.getSelectedItem());
		  outputStream.print("Toppings: ");
		  int [] indices = toppingsList.getSelectedIndices();
		  for (int i = 0; i < indices.length-1; i++)
		     outputStream.print (toppings[indices[i]] + ", ");
		  if (indices.length > 0)
		     outputStream.println (
			toppings[indices[indices.length-1]]);
		  else
		     outputStream.println ("none");
		  outputStream.println ("-----------------------------");
		  outputStream.flush();
	       }
	       catch (IOException ex)
	       {
		  debugArea.append("Error opening output file\n");
		  debugArea.setCaretPosition(
		     debugArea.getDocument().getLength());
		  return;
	       }
	       finally 
	       {
		  if (outputStream != null)
		     outputStream.close();
	       }
	       
	       debugArea.append ("Your order has been submitted\n");
	       debugArea.setCaretPosition(
		  debugArea.getDocument().getLength());
	    }  // end Submit
	    else if (command == "Reset")
	    {
	       nameField.setText ("");
	       addressField.setText ("");
	       sizeList.setSelectedIndex(2);
	       toppingsList.clearSelection();
	       debugArea.setText ("The status of your order is:\n");
	    }  // end Reset
	    else if (command == "Quit")
	    {
	       System.exit(0);
	    }  // end Quit
	    else
	       System.out.println ("Unknown command");
	 }  // end actionPerformed
   }  // end ButtonListener

    // Every Swing application will have these two functions

    // Create the GUI and show it.  For thread safety, this method should 
    // be invoked from the event-dispatching thread.
    private static void createAndShowGUI() 
    {
        // Make sure we have nice window decorations.
        JFrame.setDefaultLookAndFeelDecorated(true);
       
        // Create and set up the main window.
        JFrame frame = new JFrame("Purple Pizza Parlor Order Form");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        // Set up the main frame panel, 
        // only the application itself is created and added
	PizzaApp2 app = new PizzaApp2 (frame);
        frame.setLayout(new GridLayout(1,1));
        frame.add(app);
	frame.setJMenuBar(app.createMenuBar());

        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }  // createAndShowGUI

    public static void main(String[] args) 
    {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(
           new Runnable() // anonymous inner class
           {
                 public void run() // from Runnable interface
                 {
                    createAndShowGUI();
                 }  // end run
           });  // end new Runnable
    }  // end main
}  // end PizzaApp2
