// Linked List, Nodes, references (pointers)
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
 import java.io.*;
 
  public class LinkList extends EasyApp
  {
      public static void main(String[] args)
      {  new LinkList(); }

      Button bAdd  = addButton("Add",20,30,60,30,this);
      Button bUndo = addButton("Undo",220,30,60,30,this);
      Button bList = addButton("List",220,60,60,30,this);
      
      class Node                     // an inner class
      {                              // encapsulates two fields
          String command = "";       // similar to a "record" in
          Node next = null;          // other languages.  
      }                              // Use "new" to make copies.
      
      Node head = null;              // will point at first Node in list
      Node tail = null;              // will point at last Node in list
      
      //--- Constructor ------------------------------------------
      public LinkList()
      {
          head = new Node();                // create first Node
          head.command = "s 100 150 100";   // copy String into Node
          
          head.next = new Node();           // create second Node
          head.next.command = "red";        // copy String into Node
                    
          head.next.next = new Node();      // third Node
          head.next.next.command = "c 100 050 100";
          
          tail = head.next.next;            // sets tail to point at
                                            // the last Node in the list
          repaint();
      }
      
      public void actionPerformed(ActionEvent evt)
      {   Object source = evt.getSource();          // choose method according
          if ( source == bAdd ) { addCommand(); }   // to Button pressed
          if ( source == bUndo) { deleteTail(); }
          if ( source == bList) { showList();   }
          repaint();                                // update screen display
      }
      
      public void addCommand()
      {
          String cmd
               = input("Type a command, like the following:\n" +
                       "  red , green , blue ... for a color\n" +
                       "  s 100 150 050 ... square at 100,150 side = 50\n" +
                       "  c 200 080 120 ... circle at 200,80 diameter = 120"
                      );
          tail.next = new Node();        // Make new Node and
                                         //   attach at end of list
          tail = tail.next;              // Move tail to point at
                                         //   the new end of the list
          tail.command = cmd;            // Copy command into new Node
      }
      
      public void deleteTail()
      {
          if ( tail == head )             // Avoid NullPointerException by
          { return;}                      //   leaving at least one Node in list

          Node temp = head;               // start at head
          while ( temp.next != tail )     // stop one node BEFORE tail
          { temp = temp.next; }           // next node
          temp.next = null;               // chop off tail node
          tail = temp;                    // adjust tail to point at last node
      }
      
      public void showList()
      {
          String show = "";               // collect all commands in one String
          Node temp = head;               // start at the first Ndoe
          while (temp != null)            // go to the end of the list
          {
              show = show + temp.command + "\n";   // copy command into show
              temp = temp.next;                    // move to next Node
          }
          output(show);                   // display all commands
      }
      
      public void paint(Graphics g)
      {
          g.setColor(Color.black);        // start with black ink
          Node temp = head;               // beginning of linked-list
          while (temp != null)            // stop after end of linked-list
          {
              String cmd = temp.command;  // copy command out of Node

              if ( cmd.equals("green") )       // if "green" then setColor
              { g.setColor(Color.green);}
              else if ( cmd.equals("red") )    // if "red" then setColor
              { g.setColor(Color.red);  }
              else if ( cmd.equals("blue") )   // if "blue" then setColor
              { g.setColor(Color.blue); }
              else if ( cmd.length() == 13 )   // check for correct length
              {   
                  int x = Integer.parseInt( cmd.substring(2,5) );    // extract 3 characters
                                                                     // convert to int x
                  int y = Integer.parseInt( cmd.substring(6,9) );    // extract 3 characters
                                                                     // convert to int y
                  int s = Integer.parseInt( cmd.substring(10,13) );  // extract 3 characters
                                                                     // convert to int z
                  if ( cmd.charAt(0) == 'c' )         // circle command
                  { g.fillOval(x,y,s,s);}
                  else if ( cmd.charAt(0) == 's' )    // square command
                  { g.fillRect(x,y,s,s);}
              }

              temp = temp.next;                       // move to next Node
          }
      }
  }