import java.util.Vector;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

/**
 * @author John Free
 *
 */
public class TestTree
{
  final static Display display  = new Display();
  final static Shell shell      = new Shell(display);
  static Tree tree;

   /**
   * @param args
   */
  public static void main(String[] args)
  {
    shell.setLayout(new GridLayout());
    tree = new Tree(shell, SWT.NONE);
    tree.setLayout(new GridLayout());
    tree.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));

    TreeItem item = new TreeItem(tree, SWT.NONE);
    item.setText(getNodeName());

    final Menu menu = new Menu(tree);
    tree.setMenu(menu);

    final MenuItem insertBeforeMenuItem = new MenuItem(menu, SWT.NONE);
    insertBeforeMenuItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(final SelectionEvent e)
      {
        TreeItem [] selected = tree.getSelection();

        if (selected.length > 0)
        {
          TreeItem parent = selected[0].getParentItem();
          if (parent == null)
          {
            System.out.println("Cannot insert before the root element.");
            return;
          }
          System.out.println("Insert Before - " + selected[0].getText());
          int index = parent.indexOf(selected[0]);

          TreeItem item = new TreeItem(parent, SWT.NONE, index);
          item.setText(getNodeName());
        }
        else
          System.out.println("Insert Before - nothing selected.");
      }
    });

    insertBeforeMenuItem.setText("Insert Before");

    final MenuItem insertIntoMenuItem = new MenuItem(menu, SWT.NONE);
    insertIntoMenuItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(final SelectionEvent e)
      {
        TreeItem [] selected = tree.getSelection();

        if (selected.length > 0)
        {
          TreeItem selection = selected[0];
          TreeItem item = new TreeItem(selection, SWT.NONE, 0);
          item.setText(getNodeName());
          selection.setExpanded(true);
          System.out.println("Insert Into - " + selected[0].getText());
        }
        else
          System.out.println("Insert Into - nothing selected.");
      }
    });
    insertIntoMenuItem.setText("Insert Into");

    final MenuItem insertAfterMenuItem = new MenuItem(menu, SWT.NONE);
    insertAfterMenuItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(final SelectionEvent e)
      {
        TreeItem [] selected = tree.getSelection();

        if (selected.length > 0)
        {
          TreeItem parent = selected[0].getParentItem();
          if (parent == null)
          {
            System.out.println("Cannot insert after the root element.");
            return;
          }
          int index = parent.indexOf(selected[0]);

          TreeItem item = new TreeItem(parent, SWT.NONE, ++index);
          item.setText(getNodeName());
          System.out.println("Insert After - " + selected[0].getText());
        }
        else
          System.out.println("Insert After - nothing selected.");
      }
    });

    insertAfterMenuItem.setText("Insert After");

    new MenuItem(menu, SWT.SEPARATOR);

    final MenuItem removeItemMenuItem = new MenuItem(menu, SWT.NONE);
    removeItemMenuItem.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(final SelectionEvent e)
      {
        final class NodeValues // a helper class that holds any values we want to save from the node.
        {
          public NodeValues(TreeItem item)
          {
            data = item.getData();
            name = item.getText();
          }
          public String name;
          public Object data;
        }

        TreeItem [] selected = tree.getSelection();
        if (selected.length > 0)
        {
          TreeItem selection = selected[0];

          if (selection.getParentItem() == null)
          {
            System.out.println("Cannot remove root element.");
            return;
          }
          System.out.println("Remove - " + selected[0]);

          TreeItem parent = selection.getParentItem();

          Vector<NodeValues> children = new Vector<NodeValues>();
          TreeItem [] items = parent.getItems();

          for (int i = 0; i < items.length; i++)
          {
            if (i == parent.indexOf(selection))
            {
              System.out.println("The selected node is at index " + i);
            }
            else
              children.add(new NodeValues(items[i]));
          }
          assert children.size() == (items.length - 1);
          parent.removeAll();

          for (int i = 0; i < children.size(); i++)
          {
            TreeItem item = new TreeItem(parent, SWT.None, i);
            item.setData(children.elementAt(i).data);
            item.setText(children.elementAt(i).name);
          }
          parent.setExpanded(true);
        }
        else
          System.out.println("Remove - nothing selected.");
      }
    });
    removeItemMenuItem.setText("Remove Item");

    shell.setSize(346, 471);
    shell.setLayout(new GridLayout());
    shell.open();


    // Set up the event loop.
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) {
        // If no more entries in event queue
        display.sleep();
      }
    }
    display.dispose();
  }
  /*
   * returns the next node name in the sequnece.
   */
  static String getNodeName()
  {
    return "Item - " + lastUsed++;
  }
  static int lastUsed = 0;
}


