package fha.inf3.tree;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.util.*;

public class TreeDemo extends JFrame {
	
	private int heightRek;
	private int heightIt;

	private void traverse(TreeNode root) {
		System.out.println("Traverse rekursiv");
		System.out.println("-----------------");
		traverseRek(root, 0);
		System.out.println("Hoehe: " + this.heightRek);
		System.out.println("\n");
		System.out.println("Traverse iterativ");
		System.out.println("-----------------");
		traverseIt(root);
		System.out.println("Hoehe: " + this.heightIt);
	}
	
	private void traverseIt(TreeNode node) {
		System.out.println(node);
		if (!node.isLeaf()) {
			int level = 1;
			Enumeration children = node.children();
			while (level > 0) {
				while (children.hasMoreElements()) {
					node = (TreeNode) children.nextElement();
					if (level > this.heightIt) {
						this.heightIt = level;
					}
					for (int i = 0; i < level; i++) {
						System.out.print("     ");
					}
					System.out.println(node);
					if (!node.isLeaf()) {
						children = node.children();
						level++;
					}
				}
				node = node.getParent();
				level--;
				if (level != 0) {
					children = node.getParent().children();
					while (children.hasMoreElements() && node != (TreeNode) children.nextElement()) {
					}
				}
			}
		}
	}
	private void traverseRek(TreeNode node, int level) {
		if (level > this.heightRek) {
			this.heightRek = level;
		}
		for (int i = 0; i < level; i++) {
			System.out.print("     ");
		}
		System.out.println(node);
		Enumeration children = node.children();
		while (children.hasMoreElements()) {
			traverseRek((TreeNode) children.nextElement(), level+1);
		}
	}
	
	private int newNodeNumber = 1;

	public TreeDemo() {
		super("Tree Demo");
		
		//create the components
		final TreeView treeView = new TreeView();

		JButton addButton = new JButton("Add");
		addButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				treeView.addObject("" + newNodeNumber++);
			}
		});

		JButton removeButton = new JButton("Remove");
		removeButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				treeView.removeCurrentNode();
			}
		});

		JButton clearButton = new JButton("Clear");
		clearButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				treeView.clear();
				newNodeNumber = 1;
			}
		});

		JButton traverseButton = new JButton("Traverse");
		traverseButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				traverse(treeView.getRootNode());
			}
		});
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new GridLayout(0,1));
		buttonPanel.add(addButton);
		buttonPanel.add(removeButton);
		buttonPanel.add(clearButton);
		buttonPanel.add(traverseButton);
		
		//Lay everything out.
		Container contentPane = this.getContentPane();
		contentPane.setLayout(new BorderLayout());
		treeView.setPreferredSize(new Dimension(300, 200));
		contentPane.add(treeView, BorderLayout.CENTER);
		contentPane.add(buttonPanel, BorderLayout.EAST);
	}

	public static void main(String[] args) {
 
		JFrame frame = new TreeDemo();
		
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		frame.pack();
		frame.setLocation(100,100);
		frame.setVisible(true);
	}
}

class TreeView extends JPanel {
	private DefaultTreeModel treeModel;
	private JTree tree;

	public TreeView() {
		treeModel = new DefaultTreeModel(new DefaultMutableTreeNode("0"));
		tree = new JTree(treeModel);
		tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		tree.setShowsRootHandles(true);

		JScrollPane scrollPane = new JScrollPane(tree);
		setLayout(new GridLayout(1,1));
		add(scrollPane);
	}

	/** Return the tree model. */
	public TreeNode getRootNode(){
		return (TreeNode)treeModel.getRoot();
	}

	/** Remove all nodes except the root node. */
	public void clear() {
		((DefaultMutableTreeNode)treeModel.getRoot()).removeAllChildren();
		treeModel.reload();
	}

	/** Remove the currently selected node. */
	public void removeCurrentNode() {
		TreePath currentSelection = tree.getSelectionPath();
		if (currentSelection != null) {
			DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
						 (currentSelection.getLastPathComponent());
			MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
			if (parent != null) {
				treeModel.removeNodeFromParent(currentNode);
				return;
			}
		} 
	}

	/** Add child to the currently selected node. */
	public DefaultMutableTreeNode addObject(Object child) {
		DefaultMutableTreeNode parentNode = null;
		TreePath parentPath = tree.getSelectionPath();

		if (parentPath == null) {
			parentNode = (DefaultMutableTreeNode)getRootNode();
		} 
		else {
			parentNode = (DefaultMutableTreeNode)parentPath.getLastPathComponent();
		}

		DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
		treeModel.insertNodeInto(childNode, parentNode, parentNode.getChildCount());
		tree.scrollPathToVisible(new TreePath(childNode.getPath()));
		return childNode;
	}
}
