/*
	cursus - Race series management program
	Copyright 2011  Simon Arlott

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package eu.lp0.cursus.ui.component;

import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

public abstract class AbstractTree<O extends Frame & DatabaseWindow, R extends TreeNode, T> extends JTree {
	protected final O win;
	protected final R root;

	public AbstractTree(O win, R root) {
		super();
		this.win = win;
		this.root = root;

		setModel(new DefaultTreeModel(root));

		setRootVisible(false);
		getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent me) {
				ensureSelection(me);
				if (me.isPopupTrigger()) {
					showMenu(me);
				}
			}

			@Override
			public void mouseReleased(MouseEvent me) {
				ensureSelection(me);
				if (me.isPopupTrigger()) {
					showMenu(me);
				}
			}
		});
	}

	protected abstract T userObjectFromPathComponent(Object component);

	protected abstract JPopupMenu menuFromUserObject(T item);

	private void ensureSelection(MouseEvent me) {
		TreePath path = getPathForLocation(me.getX(), me.getY());

		if (getSelectionPath() != path) {
			if (path == null || me.isPopupTrigger()) {
				setSelectionPath(path);
			}
		}
	}

	private void showMenu(MouseEvent me) {
		TreePath path = getSelectionPath();
		JPopupMenu menu = null;

		if (path != null) {
			menu = menuFromUserObject(userObjectFromPathComponent(path.getLastPathComponent()));
		} else {
			menu = menuFromUserObject(null);
		}
		menu.show(me.getComponent(), me.getX(), me.getY());
	}
}
@@ -754,16 +754,105 @@
 .Frame;%0A
+import java.awt.Point;%0Aimport java.awt.event.KeyAdapter;%0Aimport java.awt.event.KeyEvent;%0A
 import j
@@ -871,32 +871,32 @@
 t.MouseAdapter;%0A
-
 import java.awt.
@@ -1521,16 +1521,199 @@
 TION);%0A%0A
+%09%09addKeyListener(new KeyAdapter() %7B%0A%09%09%09@Override%0A%09%09%09public void keyReleased(KeyEvent ke) %7B%0A%09%09%09%09if (ke.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) %7B%0A%09%09%09%09%09showMenu(ke);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D);%0A%0A
 %09%09addMou
@@ -2437,32 +2437,321 @@
 ouseEvent me) %7B%0A
+%09%09showMenu(me.getX(), me.getY());%0A%09%7D%0A%0A%09private void showMenu(KeyEvent ke) %7B%0A%09%09Point mouse = getMousePosition();%0A%09%09if (mouse != null) %7B%0A%09%09%09showMenu((int)getMousePosition().getX(), (int)getMousePosition().getY());%0A%09%09%7D else %7B%0A%09%09%09showMenu(0, 0);%0A%09%09%7D%0A%09%7D%0A%0A%09private void showMenu(int x, int y) %7B%0A
 %09%09TreePath path 
@@ -2976,47 +2976,18 @@
 how(
-me.getComponent(), me.getX(), me.getY()
+this, x, y
 );%0A%09

support the popup menu key