/*******************************************************************************
 * Copyright (C) 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.activities.spreadsheet.views;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Stack;

import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;

import net.sf.taverna.t2.activities.spreadsheet.Range;
import net.sf.taverna.t2.activities.spreadsheet.SpreadsheetUtils;
import net.sf.taverna.t2.activities.spreadsheet.il8n.SpreadsheetImportUIText;
import net.sf.taverna.t2.lang.ui.DialogTextArea;
import net.sf.taverna.t2.lang.ui.icons.Icons;
import net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ActivityConfigurationPanel;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;

import uk.org.taverna.commons.services.ServiceRegistry;
import uk.org.taverna.scufl2.api.activity.Activity;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * Configuration panel for the spreadsheet import activity.
 *
 * @author David Withers
 */
@SuppressWarnings("serial")
public class SpreadsheetImportConfigView extends ActivityConfigurationPanel {

	private static final String INCONSISTENT_ROW_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.INCONSISTENT_ROW_MESSAGE");

	private static final String INCONSISTENT_COLUMN_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.INCONSISTENT_COLUMN_MESSAGE");

	private static final String FROM_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.FROM_COLUMN_ERROR_MESSAGE");

	private static final String TO_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.TO_COLUMN_ERROR_MESSAGE");

	private static final String FROM_ROW_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.FROM_ROW_ERROR_MESSAGE");

	private static final String TO_ROW_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.TO_ROW_ERROR_MESSAGE");

	private static final String DEFAULT_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.DEFAULT_MESSAGE");

	private static final String EMPTY_FROM_ROW_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.EMPTY_FROM_ROW_ERROR_MESSAGE");

	private static final String EMPTY_FROM_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.EMPTY_FROM_COLUMN_ERROR_MESSAGE");

	private static final String EMPTY_TO_COLUMN_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.EMPTY_TO_COLUMN_ERROR_MESSAGE");

	private static final String DUPLICATE_PORT_NAME_ERROR_MESSAGE = SpreadsheetImportUIText
			.getString("SpreadsheetImportConfigView.DUPLICATE_PORT_NAME_ERROR_MESSAGE");

	private static Logger logger = Logger.getLogger(SpreadsheetImportConfigView.class);

	private JPanel titlePanel, contentPanel, buttonPanel, page1, page2;

	private JLabel titleLabel, titleIcon, rowLabel, columnLabel;

	private JLabel emptyCellLabel, outputFormatLabel, outputFormatDelimiterLabel, columnMappingLabel;

	private DialogTextArea titleMessage;

	private JTextField columnFromValue, columnToValue, rowFromValue, rowToValue;

	private JTextField emptyCellUserDefinedValue, outputFormatDelimiter;

	private JCheckBox rowSelectAllOption, rowExcludeFirstOption, rowIgnoreBlankRows;

	private ButtonGroup emptyCellButtonGroup, outputFormatButtonGroup;

	private JRadioButton emptyCellEmptyStringOption, emptyCellUserDefinedOption,
	emptyCellErrorValueOption;

	private JRadioButton outputFormatMultiplePort, outputFormatSinglePort;

	private JTable columnMappingTable;

	private SpreadsheetImportConfigTableModel columnMappingTableModel;

	private JButton nextButton, backButton;

	private CardLayout cardLayout = new CardLayout();

	private Stack<String> warningMessages = new Stack<String>();

	private Stack<String> errorMessages = new Stack<String>();

	private ObjectNode newConfiguration;

	private final ServiceRegistry serviceRegistry;

	/**
	 * Constructs a configuration view for an SpreadsheetImport Activity.
	 *
	 * @param activity
	 */
	public SpreadsheetImportConfigView(Activity activity, ServiceRegistry serviceRegistry) {
		super(activity);
		this.serviceRegistry = serviceRegistry;
		initialise();
	}

	@Override
	protected void initialise() {
		super.initialise();
		newConfiguration = getJson().deepCopy();

		// title
		titlePanel = new JPanel(new BorderLayout());
		titlePanel.setBackground(Color.WHITE);
		addDivider(titlePanel, SwingConstants.BOTTOM, true);

		titleLabel = new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.panelTitle"));
		titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 13.5f));
		titleIcon = new JLabel("");
		titleMessage = new DialogTextArea(DEFAULT_MESSAGE);
		titleMessage.setMargin(new Insets(5, 10, 10, 10));
		// titleMessage.setMinimumSize(new Dimension(0, 30));
		titleMessage.setFont(titleMessage.getFont().deriveFont(11f));
		titleMessage.setEditable(false);
		titleMessage.setFocusable(false);
		// titleMessage.setFont(titleLabel.getFont().deriveFont(Font.PLAIN,
		// 12f));

		// column range
		columnLabel = new JLabel(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.columnSectionLabel"));

		JsonNode columnRange = newConfiguration.get("columnRange");
		columnFromValue = new JTextField(new UpperCaseDocument(), SpreadsheetUtils.getColumnLabel(columnRange.get("start").intValue()), 4);
		columnFromValue.setMinimumSize(columnFromValue.getPreferredSize());
		columnToValue = new JTextField(new UpperCaseDocument(), SpreadsheetUtils.getColumnLabel(columnRange.get("end").intValue()), 4);
		columnToValue.setMinimumSize(columnToValue.getPreferredSize());

		columnFromValue.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
			}

			public void insertUpdate(DocumentEvent e) {
				checkValue(columnFromValue.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				checkValue(columnFromValue.getText());
			}

			private void checkValue(String text) {
				if (text.trim().equals("")) {
					addErrorMessage(EMPTY_FROM_COLUMN_ERROR_MESSAGE);
				} else if (text.trim().matches("[A-Za-z]+")) {
					String fromColumn = columnFromValue.getText().toUpperCase();
					String toColumn = columnToValue.getText().toUpperCase();
					int fromColumnIndex = SpreadsheetUtils.getColumnIndex(fromColumn);
					int toColumnIndex = SpreadsheetUtils.getColumnIndex(toColumn);
					if (checkColumnRange(fromColumnIndex, toColumnIndex)) {
						columnMappingTableModel.setFromColumn(fromColumnIndex);
						columnMappingTableModel.setToColumn(toColumnIndex);
						newConfiguration.set("columnRange", newConfiguration.objectNode().put("start", fromColumnIndex).put("end", toColumnIndex));
						validatePortNames();
					}
					removeErrorMessage(FROM_COLUMN_ERROR_MESSAGE);
					removeErrorMessage(EMPTY_FROM_COLUMN_ERROR_MESSAGE);
				} else {
					addErrorMessage(FROM_COLUMN_ERROR_MESSAGE);
					removeErrorMessage(EMPTY_FROM_COLUMN_ERROR_MESSAGE);
				}
			}

		});

		columnToValue.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
			}

			public void insertUpdate(DocumentEvent e) {
				checkValue(columnToValue.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				checkValue(columnToValue.getText());
			}

			private void checkValue(String text) {
				if (text.trim().equals("")) {
					addErrorMessage(EMPTY_TO_COLUMN_ERROR_MESSAGE);
				} else if (text.trim().matches("[A-Za-z]+")) {
					String fromColumn = columnFromValue.getText().toUpperCase();
					String toColumn = columnToValue.getText().toUpperCase();
					int fromColumnIndex = SpreadsheetUtils.getColumnIndex(fromColumn);
					int toColumnIndex = SpreadsheetUtils.getColumnIndex(toColumn);
					if (checkColumnRange(fromColumnIndex, toColumnIndex)) {
						columnMappingTableModel.setFromColumn(fromColumnIndex);
						columnMappingTableModel.setToColumn(toColumnIndex);
						newConfiguration.set("columnRange", newConfiguration.objectNode().put("start", fromColumnIndex).put("end", toColumnIndex));
						validatePortNames();
					}
					removeErrorMessage(TO_COLUMN_ERROR_MESSAGE);
					removeErrorMessage(EMPTY_TO_COLUMN_ERROR_MESSAGE);

				} else {
					addErrorMessage(TO_COLUMN_ERROR_MESSAGE);
					removeErrorMessage(EMPTY_TO_COLUMN_ERROR_MESSAGE);
				}
			}
		});

		// row range
		rowLabel = new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.rowSectionLabel"));
		addDivider(rowLabel, SwingConstants.TOP, false);

		rowSelectAllOption = new JCheckBox(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.selectAllRowsOption"));
		rowExcludeFirstOption = new JCheckBox(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.excludeHeaderRowOption"));
		rowIgnoreBlankRows = new JCheckBox(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.ignoreBlankRowsOption"));
		rowSelectAllOption.setFocusable(false);
		rowExcludeFirstOption.setFocusable(false);

		JsonNode rowRange = newConfiguration.get("rowRange");
		rowFromValue = new JTextField(new NumericDocument(), String.valueOf(rowRange.get("start").intValue() + 1), 4);
		if (rowRange.get("end").intValue() == -1) {
			rowToValue = new JTextField(new NumericDocument(), "", 4);
		} else {
			rowToValue = new JTextField(new NumericDocument(), String.valueOf(rowRange.get("end").intValue() + 1), 4);
		}
		rowFromValue.setMinimumSize(rowFromValue.getPreferredSize());
		rowToValue.setMinimumSize(rowToValue.getPreferredSize());

		if (newConfiguration.get("allRows").booleanValue()) {
			rowSelectAllOption.setSelected(true);
			rowFromValue.setEditable(false);
			rowFromValue.setEnabled(false);
			rowToValue.setEditable(false);
			rowToValue.setEnabled(false);
		} else {
			rowExcludeFirstOption.setEnabled(false);
		}
		rowExcludeFirstOption.setSelected(newConfiguration.get("excludeFirstRow").booleanValue());
		rowIgnoreBlankRows.setSelected(newConfiguration.get("ignoreBlankRows").booleanValue());

		rowFromValue.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
			}

			public void insertUpdate(DocumentEvent e) {
				checkValue(rowFromValue.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				checkValue(rowFromValue.getText());
			}

			private void checkValue(String text) {
				if (text.trim().equals("")) {
					addErrorMessage(EMPTY_FROM_ROW_ERROR_MESSAGE);
				} else if (text.trim().matches("[1-9][0-9]*")) {
					checkRowRange(rowFromValue.getText(), rowToValue.getText());
					int fromRow = Integer.parseInt(rowFromValue.getText());
					((ObjectNode) newConfiguration.get("rowRange")).put("start", fromRow - 1);
					removeErrorMessage(FROM_ROW_ERROR_MESSAGE);
					removeErrorMessage(EMPTY_FROM_ROW_ERROR_MESSAGE);
				} else {
					addErrorMessage(FROM_ROW_ERROR_MESSAGE);
					removeErrorMessage(EMPTY_FROM_ROW_ERROR_MESSAGE);
				}
			}
		});

		rowToValue.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
			}

			public void insertUpdate(DocumentEvent e) {
				checkValue(rowToValue.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				checkValue(rowToValue.getText());
			}

			private void checkValue(String text) {
				if (text.trim().equals("")) {
					((ObjectNode) newConfiguration.get("rowRange")).put("end", -1);
					removeErrorMessage(TO_ROW_ERROR_MESSAGE);
					removeErrorMessage(INCONSISTENT_ROW_MESSAGE);
				} else if (text.trim().matches("[0-9]+")) {
					checkRowRange(rowFromValue.getText(), rowToValue.getText());
					int toRow = Integer.parseInt(rowToValue.getText());
					((ObjectNode) newConfiguration.get("rowRange")).put("end", toRow - 1);
					removeErrorMessage(TO_ROW_ERROR_MESSAGE);
				} else {
					addErrorMessage(TO_ROW_ERROR_MESSAGE);
				}
			}
		});

		rowSelectAllOption.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					newConfiguration.put("allRows", true);
					rowExcludeFirstOption.setEnabled(true);
					if (rowExcludeFirstOption.isSelected()) {
						rowFromValue.setText("2");
					} else {
						rowFromValue.setText("1");
					}
					rowToValue.setText("");
					rowFromValue.setEditable(false);
					rowFromValue.setEnabled(false);
					rowToValue.setEditable(false);
					rowToValue.setEnabled(false);
				} else {
					newConfiguration.put("allRows", false);
					rowExcludeFirstOption.setEnabled(false);
					rowFromValue.setEditable(true);
					rowFromValue.setEnabled(true);
					rowToValue.setEditable(true);
					rowToValue.setEnabled(true);
				}
			}
		});

		rowExcludeFirstOption.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if (e.getStateChange() == ItemEvent.SELECTED) {
					newConfiguration.put("excludeFirstRow", true);
					rowFromValue.setText("2");
					((ObjectNode) newConfiguration.get("rowRange")).put("start", 1);
				} else {
					newConfiguration.put("excludeFirstRow", false);
					rowFromValue.setText("1");
					((ObjectNode) newConfiguration.get("rowRange")).put("start", 0);
				}
			}
		});

		rowIgnoreBlankRows.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				newConfiguration.put("ignoreBlankRows", e.getStateChange() == ItemEvent.SELECTED);
			}
		});

		// empty cells
		emptyCellLabel = new JLabel(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.emptyCellSectionLabel"));
		addDivider(emptyCellLabel, SwingConstants.TOP, false);

		emptyCellButtonGroup = new ButtonGroup();
		emptyCellEmptyStringOption = new JRadioButton(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.emptyStringOption"));
		emptyCellUserDefinedOption = new JRadioButton(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.userDefinedOption"));
		emptyCellErrorValueOption = new JRadioButton(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.generateErrorOption"));
		emptyCellEmptyStringOption.setFocusable(false);
		emptyCellUserDefinedOption.setFocusable(false);
		emptyCellErrorValueOption.setFocusable(false);

		emptyCellUserDefinedValue = new JTextField(newConfiguration.get("emptyCellValue").textValue());

		emptyCellButtonGroup.add(emptyCellEmptyStringOption);
		emptyCellButtonGroup.add(emptyCellUserDefinedOption);
		emptyCellButtonGroup.add(emptyCellErrorValueOption);

		if (newConfiguration.get("emptyCellPolicy").textValue().equals("GENERATE_ERROR")) {
			emptyCellErrorValueOption.setSelected(true);
			emptyCellUserDefinedValue.setEnabled(false);
			emptyCellUserDefinedValue.setEditable(false);
		} else if (newConfiguration.get("emptyCellPolicy").textValue().equals("EMPTY_STRING")) {
			emptyCellEmptyStringOption.setSelected(true);
			emptyCellUserDefinedValue.setEnabled(false);
			emptyCellUserDefinedValue.setEditable(false);
		} else {
			emptyCellUserDefinedOption.setSelected(true);
			emptyCellUserDefinedValue.setText(newConfiguration.get("emptyCellValue").textValue());
			emptyCellUserDefinedValue.setEnabled(true);
			emptyCellUserDefinedValue.setEditable(true);
		}

		emptyCellEmptyStringOption.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				newConfiguration.put("emptyCellPolicy", "EMPTY_STRING");
				emptyCellUserDefinedValue.setEnabled(false);
				emptyCellUserDefinedValue.setEditable(false);
			}
		});
		emptyCellUserDefinedOption.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				newConfiguration.put("emptyCellPolicy", "USER_DEFINED");
				emptyCellUserDefinedValue.setEnabled(true);
				emptyCellUserDefinedValue.setEditable(true);
				emptyCellUserDefinedValue.requestFocusInWindow();
			}
		});
		emptyCellErrorValueOption.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				newConfiguration.put("emptyCellPolicy", "GENERATE_ERROR");
				emptyCellUserDefinedValue.setEnabled(false);
				emptyCellUserDefinedValue.setEditable(false);
			}
		});

		emptyCellUserDefinedValue.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				newConfiguration.put("emptyCellValue", emptyCellUserDefinedValue.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				newConfiguration.put("emptyCellValue", emptyCellUserDefinedValue.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				newConfiguration.put("emptyCellValue", emptyCellUserDefinedValue.getText());
			}
		});

		// column mappings
		columnMappingLabel = new JLabel(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.columnMappingSectionLabel"));
		addDivider(columnMappingLabel, SwingConstants.TOP, false);

		Map<String, String> columnToPortMapping = new HashMap<>();
		if (newConfiguration.has("columnNames")) {
			for (JsonNode columnName : newConfiguration.get("columnNames")) {
				columnToPortMapping.put(columnName.get("column").textValue(), columnName.get("port").textValue());
			}
		}
		columnMappingTableModel = new SpreadsheetImportConfigTableModel(columnFromValue.getText(),
				columnToValue.getText(), columnToPortMapping);

		columnMappingTable = new JTable();
		columnMappingTable.setRowSelectionAllowed(false);
		columnMappingTable.getTableHeader().setReorderingAllowed(false);
		columnMappingTable.setGridColor(Color.LIGHT_GRAY);
		// columnMappingTable.setFocusable(false);

		columnMappingTable.setColumnModel(new DefaultTableColumnModel() {
			public TableColumn getColumn(int columnIndex) {
				TableColumn column = super.getColumn(columnIndex);
				if (columnIndex == 0) {
					column.setMaxWidth(100);
				}
				return column;
			}
		});

		TableCellEditor defaultEditor = columnMappingTable.getDefaultEditor(String.class);
		if (defaultEditor instanceof DefaultCellEditor) {
			DefaultCellEditor defaultCellEditor = (DefaultCellEditor) defaultEditor;
			defaultCellEditor.setClickCountToStart(1);
			Component editorComponent = defaultCellEditor.getComponent();
			if (editorComponent instanceof JTextComponent) {
				final JTextComponent textField = (JTextComponent) editorComponent;
				textField.getDocument().addDocumentListener(new DocumentListener() {
					public void changedUpdate(DocumentEvent e) {
						updateModel(textField.getText());
					}

					public void insertUpdate(DocumentEvent e) {
						updateModel(textField.getText());
					}

					public void removeUpdate(DocumentEvent e) {
						updateModel(textField.getText());
					}

					private void updateModel(String text) {
						int row = columnMappingTable.getEditingRow();
						int column = columnMappingTable.getEditingColumn();
						columnMappingTableModel.setValueAt(text, row, column);

						ArrayNode columnNames = newConfiguration.arrayNode();
						Map<String, String> columnToPortMapping = columnMappingTableModel.getColumnToPortMapping();
						for (Entry<String,String> entry : columnToPortMapping.entrySet()) {
							columnNames.add(newConfiguration.objectNode().put("column", entry.getKey()).put("port", entry.getValue()));
						}
						newConfiguration.put("columnNames", columnNames);
						validatePortNames();
					}

				});
			}
		}

		columnMappingTable.setModel(columnMappingTableModel);

		// output format
		outputFormatLabel = new JLabel(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.outputFormatSectionLabel"));

		outputFormatMultiplePort = new JRadioButton(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.multiplePortOption"));
		outputFormatSinglePort = new JRadioButton(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.singlePortOption"));
		outputFormatMultiplePort.setFocusable(false);
		outputFormatSinglePort.setFocusable(false);

		outputFormatDelimiterLabel = new JLabel(SpreadsheetImportUIText
				.getString("SpreadsheetImportConfigView.userDefinedCsvDelimiter"));
		outputFormatDelimiter = new JTextField(newConfiguration.get("csvDelimiter").textValue(), 5);

		outputFormatButtonGroup = new ButtonGroup();
		outputFormatButtonGroup.add(outputFormatMultiplePort);
		outputFormatButtonGroup.add(outputFormatSinglePort);

		if (newConfiguration.get("outputFormat").textValue().equals("PORT_PER_COLUMN")) {
			outputFormatMultiplePort.setSelected(true);
			outputFormatDelimiterLabel.setEnabled(false);
			outputFormatDelimiter.setEnabled(false);
		} else {
			outputFormatSinglePort.setSelected(true);
			columnMappingLabel.setEnabled(false);
			enableTable(columnMappingTable, false);
		}

		outputFormatMultiplePort.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				outputFormatDelimiterLabel.setEnabled(false);
				outputFormatDelimiter.setEnabled(false);
				columnMappingLabel.setEnabled(true);
				enableTable(columnMappingTable, true);
				newConfiguration.put("outputFormat", "PORT_PER_COLUMN");
			}
		});
		outputFormatSinglePort.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				outputFormatDelimiterLabel.setEnabled(true);
				outputFormatDelimiter.setEnabled(true);
				columnMappingLabel.setEnabled(false);
				enableTable(columnMappingTable, false);
				newConfiguration.put("outputFormat", "SINGLE_PORT");
			}

		});
		outputFormatDelimiter.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				handleUpdate();
			}

			public void insertUpdate(DocumentEvent e) {
				handleUpdate();
			}

			public void removeUpdate(DocumentEvent e) {
				handleUpdate();
			}

			private void handleUpdate() {
				String text = null;
				try {
					text = StringEscapeUtils.unescapeJava(outputFormatDelimiter.getText());
				} catch (RuntimeException re) {}
				if (text == null || text.length() == 0) {
					newConfiguration.put("csvDelimiter", ",");
				} else {
					newConfiguration.put("csvDelimiter", text.substring(0, 1));
				}
			}

		});

		// buttons
		nextButton = new JButton(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.nextButton"));
		nextButton.setFocusable(false);
		nextButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				backButton.setVisible(true);
				nextButton.setVisible(false);
				cardLayout.last(contentPanel);
			}
		});

		backButton = new JButton(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.backButton"));
		backButton.setFocusable(false);
		backButton.setVisible(false);
		backButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				nextButton.setVisible(true);
				backButton.setVisible(false);
				cardLayout.first(contentPanel);
			}
		});

		buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		addDivider(buttonPanel, SwingConstants.TOP, true);

		removeAll();
		layoutPanel();
	}

	@Override
	public void noteConfiguration() {
		setJson(newConfiguration);
		configureInputPorts(serviceRegistry);
		configureOutputPorts(serviceRegistry);
	}

	@Override
	public boolean checkValues() {
		return errorMessages.isEmpty();
	}

	private void layoutPanel() {
		setPreferredSize(new Dimension(450, 400));
		setLayout(new BorderLayout());

		page1 = new JPanel(new GridBagLayout());
		page2 = new JPanel(new GridBagLayout());

		contentPanel = new JPanel(cardLayout);
		contentPanel.add(page1, "page1");
		contentPanel.add(page2, "page2");
		add(contentPanel, BorderLayout.CENTER);

		// title
		titlePanel.setBorder(new CompoundBorder(titlePanel.getBorder(), new EmptyBorder(10, 10, 0, 10)));
		add(titlePanel, BorderLayout.NORTH);
		titlePanel.add(titleLabel, BorderLayout.NORTH);
		titlePanel.add(titleIcon, BorderLayout.WEST);
		titlePanel.add(titleMessage, BorderLayout.CENTER);

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.WEST;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 1;
		c.gridx = 0;
		c.gridwidth = GridBagConstraints.REMAINDER;

		// column range
		c.insets = new Insets(10, 10, 0, 10);
		page1.add(columnLabel, c);

		c.insets = new Insets(10, 25, 0, 0);
		c.gridwidth = 1;
		c.weightx = 0;
		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.from")), c);
		c.insets = new Insets(10, 0, 0, 0);
		c.gridx = 1;
		page1.add(columnFromValue, c);
		c.gridx = 2;
		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.to")), c);
		c.gridx = 3;
		page1.add(columnToValue, c);

		c.gridx = 0;
		c.weightx = 1;
		c.insets = new Insets(10, 10, 0, 10);
		c.gridwidth = GridBagConstraints.REMAINDER;

		// row range
		page1.add(rowLabel, c);

		c.insets = new Insets(10, 25, 0, 0);
		c.gridwidth = 1;
		c.gridx = 0;
		c.weightx = 0;
		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.from")), c);
		c.insets = new Insets(10, 0, 0, 0);
		c.gridx = 1;
		page1.add(rowFromValue, c);
		c.gridx = 2;
		page1.add(new JLabel(SpreadsheetImportUIText.getString("SpreadsheetImportConfigView.to")), c);
		c.gridx = 3;
		page1.add(rowToValue, c);
		c.gridx = 4;
		page1.add(rowSelectAllOption, c);
		c.gridx = 5;
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(10, 0, 0, 10);
		page1.add(rowExcludeFirstOption, c);
		c.insets = new Insets(10, 25, 0, 0);
		c.gridx = 0;
		page1.add(rowIgnoreBlankRows, c);

		c.gridx = 0;

		// empty cells
		c.insets = new Insets(10, 10, 10, 10);
		page1.add(emptyCellLabel, c);

		c.insets = new Insets(0, 25, 0, 10);
		page1.add(emptyCellEmptyStringOption, c);
		JPanel userDefinedPanel = new JPanel(new BorderLayout());
		userDefinedPanel.add(emptyCellUserDefinedOption, BorderLayout.WEST);
		userDefinedPanel.add(emptyCellUserDefinedValue, BorderLayout.CENTER);
		page1.add(userDefinedPanel, c);
		c.weighty = 1;
		c.anchor = GridBagConstraints.NORTHWEST;
		page1.add(emptyCellErrorValueOption, c);

		// output format
		c.insets = new Insets(10, 10, 10, 10);
		c.weighty = 0;
		c.weightx = 1;
		page2.add(outputFormatLabel, c);

		c.insets = new Insets(0, 25, 0, 10);
		page2.add(outputFormatMultiplePort, c);
		page2.add(outputFormatSinglePort, c);

		c.insets = new Insets(0, 50, 0, 10);
		JPanel outputFormatDelimiterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
		outputFormatDelimiterPanel.add(outputFormatDelimiterLabel);
		outputFormatDelimiterPanel.add(outputFormatDelimiter);
		page2.add(outputFormatDelimiterPanel, c);

		// column mapping
		c.insets = new Insets(10, 10, 0, 10);
		page2.add(columnMappingLabel, c);

		c.insets = new Insets(10, 10, 10, 10);
		c.fill = GridBagConstraints.BOTH;
		c.weighty = 1;
		page2.add(new JScrollPane(columnMappingTable), c);

		buttonPanel.add(backButton);
		buttonPanel.add(nextButton);
		add(buttonPanel, BorderLayout.SOUTH);
	}

	/**
	 * Displays the message with no icon.
	 *
	 * @param message
	 *            the message to display
	 */
	public void setMessage(String message) {
		titleIcon.setIcon(null);
		titleMessage.setText(message);
	}

	/**
	 * Adds the message to the top of the warning message stack. If the message is already in the
	 * stack it is moved to the top. If there are no error messages the message is displayed.
	 *
	 * @param message
	 *            the warning message to add
	 */
	public void addWarningMessage(String message) {
		if (warningMessages.contains(message)) {
			warningMessages.remove(message);
		}
		warningMessages.push(message);
		if (errorMessages.isEmpty()) {
			setWarningMessage(message);
		}
	}

	/**
	 * Removes the message from the warning message stack. If there are no error messages the next
	 * warning message is displayed. If there are no warning messages the default message is
	 * displayed.
	 *
	 * @param message
	 *            the warning message to remove
	 */
	public void removeWarningMessage(String message) {
		warningMessages.remove(message);
		if (errorMessages.isEmpty()) {
			if (warningMessages.isEmpty()) {
				setMessage(DEFAULT_MESSAGE);
			} else {
				setWarningMessage(warningMessages.peek());
			}
		}
	}

	/**
	 * Displays the message and a warning icon.
	 *
	 * @param message
	 *            the warning message to display
	 */
	public void setWarningMessage(String message) {
		titleIcon.setIcon(Icons.warningIcon);
		titleMessage.setText(message);
	}

	/**
	 * Adds the message to the top of the error message stack. If the message is already in the
	 * stack it is moved to the top. The message is then displayed.
	 *
	 * @param message
	 *            the error message to add
	 */
	public void addErrorMessage(String message) {
		if (errorMessages.contains(message)) {
			errorMessages.remove(message);
		}
		errorMessages.push(message);
		setErrorMessage(message);
	}

	/**
	 * Removes the message from the error message stack and displays the next error message. If
	 * there are no error messages the next warning message is displayed. If there are no warning
	 * messages the default message is displayed.
	 *
	 * @param message
	 *            the error message to remove
	 */
	public void removeErrorMessage(String message) {
		errorMessages.remove(message);
		if (errorMessages.isEmpty()) {
			if (warningMessages.isEmpty()) {
				setMessage(DEFAULT_MESSAGE);
			} else {
				setWarningMessage(warningMessages.peek());
			}
		} else {
			setErrorMessage(errorMessages.peek());
		}
	}

	/**
	 * Displays the message and an error icon.
	 *
	 * @param message
	 *            the error message to display
	 */
	public void setErrorMessage(String message) {
		titleIcon.setIcon(Icons.severeIcon);
		titleMessage.setText(message);
	}

	protected boolean validatePortNames() {
		boolean isValid = true;
		Range columnRange = SpreadsheetUtils.getRange(newConfiguration.get("columnRange"));
		Map<String, String> mapping = new HashMap<>();
		if (newConfiguration.has("columnNames")) {
			for (JsonNode columnName : newConfiguration.get("columnNames")) {
				mapping.put(columnName.get("column").textValue(), columnName.get("port").textValue());
			}
		}
		Set<String> usedNames = new HashSet<String>();
		for (Entry<String, String> entry : mapping.entrySet()) {
			if (columnRange.contains(SpreadsheetUtils.getColumnIndex(entry.getKey()))) {
				String portName = entry.getValue();
				if (!usedNames.add(portName)) {
					isValid = false;
					break;
				}
				if (portName.matches("[A-Z]+")) {
					if (!mapping.containsKey(portName)) {
						int columnIndex = SpreadsheetUtils.getColumnIndex(portName);
						if (columnRange.contains(columnIndex)) {
							isValid = false;
							break;
						}
					}
				}
			}
		}
		if (isValid) {
			removeErrorMessage(DUPLICATE_PORT_NAME_ERROR_MESSAGE);
		} else {
			addErrorMessage(DUPLICATE_PORT_NAME_ERROR_MESSAGE);
		}
		return isValid;
	}

	protected boolean checkRowRange(String from, String to) {
		boolean result = false;
		try {
			int fromRow = Integer.parseInt(from);
			int toRow = Integer.parseInt(to);
			if (toRow < fromRow) {
				addErrorMessage(INCONSISTENT_ROW_MESSAGE);
			} else {
				removeErrorMessage(INCONSISTENT_ROW_MESSAGE);
				result = true;
			}
		} catch (NumberFormatException e) {
			logger.warn("Problem checking row range", e);
		}
		return result;
	}

	protected boolean checkColumnRange(int fromColumn, int toColumn) {
		boolean result = false;
		if (toColumn < fromColumn) {
			addErrorMessage(INCONSISTENT_COLUMN_MESSAGE);
		} else {
			removeErrorMessage(INCONSISTENT_COLUMN_MESSAGE);
			result = true;
		}
		return result;
	}

	/**
	 * Adds a light gray or etched border to the top or bottom of a JComponent.
	 *
	 * @param component
	 */
	protected void addDivider(JComponent component, final int position, final boolean etched) {
		component.setBorder(new Border() {
			private final Color borderColor = new Color(.6f, .6f, .6f);

			public Insets getBorderInsets(Component c) {
				if (position == SwingConstants.TOP) {
					return new Insets(5, 0, 0, 0);
				} else {
					return new Insets(0, 0, 5, 0);
				}
			}

			public boolean isBorderOpaque() {
				return false;
			}

			public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
				if (position == SwingConstants.TOP) {
					if (etched) {
						g.setColor(borderColor);
						g.drawLine(x, y, x + width, y);
						g.setColor(Color.WHITE);
						g.drawLine(x, y + 1, x + width, y + 1);
					} else {
						g.setColor(Color.LIGHT_GRAY);
						g.drawLine(x, y, x + width, y);
					}
				} else {
					if (etched) {
						g.setColor(borderColor);
						g.drawLine(x, y + height - 2, x + width, y + height - 2);
						g.setColor(Color.WHITE);
						g.drawLine(x, y + height - 1, x + width, y + height - 1);
					} else {
						g.setColor(Color.LIGHT_GRAY);
						g.drawLine(x, y + height - 1, x + width, y + height - 1);
					}
				}
			}

		});
	}

	private void enableTable(JTable table, boolean enabled) {
		table.setEnabled(enabled);
		Component editor = table.getEditorComponent();
		if (editor != null) {
			editor.setEnabled(enabled);
		}
		if (enabled) {
			table.setForeground(Color.BLACK);
			table.getTableHeader().setForeground(Color.BLACK);
		} else {
			table.setForeground(Color.LIGHT_GRAY);
			table.getTableHeader().setForeground(Color.LIGHT_GRAY);
		}
	}

	static class UpperCaseDocument extends PlainDocument {
        @Override
        public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        	if (text.matches("[A-Za-z]+")) {
        		text = text.toUpperCase();
        		super.replace(offset, length, text, attrs);
        	}
        }
     }

	static class NumericDocument extends PlainDocument {
        @Override
        public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        	if (text.length() == 0 || text.matches("[0-9]+")) {
        		text = text.toUpperCase();
        		super.replace(offset, length, text, attrs);
        	}
        }
     }

	/**
	 * Main method for testing the panel.
	 *
	 * @param args
	 * @throws ActivityConfigurationException
	 */
//	public static void main(String[] args) throws ActivityConfigurationException {
//		final JFrame frame = new JFrame();
//		SpreadsheetImportActivity activity = new SpreadsheetImportActivity();
//		activity.configure(new SpreadsheetImportConfiguration());
//		final SpreadsheetImportConfigView config = new SpreadsheetImportConfigView(activity);
//		config.setOkAction(new AbstractAction("Finish") {
//			public void actionPerformed(ActionEvent arg0) {
//				Range columnRange = config.getConfiguration().getColumnRange();
//				String fromColumn = SpreadsheetUtils.getColumnLabel(columnRange.getStart());
//				String toColumn = SpreadsheetUtils.getColumnLabel(columnRange.getEnd());
//				System.out.printf("%s (%s) - %s (%s)", fromColumn, columnRange.getStart(),
//						toColumn, columnRange.getEnd());
//				frame.setVisible(false);
//				frame.dispose();
//			}
//		});
//		config.setCancelAction(new AbstractAction("Cancel") {
//			public void actionPerformed(ActionEvent arg0) {
//				frame.setVisible(false);
//				frame.dispose();
//			}
//		});
//		frame.add(config);
//		frame.pack();
//		frame.setVisible(true);
//	}

}
