// Shell for the start of a Binary Search Tree class

public class BST {

    private class Node {
        private Comparable data;
        private Node left;
        private Node right;
        private Node(Comparable c,Node link,Node backLink) {
            data=c;
            left=link;
            right=backLink;
        }
    }

    private Node root;

    public BST () {
        root = null;
    }

    // insert an item into the tree
    public void insert (Comparable item) {
        if (root == null) {
            root = new Node (item, null, null);
        } 
        else { 
            boolean done = false;
            Node treeNode = root;
            while (!done) {
                // move down the tree to find bottom
                if (item.compareTo(treeNode.data) < 0) {
                    // move left
                    if (treeNode.left == null) {
                        treeNode.left = new Node (item, null, null);
                        done = true;
                    }
                    else treeNode = treeNode.left;
                }
                else {
                    // move right
                    if (treeNode.right == null) {
                        treeNode.right = new Node (item, null, null);
                        done = true;
                    }
                    else treeNode = treeNode.right;
                }
            }
        }
    } // insert

    // determine if tree is empty
    public boolean isEmpty () {
        return (root == null);
    } // isEmpty
 
    // count the number of items in the tree
    public int count () {
        // method not yet implemented, so return obviously wrong value
        return -1;
    } // count

    // determine if a given item is in the tree
    // iterative version
    public boolean findIt (Comparable item) {
        // method no yet implemented -- always return false
        return false;
    } // findIt

    // determine if a given item is in the tree
    // recursive version
    public boolean findRec (Comparable item) {
        // method no yet implemented -- always return false
        return false;
    } // findRec

    // remove given item from the tree
    public void delete (Comparable item) {
        // method no yet implemented -- do nothing
    } // delete

    // print the leaves of a tree
    public void leaves (SimpleOutput out) {
        out.println ("Identification of leaves in tree");
        out.println ("    -- not yet implemented");
    } // leaves

    // return string representation of the tree data 
    public String toString () {
        // method is a husk for a husk-and-kernel algorithm
        return toString(root);
    } // toString ()

    private String toString (Node base) {
        if (base == null)
            return "";
        else return toString(base.left) 
                        + "\t" + base.data.toString() + "\n"
                        + toString(base.right);
    } // toString (base)

    public static void main (String [] args) {
        // testing procedure, which presents menu options 
        //     and calls the requested task
        SimpleInput in = new SimpleInput ();
        SimpleOutput out = new SimpleOutput ();
        String option;
        String str;
        boolean stop = false;

        BST bstTree = new BST();
    
        while (!stop) 
            {
                out.println ("Options available");
                out.println ("   C - Count number of items in the tree");
                out.println ("   D - Delete an item on tree");
                out.println ("   E - Determine if tree is empty");
                out.println ("   F - Iterative search for item in the tree");
                out.println ("   G - Recursive search for item in the tree");
                out.println ("   I - Insert an item into the tree");
                out.println ("   L - Print the leaves in the tree");
                out.println ("   P - Print alphabetical listing of items");
                out.println ("   Q - Quit");
                out.println ("Enter desired option: ");
                
                option = in.readString();
                switch (option.charAt(0)) 
                    {
                    case 'C':
                    case 'c': 
                        out.println ("Size of tree:  " + bstTree.count());
                        break;
                    case 'D':
                    case 'd': 
                        out.println ("Enter item to remove from tree");
                        str = in.readString();
                        bstTree.delete(str);
                        break;
                    case 'E':
                    case 'e': 
                        if (bstTree.isEmpty())
                            out.println ("The tree is empty");
                        else out.println ("The tree is NOT empty");
                        break;
                    case 'F':
                    case 'f': 
                        out.println ("Enter item for iterative search");
                        str = in.readString();
                        if (bstTree.findIt(str))
                            out.println ("the item was found iteratively");
                        else out.println ("item NOT found iteratively");
                        break;
                    case 'G':
                    case 'g': 
                        out.println ("Enter item for recursive search");
                        str = in.readString();
                        if (bstTree.findRec(str))
                            out.println ("the item was found recursively");
                        else out.println ("item NOT found recursively");
                        break;
                    case 'I':
                    case 'i': 
                        out.println ("Enter name of item to insert");
                        str = in.readString();
                        bstTree.insert(str);
                        break;
                    case 'L':
                    case 'l': 
                        bstTree.leaves(out);
                        break;
                    case 'P':
                    case 'p': 
                        out.println ("The elements on the tree are:");
                        out.println (bstTree.toString());
                        break;
                    case 'Q':
                    case 'q': 
                        stop = true;
                        break;
                    default:  out.println ("Invalid Option - Try Again!");
                    }
            }
        out.println ("Program terminated");

    } // main


}
