// Michael Tartaglia
// BinaryTreeDemo: An implementation of the BinaryTree file

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class BinaryTreeDemo extends Applet
implements AdjustmentListener,
           ActionListener {
   private boolean ERROR;								// ERROR CHECKER
   private BinaryTree tree = new BinaryTree();	// BINARY TREE FOR PROGRAM
   private TextArea text;								// TEXT FIELD TO SHOW RESULTS
   private TextField numField;						// FIELD IN WHICH NUMBERS ARE ENTERED
   private Button enterButton, randomButton;		// ENTER KEYS
   private Scrollbar horiz, vert;					// SCROLL BARS TO VIEW PRINTED TREE

   public void init() {
      setBackground(Color.white);

      Label instruct = new Label("Input some numbers.");
		
		// SET UP TEXTBOX
      text = new TextArea("",5,40,text.SCROLLBARS_VERTICAL_ONLY);
      text.setEditable(false);
      text.setBackground(Color.white);
		
		// SET UP NUMBER ENTRY BOX
      numField = new TextField(5);
      numField.setEditable(true);
      numField.addActionListener(this);
		
		// SET UP ENTER KEYS
      enterButton = new Button("Enter");
      enterButton.addActionListener(this);
      randomButton = new Button("__ Random #'s");
      randomButton.addActionListener(this);

		// SET UP SCROLLERS
      horiz = new Scrollbar(0,0,25,0,400);
      horiz.addAdjustmentListener(this);
      vert = new Scrollbar(1,0,25,0,400);
      vert.addAdjustmentListener(this);

      add(instruct); add(numField);
      add(enterButton); add(randomButton);
      add(text); add(horiz); add(vert);
   }

	
   public void adjustmentValueChanged(AdjustmentEvent e)
	// FOR USE WITH SCROLL BARS
	{
      repaint();
   }

   public void actionPerformed(ActionEvent e)
	// FOR USE WITH ENTER KEYS
	{
      ERROR = false;			// RESET ERROR CHECK BOOLEAN
      Object source = e.getSource();	// GET SOURCE OF ACTION
      double num; int x = 0;
      if (source == numField || source == enterButton) {
         try {					// RETRIEVE NUMBER ENTERED
            num = Double.parseDouble(numField.getText());
            tree.insertItem(num);	// PLACE NUMBER IN TREE
         } catch (NumberFormatException nfe) {ERROR = true;}
			
      } else if (source == randomButton) {	// IF "RANDOM" IS HIT
			// GET THE NUMBER "X" FROM TEXT BOX
         try {x = Integer.parseInt(numField.getText());}
         catch (NumberFormatException nfe) {ERROR = true;}
			
			// AND ADD "X" RANDOM NUMBERS ONTO TREE
         if (!ERROR) for (int i = 1; i <= x; ++i) {
            num = (double)Math.round(Math.random()*100)/10;
            tree.insertItem(num);
         }
      }
      if (ERROR) text.setText("Error! Try again!\n");
      else if (tree.isEmpty()) text.setText("No numbers in list!");
      else text.setText("Entered " +tree.length()+ " numbers:");

		// SHOW RESULTS OF VARIOUS TRAVERSALS
      text.append("\nInorder:\t\t"); showElements(tree.inorderTraverse());
      text.append("\nPreorder:\t"); showElements(tree.preorderTraverse());
      text.append("\nPostorder:\t"); showElements(tree.postorderTraverse());

      repaint();
   }

   public void paint(Graphics g) {
      printTreeInApplet(g,tree.printTree(),40,160);
   }

   private void showElements(String out) {
		// RECIEVES STRING OF NUMBERS SEPARATED BY "|" AND PRINTS NUMBERS
      int bar; String seg;
      while (out.indexOf('|') >= 0) {
         bar = out.indexOf('|');
         seg = out.substring(0,bar);
         text.append(seg + "\t ");
         out = out.substring(bar+1,out.length());
      }
      text.append("\n");
   }

   private void printTreeInApplet(Graphics g, String curTree, int x, int y) {
		// PRINTS TEXT TREE AS APPLET, WHERE "\n" IN STRING RESETS y VALUE OF APPLET;
		//		TREE, WHEN PRINTED OUT, LOOKS SIDEWAYS, WITH ROOT NODE SEEN AS LEFTMOST NUMBER
      x -= horiz.getValue();	// VALUE OF HORIZONAL SCROLLER
      y -= vert.getValue();	// VALUE OF VERTICAL SCROLLER
      int bar = 0, xOrig = x, i, greyScale = 0;
      String seg;
      while (curTree.indexOf('\n') >= 0) {		// WHILE THERE IS SOMETHING TO PRINT OTHER THAN "\n"
         bar = curTree.indexOf('\n');				// GET FIRST "LEG" OF TREE
         seg = curTree.substring(0,bar);
         for (i = 0; i < bar && curTree.charAt(i) == ' ';
              ++i, x+=5, greyScale += 4);			// THE DEEPER THE NODE, THE LIGHTER IN COLOR IT'S SEEN
         seg = seg.substring(seg.lastIndexOf(' ')+1,seg.length());
         if (greyScale > 200) greyScale = 200;	// MAX-OUT THE COLOR VALUES AT 200
         g.setColor(new Color(greyScale,greyScale,greyScale));	// SET GREY COLOR
         if (x == xOrig) {x-=10; seg += " (root)";}				// LABEL ROOT
         g.drawString(seg,x,y);						// DRAW LEG
         y += 6; x = xOrig; greyScale = 0;		// SET UP FOR NEXT LINE, AND RESET COLOR VALUE
         curTree = curTree.substring(bar+1,curTree.length());	// RESET TREE STRING
      }
   }

}