import java.io.*;
import java.text.*;
import java.awt.event.*;
import java.awt.*;

/* Application that creates a frame, which in turn creates a second frame.  The first one is used to read from a file into a linked list, display the contents, and save the list.  It also has a button to show the second frame.  The second frame is used to add a new order to the list. /*
public class OrdersAddFrame
{
     public static void main (String [] args)
     {
          OrderWindow frame = new OrderWindow ();
          frame.addWindowListener (new WindowCloser ());
          frame.show ();
     }
} // class ShowFrames

class WindowCloser extends WindowAdapter
{
     public void windowClosing (WindowEvent e){System.exit (0);}
} // class WindowCloser

// The first frame class.  It creates the main frame with its TextArea and Buttons.
class OrderWindow extends Frame
{
     private Panel panel;
     private Label areaLabel;
     private TextArea area;
     private OrderList list;
     private Button readFile, display, save, showAddWindow;
     private AddWindow addWindow;

     OrderWindow ()
     {
          super ("Orders");
          setSize (300, 300);
          panel = new Panel ();
          panel.setBackground (Color.cyan);
          areaLabel = new Label ("Order");
          area = new TextArea (10, 30);
         panel.add (areaLabel); panel.add (area);

          readFile = new Button ("Read Order");
          readFile.addActionListener (new ReadListener ());
          panel.add (readFile);

          display = new Button ("Display Order");
          display.addActionListener (new DisplayListener ());
          panel.add (display);

          save = new Button ("Save Order");
          save.addActionListener (new SaveListener ());
          panel.add (save);

          showAddWindow = new Button ("Show Add Window");
          showAddWindow.addActionListener (new ShowAddListener ());
          panel.add (showAddWindow);

         add (panel);
          list = new OrderList ();
          addWindow = new AddWindow (list);
     } // method constructor

     // Four inner classes that define the action listeners for the four buttons.
     class DisplayListener implements ActionListener
     {
          public void actionPerformed (ActionEvent e) {list.displayOrders (area);}
     } // class DisplayListener

     class ReadListener implements ActionListener
     {
          public void actionPerformed (ActionEvent e) {list.readOrders ();}
     } // class ReadListener

     class SaveListener implements ActionListener
     {
          public void actionPerformed (ActionEvent e) {list.saveOrders ();}
     } // class SaveListener

     class ShowAddListener implements ActionListener
     {
          public void actionPerformed (ActionEvent e) {addWindow.show ();}
     } // class ShowAddListener
} // class OrderFrame

// A second frame that is used to gather the data in order to add a new order.
class AddWindow extends Frame
{
     private Panel panel;
     private Button addOrder, hideWindow;
     private TextField txtName, txtId, txtPrice, txtQuantity;
     private Label lblName, lblId, lblPrice, lblQuantity;
     private OrderList list;

     AddWindow (OrderList orderList)
     {
          super ("Add Window");
          setSize (320, 300);
          list = orderList;
          panel = new Panel ();
          panel.setBackground (Color.cyan);

          txtName = new TextField (10); lblName = new Label ("Name");
          panel.add (lblName); panel.add (txtName);
          txtId = new TextField (10); lblId = new Label ("ID");
          panel.add (lblId); panel.add (txtId);
          txtPrice = new TextField (10); lblPrice = new Label ("Price");
          panel.add (lblPrice); panel.add (txtPrice);
          txtQuantity = new TextField (10); lblQuantity = new Label ("Quantity");
          panel.add (lblQuantity); panel.add (txtQuantity);
          add (panel);

          addOrder = new Button ("Add Order");
          addOrder.addActionListener (new AddListener ());
          panel.add (addOrder);

          hideWindow = new Button ("Hide");
          hideWindow.addActionListener (new HideListener ());
          panel.add (hideWindow);
          add (panel);
     } // constructor

     // Inner class that defines the action performed when the AddOrder button is clicked.
     class AddListener implements ActionListener
     {
          public void actionPerformed (ActionEvent e)
          {
               try
               {
                    String name = txtName.getText ();
                    String id = txtId.getText ();
                    double price = Double.parseDouble (txtPrice.getText ());
                    int quantity = Integer.parseInt (txtQuantity.getText ());
                    Order newOrder = new Order (name);
                    newOrder.storeOrder (id, price, quantity);
                    list.addToEnd (newOrder);
               }catch (NumberFormatException ex) {txtName.setText ("Data Error");}
          } // method actionPerformed
     } // class AddListener

     // Inner class that hides the second frame when it is no longer needed.
     class HideListener implements ActionListener
     {
          public void actionPerformed (ActionEvent e) {hide ();}
     } // class HideListener
} // class AddWindow

// Class that manages a linked list of orders.
class OrderList
{
     private Order listHead, listRear;
     final int maxSize = 10;
     private int listSize;

     OrderList ()
     {
          listHead = null;
          listRear = null;
     } // constructor

     // Method that reads orders from a text file into a linked list.
     public void readOrders ()
     {
          try
          {
               BufferedReader orderFile = new BufferedReader (new InputStreamReader (new FileInputStream ("orderFile.txt")));
               String title = orderFile.readLine ();
               while ((title != null) && (listSize < maxSize))
               {
                    Order order = new Order (title);
                    order.readOrder (orderFile);
                    addToEnd (order);
                    title = orderFile.readLine ();
               }
               orderFile.close ();
          }catch (IOException e) {System.out.println ("File Error");}
     } // method readOrders

     // Protected method that adds an order to the end of the list.
     protected void addToEnd (Order newOrder)
     {
          if (listHead == null)
          {
               listHead = newOrder;
               listRear = newOrder;
          }
          else
          {
               listRear.setNext (newOrder);
               listRear = newOrder;
          }
     } // method addToEnd

     // Method that displays orders on a TextArea.
     public void displayOrders (TextArea area)
     {
          Order tempOrder = listHead;
          while (tempOrder != null)
          {
               tempOrder.displayOrder (area);
               tempOrder = tempOrder.getNext ();
          }
          area.append ("The total cost is " + NumberFormat.getCurrencyInstance ().format (calculateTotal ()) + '\n');
     } // method displayOrders

     // Private method that calculates the total cost of the orders.
     private double calculateTotal ()
     {
          double total = 0;
          Order tempOrder = listHead;
          while (tempOrder != null)
          {
               double price = tempOrder.getPrice ();
               int quantity = tempOrder.getQuantity ();
               total += price * quantity;
               tempOrder = tempOrder.getNext ();
          }
          return total;
     } // method totalCost

     // Method that saves the list to a second text file.
     public void saveOrders ()
     {
          try
          {
               PrintStream outfile = new PrintStream (new FileOutputStream ("orderFile2.txt"));
               Order tempOrder = listHead;
               while (tempOrder != null)
               {
                    tempOrder.outputOrder (outfile);
                    tempOrder = tempOrder.getNext ();
                }
               outfile.println ("The total cost is " + NumberFormat.getCurrencyInstance ().format (calculateTotal ()));
               outfile.close ();
          } catch (FileNotFoundException e) {System.out.println ("No File");}
     } // method saveOrders
} // class OrderList

// Class that defines a single order.
class Order
{
     private String name, id;
     private double price;
     private int quantity;
     private Order next;

     // Constructor that is used when the orders are read into the linked list.
     Order (String name)
     {
          this.name = name;
          next = null;
     } // constructor

     // Constructor that is used when a new order is added to the list.
     public void storeOrder (String id, double price, int quantity)
     {
          this.id = id;
          this.price = price;
          this.quantity = quantity;
     } // constructor

     protected Order getNext () { return next;}
     protected void setNext (Order newOrder) { next = newOrder;}
     public double getPrice () {return price;}
     public int getQuantity () { return quantity;}

     // Method to read an order in from a text file.
     public void readOrder (BufferedReader orderFile) throws IOException
     {
          id = orderFile.readLine ();
          price = Double.parseDouble (orderFile.readLine ());
          quantity = Integer.parseInt (orderFile.readLine ());
     } // method readOrder

     // Method that displays an order on a TextArea.
     public void displayOrder (TextArea area)
     {
          area.append ("Product Name: " + name + '\n');
          area.append ("Product ID: " + id + '\n');
          area.append ("Price: " + price + '\n');
          area.append ("Quantity: " + quantity + '\n' + '\n');
     } // method displayOrder

     // Method that saves an order to an output file. Order
     public void outputOrder (PrintStream outfile)
     {
          outfile.println ("Product Name: " + name);
          outfile.println ("Product ID: " + id);
          outfile.println ("Price: " + price);
          outfile.println ("Quantity: " + quantity);
          outfile.println ();
     } // method outputOrder
} // class Order