package net.sf.taverna.t2.workbench.file.importworkflow.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;

import net.sf.taverna.t2.activities.dataflow.servicedescriptions.DataflowTemplateService;
import net.sf.taverna.t2.ui.menu.MenuManager;
import net.sf.taverna.t2.workbench.MainWindow;
import net.sf.taverna.t2.workbench.configuration.colour.ColourManager;
import net.sf.taverna.t2.workbench.configuration.workbench.WorkbenchConfiguration;
import net.sf.taverna.t2.workbench.edits.CompoundEdit;
import net.sf.taverna.t2.workbench.edits.Edit;
import net.sf.taverna.t2.workbench.edits.EditException;
import net.sf.taverna.t2.workbench.edits.EditManager;
import net.sf.taverna.t2.workbench.file.DataflowInfo;
import net.sf.taverna.t2.workbench.file.FileManager;
import net.sf.taverna.t2.workbench.file.exceptions.OpenException;
import net.sf.taverna.t2.workbench.file.importworkflow.DataflowMerger;
import net.sf.taverna.t2.workbench.file.importworkflow.MergeException;
import net.sf.taverna.t2.workbench.file.importworkflow.actions.OpenSourceWorkflowAction;
import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;
import net.sf.taverna.t2.workbench.models.graph.svg.SVGGraphController;
import net.sf.taverna.t2.workbench.selection.SelectionManager;
import net.sf.taverna.t2.workflow.edits.AddChildEdit;
import net.sf.taverna.t2.workflow.edits.AddProcessorEdit;

import org.apache.batik.swing.JSVGCanvas;
import org.apache.log4j.Logger;

import uk.org.taverna.scufl2.api.activity.Activity;
import uk.org.taverna.scufl2.api.common.Scufl2Tools;
import uk.org.taverna.scufl2.api.configurations.Configuration;
import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.core.Processor;
import uk.org.taverna.scufl2.api.core.Workflow;
import uk.org.taverna.scufl2.api.iterationstrategy.CrossProduct;
import uk.org.taverna.scufl2.api.port.InputActivityPort;
import uk.org.taverna.scufl2.api.port.InputProcessorPort;
import uk.org.taverna.scufl2.api.port.InputWorkflowPort;
import uk.org.taverna.scufl2.api.port.OutputActivityPort;
import uk.org.taverna.scufl2.api.port.OutputProcessorPort;
import uk.org.taverna.scufl2.api.port.OutputWorkflowPort;
import uk.org.taverna.scufl2.api.profiles.ProcessorBinding;
import uk.org.taverna.scufl2.api.profiles.ProcessorInputPortBinding;
import uk.org.taverna.scufl2.api.profiles.ProcessorOutputPortBinding;
import uk.org.taverna.scufl2.api.profiles.Profile;

import com.fasterxml.jackson.databind.node.ObjectNode;

@SuppressWarnings("serial")
public class ImportWorkflowWizard extends HelpEnabledDialog {

	private static Logger logger = Logger.getLogger(ImportWorkflowWizard.class);

	private Scufl2Tools scufl2Tools = new Scufl2Tools();

	protected BrowseFileOnClick browseFileOnClick = new BrowseFileOnClick();
	protected JButton buttonBrowse;
	protected JComboBox chooseDataflow;
	protected DataflowOpenerThread dataflowOpenerThread;

	private WorkflowBundle destinationWorkflowBundle;
	private Workflow destinationWorkflow;
	private Profile destinationProfile;
	private Workflow sourceWorkflow;

	protected JTextField fieldFile;

	protected JTextField fieldUrl;
	protected boolean mergeEnabled = true;
	protected boolean nestedEnabled = true;
	protected JSVGCanvas previewSource = new JSVGCanvas(null, false, false);
	protected JSVGCanvas previewDestination = new JSVGCanvas(null, false, false);
	protected JTextField prefixField;
	protected JRadioButton radioFile;
	protected JRadioButton radioNew;
	protected JRadioButton radioOpened;
	protected JRadioButton radioUrl;
	protected ButtonGroup sourceSelection;
	protected ActionListener updateChosenListener = new UpdateChosenListener();
	protected Thread updatePreviewsThread;
	protected Component sourceSelectionPanel;
	protected JLabel prefixLabel;
	protected JLabel prefixHelp;
//	protected JPanel destinationSelectionPanel;
//	protected ButtonGroup destinationSelection;
//	protected JRadioButton radioNewDestination;
//	protected JRadioButton radioOpenDestination;
//	protected JComboBox destinationAlreadyOpen;
	protected JPanel introductionPanel;
	protected ButtonGroup actionSelection;
	protected JRadioButton actionNested;
	protected JRadioButton actionMerge;
	protected JRadioButton radioCustomSource;
	protected JRadioButton radioCustomDestination;

	private final EditManager editManager;
	private final FileManager fileManager;
	private final MenuManager menuManager;
	private final ColourManager colourManager;
	private final WorkbenchConfiguration workbenchConfiguration;
	private final SelectionManager selectionManager;

	private WorkflowBundle customSourceDataFlow = null;
//	private Workflow customDestinationDataflow = null;
	private String customSourceName = "";
//	private String customDestinationName = "";

	private boolean sourceEnabled = true;
//	private boolean destinationEnabled = true;
	private Activity insertedActivity;

	public ImportWorkflowWizard(Frame parentFrame, EditManager editManager,
			FileManager fileManager, MenuManager menuManager, ColourManager colourManager,
			WorkbenchConfiguration workbenchConfiguration, SelectionManager selectionManager) {
		super(parentFrame, "Import workflow", true, null);
		this.selectionManager = selectionManager;
		destinationWorkflow = selectionManager.getSelectedWorkflow();
		destinationProfile = selectionManager.getSelectedProfile();
		destinationWorkflowBundle = selectionManager.getSelectedWorkflowBundle();

		this.editManager = editManager;
		this.fileManager = fileManager;
		this.menuManager = menuManager;
		this.colourManager = colourManager;
		this.workbenchConfiguration = workbenchConfiguration;

		setSize(600, 600);
		add(makeContentPane(), BorderLayout.CENTER);
		// Add some space
		add(new JPanel(), BorderLayout.WEST);
		add(new JPanel(), BorderLayout.NORTH);
		add(new JPanel(), BorderLayout.SOUTH);
		add(new JPanel(), BorderLayout.EAST);
		findChosenDataflow(this, true);
		updateAll();
	}

	public void setMergeEnabled(boolean importEnabled) {
		this.mergeEnabled = importEnabled;
		updateAll();
	}

	public void setNestedEnabled(boolean nestedEnabled) {
		this.nestedEnabled = nestedEnabled;
		updateAll();
	}

	/**
	 * Silly workaround to avoid "Cannot call invokeAndWait from the event dispatcher thread"
	 * exception.
	 *
	 * @param runnable
	 */
	public static void invokeAndWait(Runnable runnable) {
		if (SwingUtilities.isEventDispatchThread()) {
			runnable.run();
			return;
		}
		try {
			SwingUtilities.invokeAndWait(runnable);
		} catch (InterruptedException ex) {
			// logger.warn("Runnable " + runnable + " was interrupted " + runnable, ex);
		} catch (InvocationTargetException e) {
			logger.warn("Can't invoke " + runnable, e);
		}
	}

	protected Component makeWorkflowImage() {
		JPanel workflowImages = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridy = 0;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.weighty = 0.1;

		gbc.weightx = 0.1;
		workflowImages.add(new JPanel(), gbc);// filler

		gbc.weightx = 0.0;
		previewSource.setBackground(workflowImages.getBackground());
		workflowImages.add(previewSource, gbc);

		JLabel arrow = new JLabel("\u2192");
		arrow.setFont(arrow.getFont().deriveFont(48f));
		workflowImages.add(arrow, gbc);

		previewDestination.setBackground(workflowImages.getBackground());
		workflowImages.add(previewDestination, gbc);

		gbc.weightx = 0.1;
		workflowImages.add(new JPanel(), gbc);
		gbc.weightx = 0.0;

		return workflowImages;
	}

	protected void updateAll() {
		updatePreviews(); // will go in separate thread anyway, do it first
		updateHeader();
		updateSourceSection();
//		updateDestinationSection();
		updateFooter();
	}

//	protected void updateDestinationSection() {
//
//		radioNewDestination.setVisible(false);
//
//		radioCustomDestination.setText(customDestinationName);
//		radioCustomDestination.setVisible(customDestinationDataflow != null);
//
//		// radioNewDestination.setVisible(nestedEnabled);
//		// radioNewDestination.setEnabled(actionNested.isSelected());
//
//		destinationSelectionPanel.setVisible(destinationEnabled);
//
//	}

	protected synchronized void updatePreviews() {
		if (updatePreviewsThread != null && updatePreviewsThread.isAlive()) {
			updatePreviewsThread.interrupt();
		}
		updatePreviewsThread = new UpdatePreviewsThread();
		updatePreviewsThread.start();
	}

	protected void updateDestinationPreview() {
		updateWorkflowGraphic(previewDestination, destinationWorkflow, destinationProfile);
	}

	protected void updateSourcePreview() {
		Profile sourceProfile = null;
		if (sourceWorkflow != null) {
			sourceProfile = sourceWorkflow.getParent().getMainProfile();
		}
		updateWorkflowGraphic(previewSource, sourceWorkflow, sourceProfile);
	}

	protected void updateFooter() {
		prefixField.setVisible(mergeEnabled);
		prefixLabel.setVisible(mergeEnabled);
		prefixHelp.setVisible(mergeEnabled);

		prefixField.setEnabled(actionMerge.isSelected());
		prefixLabel.setEnabled(actionMerge.isSelected());
		prefixHelp.setEnabled(actionMerge.isSelected());
		if (actionMerge.isSelected()) {
			prefixHelp.setForeground(prefixLabel.getForeground());
		} else {
			// Work around
			// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4303706
			// and assume gray is the 'disabled' colour in our Look n Feel
			prefixHelp.setForeground(Color.gray);
		}

	}

	protected void updateHeader() {
		makeIntroductionPanel();
	}

	protected void updateSourceSection() {
		radioCustomSource.setText(customSourceName);
		radioCustomSource.setVisible(customSourceDataFlow != null);

		radioNew.setVisible(nestedEnabled);
		radioNew.setEnabled(actionNested.isSelected());

		if (actionNested.isSelected() && sourceSelection.getSelection() == null) {
			// Preselect the new workflow
			radioNew.setSelected(true);
		}

		sourceSelectionPanel.setVisible(sourceEnabled);
	}

	/**
	 * Create a PNG image of the workflow and place inside an ImageIcon
	 *
	 * @param dataflow
	 * @return
	 * @throws InvocationTargetException
	 * @throws InterruptedException
	 */
	protected void updateWorkflowGraphic(final JSVGCanvas svgCanvas, final Workflow workflow, final Profile profile) {
		try {
			SwingUtilities.invokeAndWait(new Runnable() {
				public void run() {
					// Set it to blank while reloading
					svgCanvas.setSVGDocument(null);
					if (workflow != null) {
						SVGGraphController currentWfGraphController = new SVGGraphController(
								workflow, profile, false, svgCanvas,
								editManager, menuManager, colourManager, workbenchConfiguration);
					}
				}
			});
		} catch (InterruptedException e) {
			// logger.error(e);
		} catch (InvocationTargetException e) {
			// logger.error(e);
		}
	}

	/**
	 * Open the selected source and destination workflows. If background is true, this method will
	 * return immediately while a {@link DataflowOpenerThread} performs the updates. If a
	 * DataflowOpenerThread is already running, it will be interrupted and stopped.
	 *
	 * @param parentComponent
	 *            The parent component for showing dialogues
	 * @param background
	 *            If true, will run in separate thread.
	 * @return <code>false</code> if running in the background, or if a dialogue was shown and the
	 *         operation is aborted by the user, or <code>true</code> if not running in the
	 *         background and the method completed without user interruption.
	 */
	protected synchronized boolean findChosenDataflow(Component parentComponent, boolean background) {
		if (dataflowOpenerThread != null && dataflowOpenerThread.isAlive()) {
			if (background) {
				// We've changed our mind
				dataflowOpenerThread.interrupt();
			} else {
				// We'll let it finish, we don't need to do it again
				try {
					dataflowOpenerThread.join();
				} catch (InterruptedException e) {
					Thread.currentThread().interrupt();
				}
				return !dataflowOpenerThread.shownWarning;
			}
		}
		dataflowOpenerThread = new DataflowOpenerThread(parentComponent, background);

		if (background) {
			dataflowOpenerThread.start();
			return false;
		} else {
			dataflowOpenerThread.run();
			return !dataflowOpenerThread.shownWarning;
		}

	}

	protected Container makeContentPane() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();

		gbc.ipadx = 5;
		gbc.ipady = 5;

		gbc.gridx = 0;
		gbc.weightx = 0.1;
		gbc.fill = GridBagConstraints.BOTH;

		introductionPanel = makeIntroductionPanel();
		panel.add(introductionPanel, gbc);

		sourceSelectionPanel = makeSourceSelectionPanel();
		panel.add(sourceSelectionPanel, gbc);

//		destinationSelectionPanel = makeDestinationSelectionPanel();
//		panel.add(destinationSelectionPanel, gbc);

		gbc.weighty = 0.1;
		panel.add(makeImportStylePanel(), gbc);

		return panel;
	}

	protected JPanel makeIntroductionPanel() {
		if (introductionPanel == null) {
			introductionPanel = new JPanel(new GridBagLayout());
		} else {
			introductionPanel.removeAll();
		}
		boolean bothEnabled = mergeEnabled && nestedEnabled;
		if (bothEnabled) {
			introductionPanel.setBorder(BorderFactory.createTitledBorder("Import method"));
		} else {
			introductionPanel.setBorder(BorderFactory.createEmptyBorder());
		}
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		// gbc.gridy = 0;
		gbc.weightx = 0.1;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.FIRST_LINE_START;

		StringBuilder nestedHelp = new StringBuilder();
		nestedHelp.append("<html><small>");
		nestedHelp.append("Add a <strong>nested workflow</strong> ");
		nestedHelp.append("into the ");
		nestedHelp.append("destination workflow as a single service. ");
		nestedHelp.append("The nested workflow ");
		nestedHelp.append("can be <em>edited separately</em>, but is shown ");
		nestedHelp.append("expanded in the diagram of the parent  ");
		nestedHelp.append("workflow. In the parent workflow you can ");
		nestedHelp.append("connect to the input and output ports of the nested ");
		nestedHelp.append("workflow. ");
		nestedHelp.append("</small></html>");

		StringBuilder mergeHelp = new StringBuilder();
		mergeHelp.append("<html><small>");
		mergeHelp.append("<strong>Merge</strong> a workflow ");
		mergeHelp.append("by copying all services, ports and links ");
		mergeHelp.append("directly into the destination workflow. This can be  ");
		mergeHelp.append("useful for merging smaller workflow fragments. For ");
		mergeHelp.append("inclusion of larger workflows you might find using ");
		mergeHelp.append("<em>nested workflows</em> more beneficial.");
		mergeHelp.append("</small></html>");

		actionSelection = new ButtonGroup();
		actionNested = new JRadioButton(nestedHelp.toString());
		ActionListener updateListener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				updateSourceSection();
//				updateDestinationSection();
				updateFooter();
			}
		};
		actionNested.addActionListener(updateListener);
		actionSelection.add(actionNested);

		actionMerge = new JRadioButton(mergeHelp.toString());
		actionMerge.addActionListener(updateListener);
		actionSelection.add(actionMerge);

		if (bothEnabled) {
			introductionPanel.add(actionNested, gbc);
			introductionPanel.add(actionMerge, gbc);
			actionNested.setSelected(true);
		} else if (nestedEnabled) {
			introductionPanel.add(new JLabel(nestedHelp.toString()), gbc);
			actionNested.setSelected(true);
		} else if (mergeEnabled) {
			introductionPanel.add(new JLabel(mergeHelp.toString()), gbc);
			actionMerge.setSelected(true);
		}
		return introductionPanel;
	}

//	protected JPanel makeDestinationSelectionPanel() {
//		JPanel j = new JPanel(new GridBagLayout());
//		j.setBorder(BorderFactory.createTitledBorder("Workflow destination"));
//
//		GridBagConstraints gbc = new GridBagConstraints();
//		gbc.gridx = 0;
//		gbc.gridy = 0;
//		gbc.fill = GridBagConstraints.BOTH;
//
//		destinationSelection = new ButtonGroup();
//		radioNewDestination = new JRadioButton("New workflow");
//		gbc.gridy = 0;
//		j.add(radioNewDestination, gbc);
//		destinationSelection.add(radioNewDestination);
//		radioNewDestination.addActionListener(updateChosenListener);
//
//		radioOpenDestination = new JRadioButton("Already opened workflow");
//		gbc.gridy = 2;
//		j.add(radioOpenDestination, gbc);
//		destinationSelection.add(radioOpenDestination);
//		radioOpenDestination.addActionListener(updateChosenListener);
//		gbc.weightx = 0.1;
//		gbc.gridx = 1;
//		destinationAlreadyOpen = makeSelectOpenWorkflowComboBox(true);
//		j.add(destinationAlreadyOpen, gbc);
//
//		radioCustomDestination = new JRadioButton(customDestinationName);
//		radioCustomDestination.setVisible(customDestinationName != null);
//		gbc.gridx = 0;
//		gbc.gridy = 3;
//		gbc.gridwidth = 2;
//		j.add(radioCustomDestination, gbc);
//		destinationSelection.add(radioCustomDestination);
//		radioCustomDestination.addActionListener(updateChosenListener);
//		gbc.gridwidth = 1;
//
//		radioOpenDestination.setSelected(true);
//		return j;
//	}

	protected Component makeImportStylePanel() {
		JPanel j = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.fill = GridBagConstraints.BOTH;

		j.setBorder(BorderFactory.createTitledBorder("Import"));

		prefixLabel = new JLabel("Prefix");
		j.add(prefixLabel, gbc);
		gbc.weightx = 0.1;
		gbc.gridx = 1;

		prefixField = new JTextField(10);
		prefixLabel.setLabelFor(prefixField);
		j.add(prefixField, gbc);

		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.gridwidth = 2;

		prefixHelp = new JLabel(
				"<html><small>Optional prefix to be prepended to the name of the "
						+ "inserted services and workflow ports. Even if no prefix is given, duplicate names will be "
						+ "resolved by adding numbers, for instance <code>my_service_2</code> if <code>my_service</code> already "
						+ "existed." + "</small></html>");
		prefixHelp.setLabelFor(prefixField);
		j.add(prefixHelp, gbc);

		gbc.gridy = 2;
		gbc.weightx = 0.1;
		gbc.weighty = 0.1;

		j.add(makeWorkflowImage(), gbc);

		gbc.gridy = 3;
		gbc.weighty = 0.0;
		j.add(new JPanel(), gbc);

		gbc.gridy = 4;
		gbc.fill = GridBagConstraints.NONE;
		JButton comp = new JButton(new ImportWorkflowAction());
		j.add(comp, gbc);
		return j;

	}

	protected Component makeSelectFile() {
		JPanel j = new JPanel(new GridBagLayout());
		j.setBorder(BorderFactory.createEtchedBorder());

		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.weightx = 0.1;

		fieldFile = new JTextField(20);
		fieldFile.setEditable(false);
		fieldFile.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				radioFile.setSelected(true);
			}

			@Override
			public void focusLost(FocusEvent e) {
				findChosenDataflow(e.getComponent(), true);
			}
		});
		j.add(fieldFile, gbc);
		radioFile.addItemListener(new ItemListener() {

			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					browseFileOnClick.checkEmptyFile();
				}
			}
		});

		gbc.gridx = 1;
		gbc.weightx = 0.0;
		gbc.fill = GridBagConstraints.NONE;
		buttonBrowse = new JButton(new OpenSourceWorkflowAction(fileManager) {
			@Override
			public void openWorkflows(Component parentComponent, File[] files) {
				if (files.length == 0) {
					radioFile.setSelected(false);
					fieldFile.setText("");
					radioFile.requestFocus();
					return;
				}
				fieldFile.setText(files[0].getPath());
				if (!radioFile.isSelected()) {
					radioFile.setSelected(true);
				}
				findChosenDataflow(parentComponent, true);
			}
		});
		buttonBrowse.setText("Browse");
		j.add(buttonBrowse, gbc);

		// This just duplicates things - we already have actions on
		// the radioFile and fieldFile that will handle the events
		// radioFile.addActionListener(browseFileOnClick);
		// fieldFile.addActionListener(browseFileOnClick);
		return j;
	}

	protected JComboBox makeSelectOpenWorkflowComboBox(boolean selectCurrent) {
		List<DataflowSelection> openDataflows = new ArrayList<DataflowSelection>();
		DataflowSelection current = null;
		for (WorkflowBundle df : fileManager.getOpenDataflows()) {
			String name = df.getMainWorkflow().getName();
			boolean isCurrent = df.equals(fileManager.getCurrentDataflow());
			if (isCurrent) {
				// Wrapping as HTML causes weird drop-down box under MAC, so
				// we just use normal text
				// name = "<html><body>" + name
				// + " <i>(current)</i></body></html>";
				name = name + " (current)";
			}
			DataflowSelection selection = new DataflowSelection(df, name);
			openDataflows.add(selection);
			if (isCurrent) {
				current = selection;
			}
		}
		JComboBox chooseDataflow = new JComboBox(openDataflows.toArray());
		if (selectCurrent) {
			chooseDataflow.setSelectedItem(current);
		}
		chooseDataflow.addActionListener(updateChosenListener);
		return chooseDataflow;

	}

	protected Component makeSourceSelectionPanel() {
		JPanel j = new JPanel(new GridBagLayout());
		j.setBorder(BorderFactory.createTitledBorder("Workflow source"));

		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.fill = GridBagConstraints.BOTH;

		sourceSelection = new ButtonGroup();
		radioNew = new JRadioButton("New workflow");
		gbc.gridy = 0;
		j.add(radioNew, gbc);
		sourceSelection.add(radioNew);

		radioNew.addActionListener(updateChosenListener);

		radioFile = new JRadioButton("Import from file");
		gbc.gridy = 1;
		j.add(radioFile, gbc);
		sourceSelection.add(radioFile);
		radioFile.addActionListener(updateChosenListener);

		radioUrl = new JRadioButton("Import from URL");
		gbc.gridy = 2;
		j.add(radioUrl, gbc);
		sourceSelection.add(radioUrl);
		radioUrl.addActionListener(updateChosenListener);

		radioOpened = new JRadioButton("Already opened workflow");
		gbc.gridy = 3;
		j.add(radioOpened, gbc);
		sourceSelection.add(radioOpened);
		radioOpened.addActionListener(updateChosenListener);

		radioCustomSource = new JRadioButton(customSourceName);
		radioCustomSource.setVisible(customSourceDataFlow != null);
		gbc.gridy = 4;
		gbc.gridwidth = 2;
		j.add(radioCustomSource, gbc);
		sourceSelection.add(radioCustomSource);
		radioCustomSource.addActionListener(updateChosenListener);
		gbc.gridwidth = 1;

		gbc.gridx = 1;
		gbc.gridy = 1;
		gbc.weightx = 0.1;
		j.add(makeSelectFile(), gbc);

		gbc.gridy = 2;
		fieldUrl = new JTextField(20);
		j.add(fieldUrl, gbc);
		fieldUrl.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				radioUrl.setSelected(true);
			}

			@Override
			public void focusLost(FocusEvent e) {
				findChosenDataflow(e.getComponent(), true);
			}
		});

		gbc.gridy = 3;
		chooseDataflow = makeSelectOpenWorkflowComboBox(false);
		chooseDataflow.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				radioOpened.setSelected(true);
			}
		});
		j.add(chooseDataflow, gbc);

		return j;
	}

	protected Edit<?> makeInsertNestedWorkflowEdit(Workflow nestedFlow) {
		Processor processor = new Processor();
		processor.setName("nestedWorkflow");

		CrossProduct crossProduct = new CrossProduct();
		crossProduct.setParent(processor.getIterationStrategyStack());

		Activity activity = new Activity();
		activity.setType(DataflowTemplateService.ACTIVITY_TYPE);
		Configuration configuration = new Configuration();
		configuration.setType(DataflowTemplateService.ACTIVITY_TYPE.resolve("#Config"));
		destinationWorkflowBundle.getWorkflows().addWithUniqueName(nestedFlow);
		((ObjectNode) configuration.getJson()).put("nestedWorkflow", nestedFlow.getName());
		destinationWorkflowBundle.getWorkflows().remove(nestedFlow);
		configuration.setConfigures(activity);

		ProcessorBinding processorBinding = new ProcessorBinding();
		processorBinding.setBoundProcessor(processor);
		processorBinding.setBoundActivity(activity);

		for (InputWorkflowPort workflowPort : nestedFlow.getInputPorts()) {
			InputActivityPort activityPort = new InputActivityPort(activity, workflowPort.getName());
			activityPort.setDepth(workflowPort.getDepth());
			// create processor port
			InputProcessorPort processorPort = new InputProcessorPort(processor, activityPort.getName());
			processorPort.setDepth(activityPort.getDepth());
			// add a new port binding
			new ProcessorInputPortBinding(processorBinding, processorPort, activityPort);
		}
		for (OutputWorkflowPort workflowPort : nestedFlow.getOutputPorts()) {
			OutputActivityPort activityPort = new OutputActivityPort(activity, workflowPort.getName());
			// TODO calculate output depth
			activityPort.setDepth(0);
			activityPort.setGranularDepth(0);
			// create processor port
			OutputProcessorPort processorPort = new OutputProcessorPort(processor, activityPort.getName());
			processorPort.setDepth(activityPort.getDepth());
			processorPort.setGranularDepth(activityPort.getGranularDepth());
			// add a new port binding
			new ProcessorOutputPortBinding(processorBinding, activityPort, processorPort);
		}

		List<Edit<?>> editList = new ArrayList<Edit<?>>();
		editList.add(new AddChildEdit<Profile>(destinationProfile, activity));
		editList.add(new AddChildEdit<Profile>(destinationProfile, configuration));
		editList.add(new AddChildEdit<Profile>(destinationProfile, processorBinding));
		editList.add(new AddProcessorEdit(destinationWorkflow, processor));

		editList.add(makeInsertWorkflowEdit(nestedFlow, nestedFlow.getParent().getMainProfile()));

		return new CompoundEdit(editList);
	}

	protected Edit<?> makeInsertWorkflowEdit(Workflow nestedFlow, Profile profile) {
		return makeInsertWorkflowEdit(nestedFlow, profile, new HashSet<>());
	}

	protected Edit<?> makeInsertWorkflowEdit(Workflow nestedFlow, Profile profile, Set<Object> seen) {
		List<Edit<?>> editList = new ArrayList<Edit<?>>();
		// add the nested workflow to the workflow bundle
		editList.add(new AddChildEdit<WorkflowBundle>(destinationWorkflowBundle, nestedFlow));
		seen.add(nestedFlow);
		for (Processor processor : nestedFlow.getProcessors()) {
			// add processor bindings to the profile
			List<ProcessorBinding> processorBindings = scufl2Tools.processorBindingsForProcessor(processor, profile);
			for (ProcessorBinding processorBinding : processorBindings) {
				editList.add(new AddChildEdit<Profile>(destinationProfile, processorBinding));
				// add activity to the profile
				Activity activity = processorBinding.getBoundActivity();
				if (!seen.contains(activity)) {
					editList.add(new AddChildEdit<Profile>(destinationProfile, activity));
					// add activity configurations to the profile
					for (Configuration configuration : scufl2Tools.configurationsFor(activity, profile)) {
						editList.add(new AddChildEdit<Profile>(destinationProfile, configuration));
					}
					seen.add(activity);
				}
			}
			// add processor configurations to the profile
			List<Configuration> configurations = scufl2Tools.configurationsFor(processor, profile);
			for (Configuration configuration : configurations) {
				editList.add(new AddChildEdit<Profile>(destinationProfile, configuration));
			}

			for (Workflow workflow : scufl2Tools.nestedWorkflowsForProcessor(processor, profile)) {
				if (!seen.contains(workflow)) {
					// recursively add nested workflows
					editList.add(makeInsertWorkflowEdit(workflow, profile, seen));
				}
			}
		}
		return new CompoundEdit(editList);
	}

//	protected Activity getInsertedActivity() {
//		return insertedActivity;
//	}

	protected class ImportWorkflowAction extends AbstractAction implements Runnable {
		private static final String VALID_NAME_REGEX = "[\\p{L}\\p{Digit}_.]+";
		private Component parentComponent;
		private ProgressMonitor progressMonitor;

		protected ImportWorkflowAction() {
			super("Import workflow");
		}

		public void actionPerformed(ActionEvent e) {
			/*
			 * if (e.getSource() instanceof Component) { parentComponent = (Component)
			 * e.getSource(); } else { parentComponent = null; }
			 */
			parentComponent = MainWindow.getMainWindow();
			Thread t = new Thread(this, "Import workflow");
			progressMonitor = new ProgressMonitor(parentComponent, "Importing workflow", "", 0, 100);
			progressMonitor.setMillisToDecideToPopup(200);
			progressMonitor.setProgress(5);
			t.start();
			setVisible(false);
		}

		protected void nested() {
			if (progressMonitor.isCanceled()) {
				return;
			}
			progressMonitor.setProgress(15);
			selectionManager.setSelectedWorkflowBundle(destinationWorkflowBundle);
			if (progressMonitor.isCanceled()) {
				return;
			}

			progressMonitor.setNote("Copying source workflow");
			Workflow nestedFlow;
			try {
				nestedFlow = DataflowMerger.copyWorkflow(sourceWorkflow);
			} catch (Exception ex) {
				logger.warn("Could not copy nested workflow", ex);
				progressMonitor.setProgress(100);
				JOptionPane.showMessageDialog(parentComponent,
						"An error occured while copying workflow:\n" + ex.getLocalizedMessage(),
						"Could not copy nested workflow", JOptionPane.WARNING_MESSAGE);
				return;
			}
			if (progressMonitor.isCanceled()) {
				return;
			}

			progressMonitor.setNote("Creating nested workflow");
			progressMonitor.setProgress(45);

			Edit<?> edit = makeInsertNestedWorkflowEdit(nestedFlow);
			if (progressMonitor.isCanceled()) {
				return;
			}

			progressMonitor.setNote("Inserting nested workflow");
			progressMonitor.setProgress(65);

			try {
				editManager.doDataflowEdit(destinationWorkflowBundle, edit);
			} catch (EditException e) {
				progressMonitor.setProgress(100);
				logger.warn("Could not import nested workflow", e);
				JOptionPane.showMessageDialog(parentComponent,
						"An error occured while importing workflow:\n" + e.getLocalizedMessage(),
						"Could not import workflows", JOptionPane.WARNING_MESSAGE);
				return;
			}

			if (radioNew.isSelected()) {
				progressMonitor.setNote("Opening new nested workflow for editing");
				progressMonitor.setProgress(90);
				selectionManager.setSelectedWorkflow(nestedFlow);
			}
			progressMonitor.setProgress(100);
		}

		protected void merge() {
			progressMonitor.setProgress(10);
			DataflowMerger merger = new DataflowMerger(destinationWorkflow);
			progressMonitor.setProgress(25);
			progressMonitor.setNote("Planning workflow merging");

			String prefix = prefixField.getText();
			if (!prefix.equals("")) {
				if (!prefix.matches("[_.]$")) {
					prefix = prefix + "_";
				}
				if (!prefix.matches(VALID_NAME_REGEX)) {
					progressMonitor.setProgress(100);
					final String wrongPrefix = prefix;
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							JOptionPane.showMessageDialog(parentComponent, "The merge prefix '"
									+ wrongPrefix + "' is not valid. Try "
									+ "using only letters, numbers, " + "underscore and dot.",
									"Invalid merge prefix", JOptionPane.ERROR_MESSAGE);
							prefixField.requestFocus();
							ImportWorkflowWizard.this.setVisible(true);
						}
					});
					return;
				}
			}

			CompoundEdit mergeEdit;
			try {
				mergeEdit = merger.getMergeEdit(ImportWorkflowWizard.this.sourceWorkflow, prefix);
			} catch (MergeException e1) {
				progressMonitor.setProgress(100);
				logger.warn("Could not merge workflow", e1);
				JOptionPane.showMessageDialog(parentComponent,
						"An error occured while merging workflows:\n" + e1.getLocalizedMessage(),
						"Could not merge workflows", JOptionPane.WARNING_MESSAGE);
				return;
			}

			progressMonitor.setProgress(55);
			selectionManager.setSelectedWorkflowBundle(destinationWorkflowBundle);

			progressMonitor.setNote("Merging workflows");
			progressMonitor.setProgress(75);

			if (progressMonitor.isCanceled()) {
				return;
			}

			try {
				editManager.doDataflowEdit(destinationWorkflowBundle, mergeEdit);
			} catch (EditException e1) {
				progressMonitor.setProgress(100);
				JOptionPane.showMessageDialog(parentComponent,
						"An error occured while merging workflows:\n" + e1.getLocalizedMessage(),
						"Could not merge workflows", JOptionPane.WARNING_MESSAGE);
				return;
			}
			progressMonitor.setProgress(100);

		}

		public void run() {
			boolean completed = findChosenDataflow(parentComponent, false);
			if (!completed) {
				return;
			}
			if (actionMerge.isSelected()) {
				merge();
			} else if (actionNested.isSelected()) {
				nested();
			}
		}
	}

	protected class UpdatePreviewsThread extends Thread {
		protected UpdatePreviewsThread() {
			super("Updating destination previews");
		}

		public void run() {
			if (Thread.interrupted()) {
				return;
			}
			updateSourcePreview();

			if (Thread.interrupted()) {
				return;
			}
			updateDestinationPreview();
		}
	}

	protected class BrowseFileOnClick implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			checkEmptyFile();
		}

		public void checkEmptyFile() {
			if (radioFile.isSelected() && fieldFile.getText().equals("")) {
				// On first label click pop up Browse dialogue.
				buttonBrowse.doClick();
			}
		}
	}

	protected class DataflowOpenerThread extends Thread {
		private final boolean background;
		private final Component parentComponent;
		private boolean shouldStop = false;
		private boolean shownWarning = false;

		protected DataflowOpenerThread(Component parentComponent, boolean background) {
			super("Inspecting selected workflow");
			this.parentComponent = parentComponent;
			this.background = background;
		}

		@Override
		public void interrupt() {
			this.shouldStop = true;
			super.interrupt();
		}

		public void run() {
			updateSource();
//			updateDestination();
		}

//		public void updateDestination() {
//			ButtonModel selection = destinationSelection.getSelection();
//			Workflow chosenDataflow = null;
//			if (selection == null) {
//				chosenDataflow = null;
//			} else if (selection.equals(radioNewDestination.getModel())) {
//				chosenDataflow = new Workflow();
//			} else if (selection.equals(radioOpenDestination.getModel())) {
//				DataflowSelection chosen = (DataflowSelection) destinationAlreadyOpen
//						.getSelectedItem();
//				chosenDataflow = chosen.getDataflow();
//			} else if (selection.equals(radioCustomDestination.getModel())) {
//				chosenDataflow = customDestinationDataflow;
//			} else {
//				logger.error("Unknown selection " + selection);
//			}
//
//			if (chosenDataflow == null) {
//				if (!background && !shownWarning) {
//					shownWarning = true;
//					SwingUtilities.invokeLater(new Runnable() {
//						public void run() {
//							JOptionPane.showMessageDialog(parentComponent,
//									"You need to choose a destination workflow",
//									"No destination workflow chosen", JOptionPane.ERROR_MESSAGE);
//							setVisible(true);
//						}
//					});
//					return;
//				}
//			}
//			if (checkInterrupted()) {
//				return;
//			}
//			if (chosenDataflow != ImportWorkflowWizard.this.destinationDataflow) {
//				updateWorkflowGraphic(previewDestination, chosenDataflow);
//				if (checkInterrupted()) {
//					return;
//				}
//				ImportWorkflowWizard.this.destinationDataflow = chosenDataflow;
//			}
//
//		}

		public void updateSource() {
			ButtonModel selection = sourceSelection.getSelection();
			Workflow chosenDataflow = null;
			if (selection == null) {
				chosenDataflow = null;
			} else if (selection.equals(radioNew.getModel())) {
				WorkflowBundle workflowBundle = new WorkflowBundle();
				workflowBundle.setMainWorkflow(new Workflow());
				workflowBundle.getMainWorkflow().setName(fileManager.getDefaultWorkflowName());
				workflowBundle.setMainProfile(new Profile());
				scufl2Tools.setParents(workflowBundle);
				chosenDataflow = workflowBundle.getMainWorkflow();
			} else if (selection.equals(radioFile.getModel())) {
				final String filePath = fieldFile.getText();
				try {
					DataflowInfo opened = fileManager
							.openDataflowSilently(null, new File(filePath));
					if (checkInterrupted()) {
						return;
					}
					chosenDataflow = opened.getDataflow().getMainWorkflow();
				} catch (final OpenException e1) {
					if (!background && !shownWarning) {
						shownWarning = true;
						logger.warn("Could not open workflow for merging: " + filePath, e1);
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								radioFile.requestFocus();
								JOptionPane.showMessageDialog(parentComponent,
										"An error occured while trying to open " + filePath + "\n"
												+ e1.getMessage(), "Could not open workflow",
										JOptionPane.WARNING_MESSAGE);
								setVisible(true);
							}
						});
					}
				}
			} else if (selection.equals(radioUrl.getModel())) {
				final String url = fieldUrl.getText();
				try {
					DataflowInfo opened = fileManager.openDataflowSilently(null, new URL(url));
					if (checkInterrupted()) {
						return;
					}
					chosenDataflow = opened.getDataflow().getMainWorkflow();
				} catch (final OpenException e1) {
					if (!background && !shownWarning) {
						logger.warn("Could not open source workflow: " + url, e1);
						shownWarning = true;
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								fieldUrl.requestFocus();
								JOptionPane.showMessageDialog(
										parentComponent,
										"An error occured while trying to open " + url + "\n"
												+ e1.getMessage(), "Could not open workflow",
										JOptionPane.WARNING_MESSAGE);
								setVisible(true);
							}
						});

					}
					if (checkInterrupted()) {
						return;
					}
				} catch (final MalformedURLException e1) {
					if (!background && !shownWarning) {
						logger.warn("Invalid workflow URL: " + url, e1);
						shownWarning = true;
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								fieldUrl.requestFocus();
								JOptionPane.showMessageDialog(
										parentComponent,
										"The workflow location " + url + " is invalid\n"
												+ e1.getLocalizedMessage(), "Invalid URL",
										JOptionPane.ERROR_MESSAGE);
								setVisible(true);
							}
						});
					}
					if (checkInterrupted()) {
						return;
					}
				}
			} else if (selection.equals(radioOpened.getModel())) {
				DataflowSelection chosen = (DataflowSelection) chooseDataflow.getSelectedItem();
				chosenDataflow = chosen.getDataflow().getMainWorkflow();
			} else if (selection.equals(radioCustomSource.getModel())) {
				chosenDataflow = customSourceDataFlow.getMainWorkflow();
			} else {
				logger.error("Unknown selection " + selection);
			}
			if (checkInterrupted()) {
				return;
			}
			if (chosenDataflow != ImportWorkflowWizard.this.sourceWorkflow) {
				Profile chosenProfile = null;
				if (chosenDataflow != null) {
					chosenProfile = chosenDataflow.getParent().getMainProfile();
				}
				updateWorkflowGraphic(previewSource, chosenDataflow, chosenProfile);
				if (checkInterrupted()) {
					return;
				}
				ImportWorkflowWizard.this.sourceWorkflow = chosenDataflow;
			}
			if (chosenDataflow == null) {
				if (!background && !shownWarning) {
					shownWarning = true;
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							JOptionPane.showMessageDialog(parentComponent,
									"You need to choose a workflow for merging",
									"No workflow chosen", JOptionPane.ERROR_MESSAGE);
							setVisible(true);
						}
					});
				}
			}
		}

		private boolean checkInterrupted() {
			if (Thread.interrupted() || this.shouldStop) {
				// ImportWorkflowWizard.this.chosenDataflow = null;
				return true;
			}
			return false;
		}
	}

	public static class DataflowSelection {
		private final WorkflowBundle dataflow;
		private final String name;

		public DataflowSelection(WorkflowBundle dataflow, String name) {
			this.dataflow = dataflow;
			this.name = name;
		}

		public WorkflowBundle getDataflow() {
			return dataflow;
		}

		public String getName() {
			return name;
		}

		@Override
		public String toString() {
			return name;
		}

	}

	protected class UpdateChosenListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			Component parentComponent;
			if (e.getSource() instanceof Component) {
				parentComponent = (Component) e.getSource();
			} else {
				parentComponent = null;
			}
			findChosenDataflow(parentComponent, true);

		}
	}

	public void setCustomSourceDataflow(WorkflowBundle sourceDataflow, String label) {
		this.customSourceDataFlow = sourceDataflow;
		this.customSourceName = label;
		updateSourceSection();
		radioCustomSource.doClick();
	}

//	public void setCustomDestinationDataflow(Workflow destinationDataflow, String label) {
//		this.customDestinationDataflow = destinationDataflow;
//		this.customDestinationName = label;
//		updateDestinationSection();
//		radioCustomDestination.doClick();
//	}

//	public void setDestinationEnabled(boolean destinationEnabled) {
//		this.destinationEnabled = destinationEnabled;
//		updateDestinationSection();
//	}

	public void setSourceEnabled(boolean sourceEnabled) {
		this.sourceEnabled = sourceEnabled;
		updateSourceSection();
	}
}
