/*******************************************************************************
 * Copyright (c) 2007, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.tests.internal.model.value.swing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.EnumerationIterator;
import org.eclipse.jpt.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.swing.TreeModelAdapter;
import org.eclipse.jpt.utility.internal.swing.Displayable;
import org.eclipse.jpt.utility.model.value.TreeNodeValueModel;
import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;
import org.eclipse.jpt.utility.tests.internal.model.value.swing.TreeModelAdapterTests.SortedTestNode;
import org.eclipse.jpt.utility.tests.internal.model.value.swing.TreeModelAdapterTests.TestModel;
import org.eclipse.jpt.utility.tests.internal.model.value.swing.TreeModelAdapterTests.TestNode;
import org.eclipse.jpt.utility.tests.internal.model.value.swing.TreeModelAdapterTests.UnsortedTestNode;

/**
 * an example UI for testing the TreeModelAdapter
 */
public class TreeModelAdapterUITest {

	// hold the tree so we can restore its expansion state
	private JTree tree;
	private WritablePropertyValueModel<TreeNodeValueModel<Object>> rootNodeHolder;
	private boolean sorted;
	private TreeModel treeModel;
	private TreeSelectionModel treeSelectionModel;
	private TextField nameTextField;

	public static void main(String[] args) throws Exception {
		new TreeModelAdapterUITest().exec(args);
	}

	private TreeModelAdapterUITest() {
		super();
	}

	private void exec(String[] args) throws Exception {
		this.rootNodeHolder = this.buildRootNodeHolder();
		this.sorted = this.rootNodeHolder.getValue() instanceof SortedTestNode;
		this.treeModel = this.buildTreeModel();
		this.treeSelectionModel = this.buildTreeSelectionModel();
		this.nameTextField = new TextField();
		this.openWindow();
	}

	private WritablePropertyValueModel<TreeNodeValueModel<Object>> buildRootNodeHolder() {
		return new SimplePropertyValueModel<TreeNodeValueModel<Object>>(this.buildSortedRootNode());
	}

	private TestNode buildSortedRootNode() {
		return new SortedTestNode(this.buildRoot());
	}

	private TestNode buildUnsortedRootNode() {
		return new UnsortedTestNode(this.buildRoot());
	}

	private TestModel buildRoot() {
		TestModel root = new TestModel("root");

		TestModel node_1 = root.addChild("node 1");
		/*Node node_1_1 = */node_1.addChild("node 1.1");

		TestModel node_2 = root.addChild("node 2");
		/*Node node_2_1 = */node_2.addChild("node 2.1");
		TestModel node_2_2 = node_2.addChild("node 2.2");
		/*Node node_2_2_1 = */node_2_2.addChild("node 2.2.1");
		/*Node node_2_2_2 = */node_2_2.addChild("node 2.2.2");
		/*Node node_2_3 = */node_2.addChild("node 2.3");
		/*Node node_2_4 = */node_2.addChild("node 2.4");
		/*Node node_2_5 = */node_2.addChild("node 2.5");

		TestModel node_3 = root.addChild("node 3");
		TestModel node_3_1 = node_3.addChild("node 3.1");
		TestModel node_3_1_1 = node_3_1.addChild("node 3.1.1");
		/*Node node_3_1_1_1 = */node_3_1_1.addChild("node 3.1.1.1");

		/*Node node_4 = */root.addChild("node 4");

		return root;
	}

	private TreeModel buildTreeModel() {
		return new TreeModelAdapter<Object>(this.rootNodeHolder);
	}

	private TreeSelectionModel buildTreeSelectionModel() {
		TreeSelectionModel tsm = new DefaultTreeSelectionModel();
		tsm.addTreeSelectionListener(this.buildTreeSelectionListener());
		tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		return tsm;
	}

	private TreeSelectionListener buildTreeSelectionListener() {
		return new TreeSelectionListener() {
			public void valueChanged(TreeSelectionEvent e) {
				TreeModelAdapterUITest.this.treeSelectionChanged(e);
			}
		};
	}

	void treeSelectionChanged(TreeSelectionEvent e) {
		TestModel selectedTestModel = this.selectedTestModel();
		if (selectedTestModel != null) {
			this.nameTextField.setText(selectedTestModel.getName());
		}
	}

	private void openWindow() {
		JFrame window = new JFrame(this.getClass().getName());
		window.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		window.addWindowListener(this.buildWindowListener());
		window.getContentPane().add(this.buildMainPanel(), "Center");
		window.setLocation(300, 300);
		window.setSize(400, 400);
		window.setVisible(true);
	}

	private WindowListener buildWindowListener() {
		return new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				e.getWindow().setVisible(false);
				System.exit(0);
			}
		};
	}

	private Component buildMainPanel() {
		JPanel mainPanel = new JPanel(new BorderLayout());
		mainPanel.add(this.buildTreePane(), BorderLayout.CENTER);
		mainPanel.add(this.buildControlPanel(), BorderLayout.SOUTH);
		return mainPanel;
	}

	private Component buildTreePane() {
		return new JScrollPane(this.buildTree());
	}

	private JTree buildTree() {
		this.tree = new JTree(this.treeModel) {
			@Override
			public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
				return ((Displayable) value).displayString();
			}
		};
		this.tree.setSelectionModel(this.treeSelectionModel);
		this.tree.setRootVisible(true);
		this.tree.setShowsRootHandles(true);
		this.tree.setRowHeight(20);
		this.tree.setDoubleBuffered(true);
		return this.tree;
	}

	private Component buildControlPanel() {
		JPanel controlPanel = new JPanel(new GridLayout(0, 1));
		controlPanel.add(this.buildAddRenameNodePanel());
		controlPanel.add(this.buildMiscPanel());
		return controlPanel;
	}

	private Component buildAddRenameNodePanel() {
		JPanel addRenameNodePanel = new JPanel(new BorderLayout());
		addRenameNodePanel.add(this.buildAddButton(), BorderLayout.WEST);
		addRenameNodePanel.add(this.nameTextField, BorderLayout.CENTER);
		addRenameNodePanel.add(this.buildRenameButton(), BorderLayout.EAST);
		return addRenameNodePanel;
	}

	private Component buildMiscPanel() {
		JPanel miscPanel = new JPanel(new GridLayout(1, 0));
		miscPanel.add(this.buildClearChildrenButton());
		miscPanel.add(this.buildRemoveButton());
		miscPanel.add(this.buildResetButton());
		return miscPanel;
	}

	private String getName() {
		return this.nameTextField.getText();
	}

	// ********** queries **********
	private TestNode selectedNode() {
		if (this.treeSelectionModel.isSelectionEmpty()) {
			return null;
		}
		return (TestNode) this.treeSelectionModel.getSelectionPath().getLastPathComponent();
	}

	private TestModel selectedTestModel() {
		if (this.treeSelectionModel.isSelectionEmpty()) {
			return null;
		}
		return this.selectedNode().getValue();
	}

	private TestNode rootNode() {
		return (TestNode) this.treeModel.getRoot();
	}

	private TestModel root() {
		return this.rootNode().getValue();
	}

	private Collection<TreePath> expandedPaths() {
		Enumeration<TreePath> stream = this.tree.getExpandedDescendants(new TreePath(this.rootNode()));
		if (stream == null) {
			return Collections.emptyList();
		}
		return CollectionTools.list(new EnumerationIterator<TreePath>(stream));
	}

	// ********** behavior **********
	private void setSelectedNode(TestNode selectedNode) {
		this.treeSelectionModel.setSelectionPath(new TreePath(selectedNode.path()));
	}

	private void expandPaths(Collection<TreePath> paths) {
		for (TreePath path : paths) {
			this.tree.expandPath(path);
		}
	}

	// ********** add **********
	private JButton buildAddButton() {
		return new JButton(this.buildAddAction());
	}

	private Action buildAddAction() {
		Action action = new AbstractAction("add") {
			public void actionPerformed(ActionEvent event) {
				TreeModelAdapterUITest.this.addNode();
			}
		};
		action.setEnabled(true);
		return action;
	}

	/**
	 * adding causes the tree to be sorted and nodes to be
	 * removed and re-added; so we have to fiddle with the expansion state
	 */
	void addNode() {
		TestModel selectedTestModel = this.selectedTestModel();
		if (selectedTestModel != null) {
			String name = this.getName();
			// save the expansion state and restore it after the add
			Collection<TreePath> paths = this.expandedPaths();

			selectedTestModel.addChild(name);

			this.expandPaths(paths);
			this.setSelectedNode(this.selectedNode().childNamed(name));
		}
	}

	// ********** remove **********
	private JButton buildRemoveButton() {
		return new JButton(this.buildRemoveAction());
	}

	private Action buildRemoveAction() {
		Action action = new AbstractAction("remove") {
			public void actionPerformed(ActionEvent event) {
				TreeModelAdapterUITest.this.removeNode();
			}
		};
		action.setEnabled(true);
		return action;
	}

	/**
	 * we need to figure out which node to select after
	 * the selected node is deleted
	 */
	void removeNode() {
		TestModel selectedTestModel = this.selectedTestModel();
		// do not allow the root to be removed
		if ((selectedTestModel != null) && (selectedTestModel != this.root())) {
			// save the parent and index, so we can select another, nearby, node
			// once the selected node is removed
			TestNode parentNode = (TestNode) this.selectedNode().parent();
			int childIndex = parentNode.indexOfChild(this.selectedNode());

			selectedTestModel.getParent().removeChild(selectedTestModel);

			int childrenSize = parentNode.childrenSize();
			if (childIndex < childrenSize) {
				// select the child that moved up and replaced the just-deleted child
				this.setSelectedNode((TestNode) parentNode.child(childIndex));
			} else {
				if (childrenSize == 0) {
					// if there are no more children, select the parent
					this.setSelectedNode(parentNode);
				} else {
					// if the child at the bottom of the list was deleted, select the next child up
					this.setSelectedNode((TestNode) parentNode.child(childIndex - 1));
				}
			}
		}
	}

	// ********** rename **********
	private JButton buildRenameButton() {
		return new JButton(this.buildRenameAction());
	}

	private Action buildRenameAction() {
		Action action = new AbstractAction("rename") {
			public void actionPerformed(ActionEvent event) {
				TreeModelAdapterUITest.this.renameNode();
			}
		};
		action.setEnabled(true);
		return action;
	}

	/**
	 * renaming causes the tree to be sorted and nodes to be
	 * removed and re-added; so we have to fiddle with the expansion state
	 */
	void renameNode() {
		TestModel selectedTestModel = this.selectedTestModel();
		if (selectedTestModel != null) {
			// save the node and re-select it after the rename
			TestNode selectedNode = this.selectedNode();
			// save the expansion state and restore it after the rename
			Collection<TreePath> paths = this.expandedPaths();

			selectedTestModel.setName(this.getName());

			this.expandPaths(paths);
			this.setSelectedNode(selectedNode);
		}
	}

	// ********** clear children **********
	private JButton buildClearChildrenButton() {
		return new JButton(this.buildClearChildrenAction());
	}

	private Action buildClearChildrenAction() {
		Action action = new AbstractAction("clear children") {
			public void actionPerformed(ActionEvent event) {
				TreeModelAdapterUITest.this.clearChildren();
			}
		};
		action.setEnabled(true);
		return action;
	}

	/**
	 * nothing special, we just want to test #fireCollectionChanged(String)
	 */
	void clearChildren() {
		TestModel selectedTestModel = this.selectedTestModel();
		if (selectedTestModel != null) {
			selectedTestModel.clearChildren();
		}
	}

	// ********** reset **********
	private JButton buildResetButton() {
		return new JButton(this.buildResetAction());
	}

	private Action buildResetAction() {
		Action action = new AbstractAction("reset") {
			public void actionPerformed(ActionEvent event) {
				TreeModelAdapterUITest.this.reset();
			}
		};
		action.setEnabled(true);
		return action;
	}

	/**
	 * test the adapter's root node holder;
	 * toggle between sorted and unsorted lists
	 */
	void reset() {
		this.sorted = ! this.sorted;
		if (this.sorted) {
			this.rootNodeHolder.setValue(this.buildSortedRootNode());
		} else {
			this.rootNodeHolder.setValue(this.buildUnsortedRootNode());
		}
		this.tree.expandPath(new TreePath(this.rootNode()));
	}

}
