/* A highly commented version of QTest.java, an applet/application for
 * testing the Queue class
 *
 * Written by Paul Chew for CS410, March 1997.
 * Modified by Paul Chew for CS410, January 1998. * Modified by Paul Chew for CS409, February 2000.
 */

/* Each import statement causes a single public class to be available
 * from the named package.  The version below, with a * as the name of the
 * class, is a special syntax for importing all the public classes of the
 * java.awt package.  Without the import statement we could still use
 * the public classes of this package, but we would have to use the
 * fully qualified names (e.g., java.awt.Panel instead of just Panel).
 */
import java.awt.*;import java.awt.event.*;

/* Comments that start with "/**" are documentation commments that can
 * be used to automatically create code documentation.  Such comments
 * can (and should) be used before classes and methods.  The comment should
 * begin with a simple one sentence summary of the class or method; this
 * single sentence appears by itself in the documentation.  Any additional 
 * sentences expanding on the single summary sentence, are included in a 
 * later portion of the documentation.
 *
 * The following tags, when they appear at the beginning of a comment line
 * within a documentation comment, generate additional documentation: @see,
 * @author, @version, @param, @return, @exception.  It's a good idea to use
 * the last three even when you don't plan to produce separate documentation.
 */
/**
 * QTest - tests the Queue class.  Can be run as an applet or as a 
 * standalone application.
 * @author Paul Chew
 * @see Queue.java
 */
public class QTest extends java.applet.Applet {	
	/* For QTest to be able to run as an applet it must be a subclass of
	 * java.applet.Applet.
	 */

	/* Field and method declarations follow.  Access to both fields
	 * and methods is controlled by the keywords public, protected, and
	 * private.  Here's a table descrbing the various levels of access:
	 *
	 *				class		subclass	package		world
	 *	private			X
	 *	"friendly"		X						X
	 *	protected		X			X*			X
	 *	public			X			X			X			X
	 *
	 * "Friendly" is the access method used when nothing else is specified.
	 * The one entry has a * because a subclass can access a protected
	 * field of a class, but only its own copy. 
	 */

	/* A field or method can also be static or final.  A static field or
	 * method is associated with the class itself rather than an instance
	 * of that class.  A final method cannot be overridden.  
	 * A final field is constant; it cannot be assigned to.  By convention
	 * constants are written entirely in uppercase.  Note that Java
	 * is case-sensitive.
	 */		/* It's also possible to define internal classes.  One such class is	 * QNode defined within Queue.  Note that it is defined as "static";	 * this implies that this helper class is not associated with any	 * particular instance of Queue.  It's also "private" since no other 
	 * class needs to know anything about QNode.	 */

	/* q and qDisplay are accesible only from within this class.
	 */
	private Queue q = new Queue();			// Our Queue.
	private Label qDisplay;					// Displays queue's contents.
	
	/**
	 * This is the constructor for the QTest class.  For this example,	 * the constructor is actually unnecessary since the default	 * constructor does exactly what this one does.	 * 	 * The name of a constructor matches the name of its class.  	 * Constructors have a different syntax than other methods;
	 * note that there is no return type and that there is no return	 * statement within the code.	 * 
	 * A constructor implicitly creates an instance of this class as its
	 * first action.  The rest of the code should assign values to the
	 * fields of this instance.  If no constructor is specified then
	 * a default constructor is used; it takes no arguments.  The default	 * constructor is often sufficient since fields can be initialized	 * when they are declared.  If your class is parameterized in some	 * way then you must write your own constructor since this is the only	 * way to pass arguements when creating a class.
	 *
	 * A constructor is called with a special syntax using the keyword `new'.
	 */
	public QTest () {	}		/**
	 * Initializer for the QTest applet.  This code is called automatically
	 * when an applet is started.  For this example, the code is also
	 * called by the main() method to initialize QTest when QTest is
	 * running as a standalone application.
	 */	public void init () {
		setBackground(Color.green);			// Background color.				// setLayout is used to specify how controls are layed out within
		// our applet's space.  BorderLayout allows us to place items in any
		// of 5 positions: "North", "South", "East", "West", and "Center".
		setLayout(new BorderLayout());		// Placement scheme.

		// Display area.  This is just a Label that sits in the center of		// the area; the Label holds a String showing the current contents		// of the queue.  It's important that qDisplay is updated after		// each change to the queue.
		qDisplay = new Label(q.toString(),Label.CENTER);
		add("Center",qDisplay);		
		// A Panel can be thought of as a simple box used to group things.
		// Panel for inserting.
		Panel ip = new Panel();
		ip.setBackground(Color.gray);
		ip.add(new Button("jan")); 
		ip.add(new Button("feb")); 
		ip.add(new Button("mar")); 
		ip.add(new Button("apr")); 
		ip.add(new Button("may")); 
		ip.add(new Button("jun")); 
		ip.add(new Button("jul"));
		ip.add(new Button("aug"));
		ip.add(new Button("sep"));
		ip.add(new Button("oct"));
		ip.add(new Button("nov"));
		ip.add(new Button("dec"));
		add("North",ip);		
		// This is an ActionListener, defined using an anonymous class.
		// ActionListener is a predefined interface.  To implement
		// the interface we need to provide a class with an
		// actionPerformed method.  Rather than giving this class a
		// name, Java has syntax that allows us to define an anonymous
		// class: this class has no name and, for this example, just 		// one method.  This version listens for button events and performs
		// a put() operation on our queue.		ActionListener al = new ActionListener () {			public void actionPerformed (ActionEvent e) {				// An ActionEvent has a command string.  For an ActionEvent				// due to a Button, the command string contains the button's				// text.
				q.put(e.getActionCommand());		// Put button-name in q
				qDisplay.setText(q.toString());		// Update display
			}};				
		// Each of the buttons above needs to be told who handles
		// its events (action events).  This is done by adding our		// ActionListener to each button.		for (int i = 0; i < ip.getComponentCount(); i++) {
			Button b = (Button) ip.getComponent(i);
			b.addActionListener(al);
		}	
		// Panel for deleting/clearing.
		Panel dp = new Panel();
		dp.setBackground(Color.gray);		Button getButton = new Button("Get");
		dp.add(getButton);		Button clearButton = new Button("Clear");
		dp.add(clearButton);
		add("South",dp);				// We need to set up ActionListeners for these other buttons.		// This is done here, using anonymous classes.		getButton.addActionListener(new ActionListener() {			public void actionPerformed (ActionEvent e) {				if (!q.isEmpty()) q.get();			// Get item from q				qDisplay.setText(q.toString());		// Update display			}});		clearButton.addActionListener(new ActionListener() {			public void actionPerformed (ActionEvent e) {				q.clear();							// Clear the q				qDisplay.setText(q.toString());		// Update display			}});
	}

	 
	/** 
	 * The main() method acts as the entry point when QTest is run
	 * as a standalone application.  It is ignored if the class is run as	 * an applet (i.e., from a Web page).	 * 	 * When running a class as an application, the system looks for a method
	 * called `main'; it has to be declared as below (i.e., public static void
	 * and with an array of Strings for its parameter).  If no such method 
	 * exists then the program will not run.	 * 	 * @param args command line arguments that can be passed to an application
	 */
	public static void main(String args[]) {
		Frame frame = new Frame();			// Create a window.
		frame.setSize(600,200);				// Choose a size.
		frame.setTitle("Queue Window");		// Give it a title.
		QTest applet = new QTest();			// Create the applet.
		frame.add("Center",applet);			// Put the applet in the window.
		applet.init();						// Standard applet initializaion.		System.out.println("Initialized");
		applet.start();						// Standard applet start.		System.out.println("Started");
		frame.show();						// Make it visible.
		
		// System.out.println() is used above to print to standard output.
		// When using Microsoft J++, the standard output appears in a
		// special window called Output that you can find on the View
		// menu.				// The rest of the code here is to detect a window closing event.
		// A WindowListener has to handle lots of different kinds of window
		// events (e.g., open, closing, closed, iconify, deiconify,
		// activiate, and deactivate events).  The WindowAdaptor class is
		// provided to simplify this.  This class does exactly nothing
		// for each of the window events.  The code below defines an
		// anonymous subclass of WindowAdaptor that handles just the 
		// WindowClosing event.		frame.addWindowListener(new WindowAdapter() {			public void windowClosing (WindowEvent e) {				System.exit(0);				// Stop the program
			}});	}

	/**
	 * Standard method for reporting information about an applet.
	 */
	public String getAppletInfo() {
		return "Name: QTest\r\n" +
		       "Author: Paul Chew\r\n";
	}

	/* Applets	have several methods that can be overridden to perform
	 * common tasks:
	 *
	 * public void init() is called when an applet is first loaded or
	 * reloaded.  Override this method to perform the initializations needed
	 * by your applet.
	 *
	 * public void start() is called when the page containing the applet
	 * first appears on the screen.
	 *
	 * public void stop() is called when the page containing the applet is
	 * no longer on the screen.
	 *
	 * public void destroy() is called when the applet is terminating.  
	 * Cleanup code goes here.
	 *
	 * public void paint(Graphics g) is called by the system whenever the 
	 * contents of your applet need to be painted or repainted.  Code for
	 * displaying your applet's contents goes here.  Note that the standard
	 * components handle their own painting.
	 */
}
