/*******************************************************************************
 * Copyright (C) 2007-2009 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.workbench.ui.workflowexplorer;

import static java.awt.BorderLayout.CENTER;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.SwingUtilities.invokeLater;
import static javax.swing.SwingUtilities.isEventDispatchThread;
import static net.sf.taverna.t2.lang.ui.ShadedLabel.GREEN;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.inputIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.minusIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.outputIcon;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.plusIcon;
import static net.sf.taverna.t2.workbench.ui.workflowexplorer.WorkflowExplorerTreeModel.INPUTS;
import static net.sf.taverna.t2.workbench.ui.workflowexplorer.WorkflowExplorerTreeModel.OUTPUTS;
import static net.sf.taverna.t2.workbench.ui.workflowexplorer.WorkflowExplorerTreeModel.PROCESSORS;
import static net.sf.taverna.t2.workbench.ui.workflowexplorer.WorkflowExplorerTreeModel.getPathForObject;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.border.EtchedBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import net.sf.taverna.t2.lang.observer.Observable;
import net.sf.taverna.t2.lang.observer.Observer;
import net.sf.taverna.t2.lang.observer.SwingAwareObserver;
import net.sf.taverna.t2.lang.ui.ShadedLabel;
import net.sf.taverna.t2.ui.menu.MenuManager;
import net.sf.taverna.t2.workbench.activityicons.ActivityIconManager;
import net.sf.taverna.t2.workbench.design.actions.AddDataflowInputAction;
import net.sf.taverna.t2.workbench.design.actions.AddDataflowOutputAction;
import net.sf.taverna.t2.workbench.edits.EditManager;
import net.sf.taverna.t2.workbench.edits.EditManager.AbstractDataflowEditEvent;
import net.sf.taverna.t2.workbench.edits.EditManager.EditManagerEvent;
import net.sf.taverna.t2.workbench.file.FileManager;
import net.sf.taverna.t2.workbench.file.events.ClosedDataflowEvent;
import net.sf.taverna.t2.workbench.file.events.FileManagerEvent;
import net.sf.taverna.t2.workbench.report.ReportManager;
import net.sf.taverna.t2.workbench.selection.DataflowSelectionModel;
import net.sf.taverna.t2.workbench.selection.SelectionManager;
import net.sf.taverna.t2.workbench.selection.events.DataflowSelectionMessage;
import net.sf.taverna.t2.workbench.selection.events.SelectionManagerEvent;
import net.sf.taverna.t2.workbench.selection.events.WorkflowBundleSelectionEvent;
import net.sf.taverna.t2.workbench.selection.events.WorkflowSelectionEvent;
import net.sf.taverna.t2.workbench.ui.dndhandler.ServiceTransferHandler;
import net.sf.taverna.t2.workbench.ui.zaria.UIComponentSPI;
import uk.org.taverna.commons.services.ServiceRegistry;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.core.Workflow;

/**
 * Workflow Explorer provides a context sensitive tree view of a workflow (showing its inputs,
 * outputs, processors, datalinks, etc.). Selection of a node in the Model Explorer tree and a
 * right-click leads to context sensitive options appearing in a pop-up menu.
 *
 * @author Alex Nenadic
 * @author David Withers
 */
@SuppressWarnings("serial")
public class WorkflowExplorer extends JPanel implements UIComponentSPI {
	/** Purple colour for shaded label on pop up menus */
	public static final Color PURPLISH = new Color(0x8070ff);
	/** Manager of all opened workflows */
	private SelectionManager selectionManager;
	private MenuManager menuManager;
	/** Currently selected workflow (to be displayed in the Workflow Explorer). */
	private Workflow workflow;
	/** Map of trees for all opened workflows. */
	private Map<Workflow, JTree> openedWorkflowsTrees = new HashMap<>();
	/** Tree representation of the currently selected workflow. */
	private JTree wfTree;
	/**
	 * Current workflow's selection model event observer - telling us what is
	 * the currently selected object in the current workflow.
	 */
	private Observer<DataflowSelectionMessage> workflowSelectionListener = new DataflowSelectionListener();
	/** Scroll pane containing the workflow tree. */
	private JScrollPane scrollPane;
	protected FileManager fileManager;
	protected FileManagerObserver fileManagerObserver = new FileManagerObserver();
	protected EditManager editManager;
	protected EditManagerObserver editManagerObserver = new EditManagerObserver();

	private final ReportManager reportManager;
	private final ActivityIconManager activityIconManager;
	private final ServiceRegistry serviceRegistry;

	@Override
	public ImageIcon getIcon() {
		return null;
	}

	@Override
	public String getName() {
		return "Workflow Explorer";
	}

	@Override
	public void onDisplay() {
	}

	@Override
	public void onDispose() {
	}

	/**
	 * Constructs the Workflow Explorer.
	 */
	public WorkflowExplorer(EditManager editManager, FileManager fileManager,
			MenuManager menuManager, ReportManager reportManager,
			SelectionManager selectionManager,
			ActivityIconManager activityIconManager, ServiceRegistry serviceRegistry) {
		this.editManager = editManager;
		this.fileManager = fileManager;
		this.menuManager = menuManager;
		this.reportManager = reportManager;
		this.selectionManager = selectionManager;
		this.activityIconManager = activityIconManager;
		this.serviceRegistry = serviceRegistry;
		this.setTransferHandler(new ServiceTransferHandler(editManager, menuManager,
				selectionManager, serviceRegistry));

		/*
		 * Create a tree that will represent a view over the current workflow.
		 * Initially, there is no workflow opened, so we create an empty tree,
		 * but immediately after all visual components of the Workbench are
		 * created (including Workflow Explorer) a new empty workflow is
		 * created, which is represented with a NON-empty JTree with four nodes
		 * (Inputs, Outputs, Processors, and Data links) that themselves have no
		 * children.
		 */
		assignWfTree(new JTree(new DefaultMutableTreeNode("No workflow open")));

		// Start observing workflow switching or closing events on File Manager
		fileManager.addObserver(fileManagerObserver);
		selectionManager.addObserver(new SelectionManagerObserver());

		/*
		 * Start observing events on Edit Manager when current workflow is
		 * edited (e.g. a node added, deleted or updated)
		 */
		editManager.addObserver(editManagerObserver);

		// Draw visual components
		initComponents();
	}

	private void assignWfTree(JTree tree) {
		wfTree = tree;
		wfTree.setTransferHandler(new ServiceTransferHandler(editManager,
				menuManager, selectionManager, serviceRegistry));
	}

	/**
	 * Lays out the swing components.
	 */
	public void initComponents() {
		setLayout(new BorderLayout());

		// Workflow tree scroll pane
		scrollPane = new JScrollPane(wfTree, VERTICAL_SCROLLBAR_AS_NEEDED,
				HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scrollPane.setBorder(new EtchedBorder());

		/*
		 * Title - not needed as it is now located on a tab labelled 'Workflow
		 * Explorer'
		 */
		// JLabel wfExplorerLabel = new JLabel("Workflow Explorer");
		// wfExplorerLabel.setMinimumSize(new Dimension(0, 0)); // so that it
		// can shrink completely
		// wfExplorerLabel.setBorder(new EmptyBorder(0, 0, 5, 0));

		// add(wfExplorerLabel, BorderLayout.NORTH);
		add(scrollPane, CENTER);
	}

	/**
	 * Gets called when a workflow is opened or a new (empty) one created.
	 */
	public void createWorkflowTree(Workflow df) {
		// Set the current workflow
		workflow = df;

		// Create a new tree and populate it with the workflow's data
		assignWfTree(createTreeFromWorkflow(workflow));

		// Add the new tree to the list of opened workflow trees
		openedWorkflowsTrees.put(workflow, wfTree);

		// Expand the tree
		expandAll(wfTree);

		Runnable expandWorkflowTreeRunnable = new Runnable() {
			@Override
			public void run() {
				// Repaint the scroll pane containing the tree
				scrollPane.setViewportView(wfTree);
				scrollPane.revalidate();
				scrollPane.repaint();
			}
		};

		if (isEventDispatchThread()) {
			expandWorkflowTreeRunnable.run();
		} else {
			invokeLater(expandWorkflowTreeRunnable);
		}
	}

	/**
	 * Switch the current workflow to a previously opened workflow.
	 */
	private void switchWorkflowTree(Workflow workflow) {
		// Set the current workflow to the one we have switched to
		this.workflow = workflow;
		// Select the node(s) that should be selected (do this after
		// assigning the tree to the scroll pane)
		setSelectedNodes(wfTree, workflow);
		// Set the tree for the current workflow
		wfTree = openedWorkflowsTrees.get(workflow);

		// Repaint the scroll pane containing the tree
		scrollPane.setViewportView(wfTree);

		// Repaint the scroll pane containing the tree
		scrollPane.revalidate();
		scrollPane.repaint();
	}

	/**
	 * Gets called when the current workflow is edited, or when a parent
	 * workflow of a nested workflow is edited due to saved changes in the
	 * nested workflow (which is the current workflow).
	 */
	public void updateWorkflowTree(Workflow df) {
		// Create the new tree from the updated workflow
		JTree newTree = createTreeFromWorkflow(df);

		// Get the old workflow tree
		JTree oldTree = openedWorkflowsTrees.get(df);

		// Update the tree in the list of opened workflow trees
		openedWorkflowsTrees.put(df, newTree);

		/*
		 * Update the new tree's expansion state based on the old tree i.e. all
		 * nodes in the old tree that have been expanded/collapsed should also
		 * be expanded/collapsed in the new tree (unless an expanded node has
		 * been removed)
		 */
		copyExpansionState(oldTree, (DefaultMutableTreeNode) oldTree.getModel()
				.getRoot(), newTree, (DefaultMutableTreeNode) newTree
				.getModel().getRoot());

		/*
		 * Get the current workflow from FileManager.
		 * 
		 * If current workflow is different from the workflow df passed through
		 * this method then this means that the current workflow is the nested
		 * workflow (whose parent is workflow df) and that the nested workflow
		 * has been previously edited and then saved which triggered the update
		 * on the parent workflow df.
		 * 
		 * In this case, we should just update the parent workflow tree but keep
		 * the nested workflow as the current workflow. On the other hand, if
		 * the current workflow is the same as workflow df then this is just an
		 * update to the current workflow so we have to update and redraw the
		 * workflow tree.
		 */
		if (df.equals(selectionManager.getSelectedWorkflow())) {
			// this was an update on the current workflow

			// Update the current workflow
			workflow = df; // although they are the same anyway

			// Set the current tree to the new tree
			assignWfTree(newTree);

			// Repaint the scroll pane containing the tree
			scrollPane.setViewportView(wfTree);

			// Select the node(s) that should be selected (do this after
			// assigning the tree to the scroll pane)
			setSelectedNodes(wfTree, workflow);

			scrollPane.revalidate();
			scrollPane.repaint();
		} else {
			/*
			 * just update the parent tree (already done above) but do not
			 * switch the trees. Do not revalidate/repaint as we are not
			 * switching to the new tree but keep showing the nested wf that has
			 * not changed.
			 */
		}
	}

	/**
	 * Copies the expansion state of the old tree starting from the given node
	 * in the old tree to the new tree starting from the new node. We normally
	 * use it starting from the root nodes of both trees when an update has
	 * happened to the tree and we want to preserve the expansion state in the
	 * updated tree.
	 */
	@SuppressWarnings("unchecked")
	private void copyExpansionState(JTree oldTree,
			DefaultMutableTreeNode oldNode, JTree newTree,
			DefaultMutableTreeNode newNode) {
		boolean expandParentNode = false;

		/*
		 * Do the children on the node first (so we can set the node's children
		 * to be expanded even if the node itself is collapsed)
		 */
		Enumeration<DefaultMutableTreeNode> children = newNode.children();
		while (children.hasMoreElements()) {
			DefaultMutableTreeNode newChild = children.nextElement();
			// Find the corresponding node in the old tree, if any
			DefaultMutableTreeNode oldChild = findChildWithUserObject(oldNode,
					newChild.getUserObject());

			if (oldChild != null) // corresponding node found in the old tree
				// Recursively do the same for each child
				copyExpansionState(oldTree, oldChild, newTree, newChild);
			else
				/*
				 * corresponding node not found in the old tree - a new node has
				 * been added or a node had been edited in the new tree so make
				 * that node visible now by expanding the parent node
				 */
				expandParentNode = true;
		}

		// Now do the node
		if (expandParentNode) {
			/*
			 * Order matters - we first check if a new child was inserted to
			 * this node (that means that the old node might have been a leaf
			 * before)
			 */
			int row = newTree.getRowForPath(new TreePath(newNode.getPath()));
			newTree.expandRow(row);
		} else if (oldNode.isLeaf()) {
			/*
			 * if it is a leaf - expand/collapse does not work, so use
			 * isVisible/makeVisible
			 */
			if (oldTree.isVisible(new TreePath(oldNode.getPath())))
				newTree.makeVisible(new TreePath(newNode.getPath()));
		} else if (oldTree.isExpanded(new TreePath(oldNode.getPath()))) {
			int row = newTree.getRowForPath(new TreePath(newNode.getPath()));
			newTree.expandRow(row);
		} else { // node was collapsed
			int row = newTree.getRowForPath(new TreePath(newNode.getPath()));
			newTree.collapseRow(row);
		}
	}

	/**
	 * Returns a child of a given node that contains the same user object as the
	 * one passed to the method.
	 */
	@SuppressWarnings("unchecked")
	private DefaultMutableTreeNode findChildWithUserObject(
			DefaultMutableTreeNode node, Object userObject) {
		Enumeration<DefaultMutableTreeNode> children = node.children();
		while (children.hasMoreElements()) {
			DefaultMutableTreeNode child = children.nextElement();
			if (child.getUserObject().equals(userObject))
				return child;
		}
		return null;
	}

	private JTree createTreeFromWorkflow(final Workflow workflow) {
		// Create a new tree and populate it with the workflow's data
		final JTree tree = new JTree(new WorkflowExplorerTreeModel(workflow));
		tree.setRowHeight(18);
		tree.setLargeModel(true);
		tree.setEditable(false);
		tree.setExpandsSelectedPaths(true);
		tree.setDragEnabled(false);
		tree.setScrollsOnExpand(false);
		tree.setCellRenderer(new WorkflowExplorerTreeCellRenderer(workflow,
				reportManager, activityIconManager));
		// tree.setSelectionModel(new WorkflowExplorerTreeSelectionModel());
		tree.addTreeSelectionListener(new TreeSelectionListener() {
			@Override
			public void valueChanged(TreeSelectionEvent e) {
				TreePath selectionPath = e.getNewLeadSelectionPath();
				if (selectionPath != null) {
					final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectionPath
							.getLastPathComponent();

					DataflowSelectionModel selectionModel = selectionManager
							.getDataflowSelectionModel(workflow.getParent());

					/*
					 * If the node that was clicked on was inputs, outputs,
					 * services, data links, control links or merges in the main
					 * workflow then just make it selected and clear the
					 * selection model (as these are just containers for the
					 * 'real' workflow components).
					 */
					if ((selectedNode.getUserObject() instanceof String)
							&& (selectionPath.getPathCount() == 2)) {
						selectionModel.clearSelection();
						tree.getSelectionModel().setSelectionPath(selectionPath);
					} else {
						/*
						 * a 'real' workflow component or the 'whole' workflow
						 * (i.e. the tree root) was clicked on
						 */

						/*
						 * We want to disable selection of any nested workflow
						 * components (apart from input and output ports in the
						 * wrapping DataflowActivity)
						 */
						TreePath path = getPathForObject(selectedNode
								.getUserObject(), (DefaultMutableTreeNode) tree
								.getModel().getRoot());

						/*
						 * The getPathForObject() method will return null in a
						 * node is inside a nested workflow and should not be
						 * selected
						 */
						if (path == null)
							// Just return
							return;

						/*
						 * Add it to selection model so it is also selected
						 * on the graph as well that listens to the
						 * selection model
						 */
						selectionModel.addSelection(selectedNode.getUserObject());
					}
				}
			}
		});

		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent evt) {
				handleMouseEvent(evt);
			}

			@Override
			public void mouseReleased(MouseEvent evt) {
				handleMouseEvent(evt);
			}

			private void handleMouseEvent(MouseEvent evt) {
				if (!evt.isPopupTrigger())
					return;
				// Discover the tree row that was clicked on
				int selRow = tree.getRowForLocation(evt.getX(), evt.getY());
				if (selRow == -1)
					return;

				// Get the selection path for the row
				TreePath selectionPath = tree.getPathForLocation(evt.getX(),
						evt.getY());
				if (selectionPath == null)
					return;

				// Get the selected node
				final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectionPath
						.getLastPathComponent();

				/*
				 * For both left and right click - add the workflow object to
				 * selection model. This will cause the node to become selected
				 * (from the selection listener's code)
				 */
				DataflowSelectionModel selectionModel = selectionManager
						.getDataflowSelectionModel(workflow.getParent());

				/*
				 * If the node that was clicked on was inputs, outputs,
				 * services, data links, control links or merges in the main
				 * workflow then just make it selected and clear the selection
				 * model (as these are just containers for the 'real' workflow
				 * components).
				 */
				if ((selectedNode.getUserObject() instanceof String)
						&& selectionPath.getPathCount() == 2) {
					selectionModel.clearSelection();
					tree.getSelectionModel().setSelectionPath(selectionPath);

					Object userObject = selectedNode.getUserObject();
					if (userObject.equals(PROCESSORS)) {
						JPopupMenu menu = new JPopupMenu();
						menu.add(new ShadedLabel("Tree", PURPLISH));
						menu.add(new JMenuItem(new AbstractAction("Expand",
								plusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								expandAscendants(tree, selectedNode);
							}
						}));
						menu.add(new JMenuItem(new AbstractAction("Collapse",
								minusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								collapseAscendants(tree, selectedNode);
							}
						}));
						menu.show(evt.getComponent(), evt.getX(), evt.getY());
					} else if (userObject.equals(INPUTS)) {
						JPopupMenu menu = new JPopupMenu();
						menu.add(new ShadedLabel("Workflow input ports", GREEN));
						menu.add(new JMenuItem(new AbstractAction(
								"Add workflow input port", inputIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								new AddDataflowInputAction(
										(Workflow) ((DefaultMutableTreeNode) tree
												.getModel().getRoot())
												.getUserObject(), wfTree
												.getParent(), editManager,
										selectionManager).actionPerformed(evt);
							}
						}));
						menu.show(evt.getComponent(), evt.getX(), evt.getY());
					} else if (userObject.equals(OUTPUTS)) {
						JPopupMenu menu = new JPopupMenu();
						menu.add(new ShadedLabel("Workflow output ports", GREEN));
						menu.add(new JMenuItem(new AbstractAction(
								"Add workflow output port", outputIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								new AddDataflowOutputAction(
										(Workflow) ((DefaultMutableTreeNode) tree
												.getModel().getRoot())
												.getUserObject(), wfTree
												.getParent(), editManager,
										selectionManager).actionPerformed(evt);
							}
						}));
						menu.show(evt.getComponent(), evt.getX(), evt.getY());
					}
				} else {
					/*
					 * a 'real' workflow component or the 'whole' workflow (i.e.
					 * the tree root) was clicked on
					 */

					/*
					 * We want to disable selection of any nested workflow
					 * components (apart from input and output ports in the
					 * wrapping DataflowActivity)
					 */
					TreePath path = getPathForObject(
							selectedNode.getUserObject(),
							(DefaultMutableTreeNode) tree.getModel().getRoot());

					/*
					 * The getPathForObject() method will return null in a node
					 * is inside a nested workflow and should not be selected
					 */
					if (path == null)
						// Just return
						return;

					/*
					 * Add it to selection model so it is also selected on the
					 * graph as well that listens to the selection model
					 */
					selectionModel.addSelection(selectedNode.getUserObject());

					// Show a contextual pop-up menu
					JPopupMenu menu = menuManager.createContextMenu(workflow,
							selectedNode.getUserObject(), wfTree.getParent());
					if (menu == null)
						menu = new JPopupMenu();

					if (selectedNode.getUserObject() instanceof Workflow) {
						menu.add(new ShadedLabel("Tree", PURPLISH));
						// Action to expand the whole tree
						menu.add(new JMenuItem(new AbstractAction("Expand all",
								plusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								expandAll(tree);
							}
						}));
						// Action to collapse the whole tree
						menu.add(new JMenuItem(new AbstractAction(
								"Collapse all", minusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								collapseAll(tree);
							}
						}));
					}

					menu.show(evt.getComponent(), evt.getX(), evt.getY());
				}
			}
		});

		return tree;
	}

	/**
	 * Sets the currently selected node(s) based on the workflow selection
	 * model, i.e. the node(s) currently selected in the workflow graph view
	 * also become selected in the tree view.
	 */
	private void setSelectedNodes(JTree tree, Workflow wf) {
		DataflowSelectionModel selectionModel = selectionManager
				.getDataflowSelectionModel(wf.getParent());

		// List of all selected objects in the graph view
		Set<Object> selection = selectionModel.getSelection();
		if (selection.isEmpty())
			return;

		// Selection path(s) - can be multiple if more objects are selected
		int i = selection.size();
		TreePath[] paths = new TreePath[i];

		for (Object selected : selection) {
			TreePath path = WorkflowExplorerTreeModel.getPathForObject(
					selected, (DefaultMutableTreeNode) tree.getModel()
							.getRoot());
			paths[--i] = path;
		}
		tree.setSelectionPaths(paths);
		tree.scrollPathToVisible(paths[0]);
	}

	/**
	 * Expands all nodes in the tree that have children.
	 */
	private void expandAll(JTree tree) {
		int row = 0;
		while (row < tree.getRowCount()) {
			tree.expandRow(row);
			row++;
		}
	}

	/**
	 * Collapses all but the root node in the tree that have children.
	 */
	private void collapseAll(JTree tree) {
		int row = 1;
		while (row < tree.getRowCount()) {
			tree.collapseRow(row);
			row++;
		}
	}

	/**
	 * Expands all ascendants of a node in the tree.
	 */
	private void expandAscendants(JTree tree, DefaultMutableTreeNode node) {
		@SuppressWarnings("unchecked")
		Enumeration<DefaultMutableTreeNode> children = node.children();
		while (children.hasMoreElements()) {
			DefaultMutableTreeNode child = children.nextElement();
			if (child.isLeaf())
				tree.makeVisible(new TreePath(child.getPath()));
			else
				expandAscendants(tree, child);
		}
	}

	/**
	 * Collapses all direct ascendants of a node in the tree.
	 */
	private void collapseAscendants(JTree tree, DefaultMutableTreeNode node) {
		@SuppressWarnings("unchecked")
		Enumeration<DefaultMutableTreeNode> children = node.children();
		while (children.hasMoreElements()) {
			DefaultMutableTreeNode child = children.nextElement();
			int row = tree.getRowForPath(new TreePath(child.getPath()));
			tree.collapseRow(row);
		}
	}

	/**
	 * Update workflow explorer when current dataflow changes or closes.
	 */
	public class FileManagerObserver extends
			SwingAwareObserver<FileManagerEvent> {
		@Override
		public void notifySwing(Observable<FileManagerEvent> sender,
				FileManagerEvent message) {
			if (message instanceof ClosedDataflowEvent) {
				/*
				 * Remove the closed workflow tree from the map of opened
				 * workflow trees
				 */
				openedWorkflowsTrees.remove(((ClosedDataflowEvent) message)
						.getDataflow());
			}
		}
	}

	private final class SelectionManagerObserver extends
			SwingAwareObserver<SelectionManagerEvent> {
		@Override
		public void notifySwing(Observable<SelectionManagerEvent> sender,
				SelectionManagerEvent message) {
			if (message instanceof WorkflowBundleSelectionEvent) {
				WorkflowBundleSelectionEvent workflowBundleSelectionEvent = (WorkflowBundleSelectionEvent) message;
				WorkflowBundle oldWorkflowBundle = workflowBundleSelectionEvent
						.getPreviouslySelectedWorkflowBundle();
				WorkflowBundle newWorkflowBundle = workflowBundleSelectionEvent
						.getSelectedWorkflowBundle();
				Workflow selectedWorkflow = selectionManager
						.getSelectedWorkflow();

				/*
				 * Remove the workflow selection model listener from the
				 * previous (if any) and add to the new workflow (if any)
				 */
				if (oldWorkflowBundle != null)
					selectionManager.getDataflowSelectionModel(
							oldWorkflowBundle).removeObserver(
							workflowSelectionListener);
				if (newWorkflowBundle != null)
					selectionManager.getDataflowSelectionModel(
							newWorkflowBundle).addObserver(
							workflowSelectionListener);

				// If the workflow tree has already been created switch to it
				if (openedWorkflowsTrees.containsKey(selectedWorkflow))
					switchWorkflowTree(selectedWorkflow);
				else // otherwise create a new tree for the workflow
					createWorkflowTree(selectedWorkflow);
			} else if (message instanceof WorkflowSelectionEvent) {
				WorkflowSelectionEvent workflowSelectionEvent = (WorkflowSelectionEvent) message;
				Workflow newWorkflow = workflowSelectionEvent.getSelectedWorkflow();

				// If the workflow tree has already been created switch to it
				if (openedWorkflowsTrees.containsKey(newWorkflow))
					switchWorkflowTree(newWorkflow);
				else // otherwise create a new tree for the workflow
					createWorkflowTree(newWorkflow);
			}
		}
	}

	/**
	 * Update workflow tree on edits to the workflow. Gets called when either
	 * current workflow is edited or when current workflow is a nested workflow
	 * that had been edited and then saved which will trigger update to the
	 * parent workflow which is not the current workflow.
	 */
	public class EditManagerObserver extends
			SwingAwareObserver<EditManagerEvent> {
		@Override
		public void notifySwing(Observable<EditManagerEvent> sender,
				final EditManagerEvent message) {
			if (message instanceof AbstractDataflowEditEvent) {
				WorkflowBundle workflowBundle = ((AbstractDataflowEditEvent) message)
						.getDataFlow();
				// Update the workflow trees to reflect the changes
				for (Workflow workflow : workflowBundle.getWorkflows())
					if (openedWorkflowsTrees.containsKey(workflow))
						updateWorkflowTree(workflow);
			}
		}
	}

	/**
	 * Observes events on workflow Selection Manager, i.e. when a workflow node
	 * is selected in the graph view.
	 */
	private final class DataflowSelectionListener extends
			SwingAwareObserver<DataflowSelectionMessage> {
		@Override
		public void notifySwing(Observable<DataflowSelectionMessage> sender,
				DataflowSelectionMessage message) {
			setSelectedNodes(wfTree, workflow);
			scrollPane.revalidate();
			scrollPane.repaint();
		}
	}
}
