/*******************************************************************************
 * Copyright (c) 2014 TwelveTone LLC and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Steven Spungin <steven@spungin.tv> - initial API and implementation, Bug 432555, Bug 436889, Bug 437372, Bug 440469,
 * Ongoing Maintenance
 *******************************************************************************/

package org.eclipse.e4.tools.emf.ui.internal.common.component.tabs;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.nls.Translation;
import org.eclipse.e4.tools.emf.ui.common.IModelResource;
import org.eclipse.e4.tools.emf.ui.common.ModelEditorPreferences;
import org.eclipse.e4.tools.emf.ui.common.Plugin;
import org.eclipse.e4.tools.emf.ui.internal.Messages;
import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.BundleImageCache;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.EAttributeEditingSupport.ATT_TYPE;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.E;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.EmptyFilterOption;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.TitleAreaFilterDialog;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.TitleAreaFilterDialogWithEmptyOptions;
import org.eclipse.e4.tools.emf.ui.internal.common.xml.EMFDocumentResourceMediator;
import org.eclipse.e4.tools.services.IResourcePool;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.osgi.service.prefs.BackingStoreException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * A tab that contains a list EObjects, and provides editable columns for
 * EObject features.
 *
 * @author Steven Spungin
 *
 */
public class ListTab implements IViewEObjects {

	static final String ELIPSIS = "..."; //$NON-NLS-1$

	ConcurrentHashMap<String, List<EObject>> mapId_Object = new ConcurrentHashMap<>();

	@Inject
	private IEclipseContext context;

	@Inject
	private IModelResource modelResource;

	private TableViewer tvResults;

	@Inject
	private IGotoObject gotoObjectHandler;

	@Inject
	private IResourcePool resourcePool;

	@Inject
	@Translation
	protected Messages Messages;

	@Inject
	MApplication app;

	BundleImageCache imageCache;

	private CTabItem tabItem;

	private ModelResourceContentProvider provider;

	private IDocumentListener documentListener;

	private Collection<?> highlightedItems;

	protected Image imgMarkedItem;

	LinkedHashMap<String, EAttributeTableViewerColumn> defaultColumns = new LinkedHashMap<>();
	LinkedHashMap<String, EAttributeTableViewerColumn> optionalColumns = new LinkedHashMap<>();
	LinkedHashMap<String, TableColumn> requiredColumns = new LinkedHashMap<>();
	private TableViewerColumn colItem;
	private TableViewerColumn colGo;
	private TableViewerColumn colGoXmi;
	private TableViewerColumn colMarked;

	private ToolItem filterByItem;
	private ToolItem filterByAttribute;
	private String filterByAttrName;
	private String filterByItemName;
	private EmptyFilterOption filterByAttrEmptyOption;

	@PreDestroy
	public void preDestroy() {
		// race condition issue with observables (exception is not thrown when
		// break points are set)
		tvResults.setContentProvider(ArrayContentProvider.getInstance());
		context.get(EMFDocumentResourceMediator.class).getDocument().removeDocumentListener(documentListener);
	}

	// save custom column and filter settings
	public void saveSettings() {
		final IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(Plugin.ID);
		try {
			final Document doc = DocUtil.createDocument("list-tab"); //$NON-NLS-1$
			final Element cols = DocUtil.createChild(doc.getDocumentElement(), "columns"); //$NON-NLS-1$

			final ArrayList<TableColumn> allCols = TableViewerUtil.getColumnsInDisplayOrder(tvResults);
			for (final TableColumn col : allCols) {
				String id;
				if (requiredColumns.containsValue(col)) {
					id = getKey(requiredColumns, col);
				} else {
					id = col.getText();
				}
				saveColumn(cols, id, col);
			}

			final Element filters = DocUtil.createChild(doc.getDocumentElement(), "filters"); //$NON-NLS-1$
			if (E.notEmpty(filterByAttrName)) {
				final Element filter = DocUtil.createChild(filters, "filter"); //$NON-NLS-1$
				DocUtil.createChild(filter, "type").setTextContent("attribute"); //$NON-NLS-1$//$NON-NLS-2$
				DocUtil.createChild(filter, "condition").setTextContent(filterByAttrName); //$NON-NLS-1$
				DocUtil.createChild(filter, "emptyOption").setTextContent(filterByAttrEmptyOption.name()); //$NON-NLS-1$
			}
			if (E.notEmpty(filterByItemName)) {
				final Element filter = DocUtil.createChild(filters, "filter"); //$NON-NLS-1$
				DocUtil.createChild(filter, "type").setTextContent("item"); //$NON-NLS-1$ //$NON-NLS-2$
				DocUtil.createChild(filter, "condition").setTextContent(filterByItemName); //$NON-NLS-1$
			}

			pref.put("list-tab-xml", docToString(doc)); //$NON-NLS-1$
		} catch (final ParserConfigurationException e1) {
			e1.printStackTrace();
		} catch (final TransformerException e) {
			e.printStackTrace();
		}

		try {
			pref.flush();
		} catch (final BackingStoreException e) {
			e.printStackTrace();
		}
	}

	private String getKey(Map<String, ?> map, Object value) {
		for (final Entry<String, ?> entry : map.entrySet()) {
			if (entry.getValue().equals(value)) {
				return entry.getKey();
			}
		}
		return null;
	}

	private void saveColumn(Element eleCols, String columnName, TableColumn objCol) {
		final Element col = DocUtil.createChild(eleCols, "column"); //$NON-NLS-1$

		DocUtil.createChild(col, "attribute").setTextContent(columnName); //$NON-NLS-1$

		final Integer width = objCol.getWidth();
		DocUtil.createChild(col, "width").setTextContent(width.toString()); //$NON-NLS-1$
	}

	// load custom column and filter settings
	private void loadSettings() {
		final IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(Plugin.ID);

		final boolean restoreColumns = pref.getBoolean(ModelEditorPreferences.LIST_TAB_REMEMBER_COLUMNS, false);
		final boolean restoreFilters = pref.getBoolean(ModelEditorPreferences.LIST_TAB_REMEMBER_FILTERS, false);
		if (!restoreColumns && !restoreFilters) {
			return;
		}

		final String xml = pref.get("list-tab-xml", ""); //$NON-NLS-1$ //$NON-NLS-2$
		if (E.notEmpty(xml)) {
			try {
				final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
					.parse(new InputSource(new StringReader(xml)));
				final XPath xpath = XPathFactory.newInstance().newXPath();
				NodeList list;
				if (restoreColumns) {
					// restore columns and column widths
					list = (NodeList) xpath.evaluate("//columns/column", doc, XPathConstants.NODESET); //$NON-NLS-1$
					for (int i = 0; i < list.getLength(); i++) {
						final Element ele = (Element) list.item(i);
						TableColumn col;
						final String colName = xpath.evaluate("attribute/text()", ele); //$NON-NLS-1$
						if (colName.isEmpty()) {
							continue;
						}
						col = requiredColumns.get(colName);
						if (col == null) {
							col = addColumn(colName).getTableViewerColumn().getColumn();
						}

						// move it to the end of the list.
						final int currentIndex = TableViewerUtil.getVisibleColumnIndex(tvResults, col);
						final int[] order = tvResults.getTable().getColumnOrder();
						for (int idx = 0; idx < order.length; idx++) {
							if (order[idx] > currentIndex) {
								order[idx]--;
							} else if (order[idx] == currentIndex) {
								order[idx] = order.length - 1;
							}
						}
						tvResults.getTable().setColumnOrder(order);

						//					if ("Item".equals(colName)) { //$NON-NLS-1$
						// col = colItem;
						//					} else if ("Item".equals(colName)) { //$NON-NLS-1$
						// col = colItem;
						// }

						final String sWidth = xpath.evaluate("width/text()", ele); //$NON-NLS-1$
						try {
							col.setWidth(Integer.parseInt(sWidth));
						} catch (final Exception e) {
						}
					}
				}

				if (restoreFilters) {
					// restore filters
					list = (NodeList) xpath.evaluate("//filters/filter", doc, XPathConstants.NODESET); //$NON-NLS-1$
					for (int i = 0; i < list.getLength(); i++) {
						final Element ele = (Element) list.item(i);
						final String type = xpath.evaluate("type/text()", ele); //$NON-NLS-1$
						final String condition = xpath.evaluate("condition/text()", ele); //$NON-NLS-1$
						final String emptyOption = xpath.evaluate("emptyOption/text()", ele); //$NON-NLS-1$
						if ("item".equals(type)) { //$NON-NLS-1$
							filterByItem(condition);
						} else if ("attribute".equals(type)) { //$NON-NLS-1$
							EmptyFilterOption emptyFilterOption;
							try {
								emptyFilterOption = EmptyFilterOption.valueOf(emptyOption);
							} catch (final Exception e) {
								emptyFilterOption = EmptyFilterOption.INCLUDE;
							}
							filterByAttribute(condition, emptyFilterOption);
						}
					}
				}
			} catch (final Exception e) {
			}
		}
	}

	// @Refactor
	static private String docToString(Document doc) throws TransformerException {
		final TransformerFactory tf = TransformerFactory.newInstance();
		final Transformer transformer = tf.newTransformer();
		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
		final StringWriter writer = new StringWriter();
		transformer.transform(new DOMSource(doc), new StreamResult(writer));
		final String output = writer.getBuffer().toString().replaceAll("\n|\r", ""); //$NON-NLS-1$ //$NON-NLS-2$
		return output;
	}

	// @Refactor
	static String join(Collection<String> items, String separator) {
		final StringBuilder sb = new StringBuilder();
		for (final String item : items) {
			sb.append(item);
			sb.append(separator);
		}
		if (sb.length() > 0) {
			sb.setLength(sb.length() - separator.length());
		}
		return sb.toString();
	}

	@PostConstruct
	public void postConstruct(final CTabFolder tabFolder) {
		imageCache = new BundleImageCache(context.get(Display.class), getClass().getClassLoader());
		tabFolder.addDisposeListener(new DisposeListener() {

			@Override
			public void widgetDisposed(DisposeEvent e) {
				imageCache.dispose();
			}
		});
		try {
			imgMarkedItem = imageCache.create(Plugin.ID, "/icons/full/obj16/mark_occurrences.png"); //$NON-NLS-1$
		} catch (final Exception e2) {
			e2.printStackTrace();
		}

		documentListener = new IDocumentListener() {

			@Override
			public void documentChanged(DocumentEvent event) {
				reload();
			}

			@Override
			public void documentAboutToBeChanged(DocumentEvent event) {
			}
		};
		context.get(EMFDocumentResourceMediator.class).getDocument().addDocumentListener(documentListener);

		tabItem = new CTabItem(tabFolder, SWT.NONE, 1);

		final Composite composite = new Composite(tabFolder, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(new GridLayout(2, false));
		tabItem.setControl(composite);
		tabItem.setText(Messages.ListTab_0);

		tabItem.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Widgets_table_obj));

		final ToolBar toolBar = new ToolBar(composite, SWT.FLAT | SWT.NO_FOCUS);
		toolBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));

		{
			final ToolItem button = new ToolItem(toolBar, SWT.PUSH);
			button.setText(Messages.ListTab_addColumn + ELIPSIS);
			button.setImage(imageCache.create("/icons/full/obj16/add_column.gif")); //$NON-NLS-1$

			button.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final TitleAreaFilterDialogWithEmptyOptions dlg = createEObjectAttributePicker(Messages.ListTab_addColumn);
					dlg.setShowEmptyOptions(false);
					if (dlg.open() == Window.OK) {
						// Add Column
						final String attName = dlg.getFirstElement().toString();
						final EAttributeTableViewerColumn col = addColumn(attName);
						col.getTableViewerColumn().getColumn().pack();
						tvResults.refresh();
					}
				}
			});
		}

		{
			final ToolItem button = new ToolItem(toolBar, SWT.PUSH);
			button.setText(Messages.ListTab_resetColumns);
			button.setImage(imageCache.create("/icons/full/obj16/reset_columns.gif")); //$NON-NLS-1$

			button.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					for (final EAttributeTableViewerColumn col : optionalColumns.values()) {
						col.dispose();
					}
					optionalColumns.clear();
				}
			});
		}

		new ToolItem(toolBar, SWT.SEPARATOR);

		filterByItem = new ToolItem(toolBar, SWT.NONE);
		{

			filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS);
			filterByItem.setImage(imageCache.create("/icons/full/obj16/filter_by_item.gif")); //$NON-NLS-1$

			filterByItem.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					final TitleAreaFilterDialog dlg = createElementTypePicker(Messages.ListTab_filterByItem);
					if (dlg.open() == Window.OK) {
						filterByItem(dlg.getFirstElement().toString());
					}
				}
			});
		}

		filterByAttribute = new ToolItem(toolBar, SWT.NONE);
		{

			filterByAttribute.setText(Messages.ListTab_filterByAttribute + ELIPSIS);
			filterByAttribute.setImage(imageCache.create("/icons/full/obj16/filter_by_attribute.gif")); //$NON-NLS-1$

			filterByAttribute.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final TitleAreaFilterDialogWithEmptyOptions dlg = createEObjectAttributePicker(Messages.ListTab_filterByAttribute);
					if (dlg.open() == Window.OK) {
						filterByAttribute(dlg.getFirstElement().toString(), dlg.getEmptyFilterOption());
					}
				}
			});
		}

		{
			final ToolItem filterRemove = new ToolItem(toolBar, SWT.NONE);
			filterRemove.setText(Messages.ListTab_removeFilter);
			filterRemove.setImage(imageCache.create("/icons/full/obj16/remove_filter.png")); //$NON-NLS-1$

			filterRemove.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					filterByItemName = null;
					filterByAttrName = null;
					tvResults.setFilters(new ViewerFilter[0]);
					filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS);
					filterByAttribute.setText(Messages.ListTab_markAttribute + ELIPSIS);
				}
			});
		}

		new ToolItem(toolBar, SWT.SEPARATOR);

		{
			final E4ToolItemMenu tiCommands = new E4ToolItemMenu(toolBar, context);
			tiCommands.getToolItem().setImage(imageCache.create("/icons/full/obj16/command.gif")); //$NON-NLS-1$

			final ArrayList<String> commandIds = new ArrayList<>();
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.mark_duplicate_attributes"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.mark_duplicate_ids"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.mark_duplicate_labels"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.repair_duplicate_ids"); //$NON-NLS-1$
			commandIds.add(E4ToolItemMenu.SEPARATOR);
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.unmark"); //$NON-NLS-1$
			commandIds.add(E4ToolItemMenu.SEPARATOR);
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.autosizeColumns"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.resetToDefault"); //$NON-NLS-1$
			tiCommands.addCommands(commandIds);
		}

		tvResults = new TableViewer(composite, SWT.FULL_SELECTION);
		tvResults.getTable().setHeaderVisible(true);
		tvResults.getTable().setLinesVisible(true);

		provider = new ModelResourceContentProvider();
		tvResults.setContentProvider(provider);

		tvResults.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		((GridData) tvResults.getTable().getLayoutData()).horizontalSpan = 2;

		final Image imgForm = resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_application_form);
		final Image imgXmi = resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_chart_organisation);

		colGo = new TableViewerColumn(tvResults, SWT.NONE);
		colGo.getColumn().setText(Messages.ListTab_col_go);
		requiredColumns.put("GoTree", colGo.getColumn()); //$NON-NLS-1$
		colGo.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public Image getImage(Object element) {
				return imgForm;
			}

			@Override
			public String getText(Object element) {
				return ""; //$NON-NLS-1$
			}
		});

		colGoXmi = new TableViewerColumn(tvResults, SWT.NONE);
		colGoXmi.getColumn().setText(Messages.ListTab_col_go);
		requiredColumns.put("GoXmi", colGoXmi.getColumn()); //$NON-NLS-1$
		colGoXmi.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				return ""; //$NON-NLS-1$
			}

			@Override
			public Image getImage(Object element) {
				return imgXmi;
			}
		});

		tvResults.getTable().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				if (TableViewerUtil.isColumnClicked(tvResults, e, colGo)) {
					gotoObjectHandler.gotoEObject(ModelEditor.TAB_FORM, (EObject) TableViewerUtil.getData(tvResults, e));
				} else if (TableViewerUtil.isColumnClicked(tvResults, e, colGoXmi)) {
					gotoObjectHandler.gotoEObject(ModelEditor.TAB_XMI, (EObject) TableViewerUtil.getData(tvResults, e));
				}
			}
		});

		colMarked = new TableViewerColumn(tvResults, SWT.NONE);
		colMarked.getColumn().setWidth(16);
		colMarked.getColumn().setText(Messages.ListTab_mark);
		requiredColumns.put("Marked", colMarked.getColumn()); //$NON-NLS-1$
		colMarked.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public Image getImage(Object element) {
				Image ret = null;
				if (isHighlighted(element)) {
					try {
						ret = imgMarkedItem;
					} catch (final Exception e) {
					}
				}
				return ret;
			}

			@Override
			public String getText(Object element) {
				return ""; //$NON-NLS-1$
			}
		});

		colItem = new TableViewerColumn(tvResults, SWT.NONE);
		colItem.getColumn().setText(Messages.ListTab_col_item);
		requiredColumns.put("Item", colItem.getColumn()); //$NON-NLS-1$
		colItem.setLabelProvider(new ColumnLabelProvider_Markable() {
			@Override
			public String getText(Object element) {
				final EObject eObject = (EObject) element;
				return super.getText(eObject.eClass().getName());
			}
		});

		app.getContext().set("org.eclipse.e4.tools.active-object-viewer", this); //$NON-NLS-1$

		final EAttributeTableViewerColumn colId = new EAttributeTableViewerColumn(tvResults,
			"elementId", "elementId", context); //$NON-NLS-1$//$NON-NLS-2$
		defaultColumns.put("elementId", colId); //$NON-NLS-1$

		final EAttributeTableViewerColumn colLabel = new EAttributeTableViewerColumn_Markable(tvResults,
			"label", "label", context); //$NON-NLS-1$//$NON-NLS-2$
		defaultColumns.put("label", colLabel); //$NON-NLS-1$

		// Custom selection for marked items
		tvResults.getTable().addListener(SWT.EraseItem, new Listener() {
			@Override
			public void handleEvent(Event event) {
				event.detail &= ~SWT.HOT;
				if ((event.detail & SWT.SELECTED) == 0)
				{
					return; // / item not selected
				}

				final TableItem item = (TableItem) event.item;
				if (isHighlighted(item.getData())) {

					final Table table = (Table) event.widget;
					final int clientWidth = table.getClientArea().width;
					final GC gc = event.gc;
					// Color oldForeground = gc.getForeground();
					// Color oldBackground = gc.getBackground();

					// gc.setBackground(item.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
					gc.setForeground(item.getDisplay().getSystemColor(SWT.COLOR_RED));
					gc.fillRectangle(0, event.y, clientWidth, event.height);

					// gc.setForeground(oldForeground);
					// gc.setBackground(oldBackground);
					event.detail &= ~SWT.SELECTED;
				}
			}
		});

		tvResults.getTable().setFocus();

		for (final EAttributeTableViewerColumn col : defaultColumns.values()) {
			col.getTableViewerColumn().getColumn().setMoveable(true);
		}
		for (final TableColumn col : requiredColumns.values()) {
			col.setMoveable(true);
		}

		makeSortable(colId.getTableViewerColumn().getColumn(), new AttributeColumnLabelSorter(colId
			.getTableViewerColumn().getColumn(), "elementId")); //$NON-NLS-1$
		makeSortable(colLabel.getTableViewerColumn().getColumn(), new AttributeColumnLabelSorter(colLabel
			.getTableViewerColumn().getColumn(), "label")); //$NON-NLS-1$
		makeSortable(colItem.getColumn(), new TableViewerUtil.ColumnLabelSorter(colItem.getColumn()));
		makeSortable(colMarked.getColumn(), new TableViewerUtil.AbstractInvertableTableSorter() {

			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				final boolean mark1 = isHighlighted(e1);
				final boolean mark2 = isHighlighted(e2);
				if (mark1 && !mark2) {
					return -1;
				} else if (mark2 && !mark1) {
					return 1;
				} else {
					return 0;
				}
			}
		});

		reload();
		TableViewerUtil.refreshAndPack(tvResults);
		loadSettings();
	}

	private void makeSortable(TableColumn column, TableViewerUtil.AbstractInvertableTableSorter sorter) {
		new TableViewerUtil.TableSortSelectionListener(tvResults, column, sorter, SWT.UP, false);
	}

	public void reload() {
		tvResults.setInput(modelResource);
	}

	public TableViewer getViewer() {
		return tvResults;
	}

	public CTabItem getTabItem() {
		return tabItem;
	}

	public IEclipseContext getContext() {
		return context;
	}

	@Override
	public void highlightEObjects(Collection<EObject> items) {
		highlightedItems = items;
		tvResults.refresh();
	}

	@Override
	public List<EObject> getAllEObjects() {
		final ArrayList<EObject> list = new ArrayList<>();
		final TreeIterator<Object> itTree = EcoreUtil.getAllContents(modelResource.getRoot());
		while (itTree.hasNext()) {
			final Object object = itTree.next();
			final EObject eObject = (EObject) object;
			final EAttribute att = EmfUtil.getAttribute(eObject, "elementId"); //$NON-NLS-1$
			if (att != null) {
				list.add(eObject);
			}
		}
		return list;
	}

	@Override
	public Collection<EObject> getSelectedEObjects() {
		final ArrayList<EObject> selected = new ArrayList<>();
		for (final Object item : ((IStructuredSelection) tvResults.getSelection()).toList()) {
			if (item instanceof EObject) {
				selected.add((EObject) item);

			}
		}
		return selected;
	}

	@Override
	public void deleteEObjects(Collection<EObject> list) {
		if (list.isEmpty() == false) {
			final Command cmd = DeleteCommand.create(modelResource.getEditingDomain(), list);
			if (cmd.canExecute()) {
				modelResource.getEditingDomain().getCommandStack().execute(cmd);
			}
			reload();
		}
	}

	private TitleAreaFilterDialogWithEmptyOptions createEObjectAttributePicker(final String title) {
		// Get Attribute Names
		final HashSet<String> set = new HashSet<>();
		final Collection<EObject> allEObjects = getAllEObjects();
		for (final EObject obj : allEObjects) {
			for (final EAttribute attribute : obj.eClass().getEAllAttributes()) {
				set.add(attribute.getName());
			}
		}
		final ArrayList<String> sorted = new ArrayList<>(set);
		Collections.sort(sorted);

		// Select Attribute
		final ILabelProvider renderer = new LabelProvider() {
			@Override
			public String getText(Object element) {
				return String.valueOf(element);
			}
		};
		final TitleAreaFilterDialogWithEmptyOptions dlg = new TitleAreaFilterDialogWithEmptyOptions(
			context.get(Shell.class), renderer) {
			@Override
			protected Control createContents(Composite parent) {
				final Control ret = super.createContents(parent);
				setMessage(Messages.ListTab_selectAnAttribute);
				try {
					setTitleImage(imageCache.create(Plugin.ID, "/icons/full/wizban/attribute_wiz.gif")); //$NON-NLS-1$
				} catch (final Exception e) {
					e.printStackTrace();
				}
				setTitle(title);
				setElements(sorted.toArray(new String[0]));
				return ret;
			}
		};
		return dlg;
	}

	private TitleAreaFilterDialog createElementTypePicker(final String title) {
		// Get Attribute Names
		final HashSet<String> set = new HashSet<>();
		final Collection<EObject> allEObjects = getAllEObjects();
		for (final EObject obj : allEObjects) {
			set.add(obj.eClass().getName());
		}

		final ArrayList<String> sorted = new ArrayList<>(set);
		Collections.sort(sorted);

		final ILabelProvider renderer = new LabelProvider() {
			@Override
			public String getText(Object element) {
				return String.valueOf(element);
			}
		};
		final TitleAreaFilterDialog dlg = new TitleAreaFilterDialog(context.get(Shell.class), renderer) {

			@Override
			protected Control createContents(Composite parent) {
				final Control ret = super.createContents(parent);
				setMessage(Messages.ListTab_selectAType);
				setTitle(title);
				setElements(sorted.toArray(new String[0]));
				return ret;
			}
		};
		return dlg;
	}

	/**
	 * Adds a column if it does not already exist
	 *
	 * @param attName
	 * @return The existing or newly created column
	 */
	private EAttributeTableViewerColumn addColumn(String attName) {
		EAttributeTableViewerColumn colName = defaultColumns.get(attName);
		if (colName == null) {
			colName = optionalColumns.get(attName);
			if (colName == null) {
				colName = new EAttributeTableViewerColumn_Markable(tvResults, attName, attName, context);
				optionalColumns.put(attName, colName);
				colName.getTableViewerColumn().getColumn().setMoveable(true);
				makeSortable(colName.getTableViewerColumn().getColumn(), new AttributeColumnLabelSorter(colName
					.getTableViewerColumn().getColumn(), attName));
				tvResults.refresh();
			}
		}
		return colName;
	}

	static private class AttributeColumnLabelSorter extends TableViewerUtil.ColumnLabelSorter {

		private final String attName;

		AttributeColumnLabelSorter(TableColumn col, String attName) {
			super(col);
			this.attName = attName;
		}

		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			// if either is boolean, use boolean value, otherwise use text value
			final ATT_TYPE e1Type = EAttributeEditingSupport.getAttributeType(e1, attName);
			final ATT_TYPE e2Type = EAttributeEditingSupport.getAttributeType(e2, attName);
			if (e1Type == ATT_TYPE.BOOLEAN || e2Type == ATT_TYPE.BOOLEAN) {
				final Boolean b1 = (Boolean) EmfUtil.getAttributeValue((EObject) e1, attName);
				final Boolean b2 = (Boolean) EmfUtil.getAttributeValue((EObject) e2, attName);
				if (b1 == null && b2 != null) {
					return -2;
				} else if (b2 == null && b1 != null) {
					return 2;
				} else {
					return b1.compareTo(b2);
				}
			}
			return super.compare(viewer, e1, e2);
		}
	}

	private class EAttributeTableViewerColumn_Markable extends EAttributeTableViewerColumn {
		public EAttributeTableViewerColumn_Markable(TableViewer tvResults, String label, String attName,
			IEclipseContext context) {
			super(tvResults, label, attName, context);
		}

		@Override
		public Color getBackground(Object element) {
			Color ret;
			if (isHighlighted(element)) {
				return ret = tvResults.getTable().getDisplay().getSystemColor(SWT.COLOR_YELLOW);
			}
			ret = super.getBackground(element);
			return ret;
		}
	}

	private class ColumnLabelProvider_Markable extends ColumnLabelProvider {
		@Override
		public Color getBackground(Object element) {
			Color ret;
			if (isHighlighted(element)) {
				ret = tvResults.getTable().getDisplay().getSystemColor(SWT.COLOR_YELLOW);
			} else {
				ret = super.getBackground(element);
			}
			return ret;
		}
	}

	@Override
	public EditingDomain getEditingDomain() {
		return modelResource.getEditingDomain();
	}

	public boolean isHighlighted(Object element) {
		return highlightedItems != null && highlightedItems.contains(element);
	}

	private void filterByItem(String name) {
		filterByItemName = name;
		filterByAttrName = null;
		filterByAttrEmptyOption = null;
		mapId_Object.clear();
		final ArrayList<EObject> filtered = new ArrayList<>();
		for (final EObject object : getAllEObjects()) {
			if (object.eClass().getName().equals(filterByItemName)) {
				filtered.add(object);
				// filter.setText(Messages.ListTab_7 +
				// attFilter);

			}

			final ViewerFilter viewerFilter = new ViewerFilter() {

				@Override
				public boolean select(Viewer viewer, Object parentElement, Object element) {
					return filtered.contains(element);
				}

			};
			tvResults.setFilters(new ViewerFilter[] { viewerFilter });
			filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS + "(" + filterByItemName + ")"); //$NON-NLS-1$//$NON-NLS-2$
			filterByAttribute.setText(Messages.ListTab_filterByAttribute + ELIPSIS);
		}
	}

	private void filterByAttribute(String name, final EmptyFilterOption emptyOption) {
		filterByAttrName = name;
		filterByAttrEmptyOption = emptyOption;
		filterByItemName = null;
		mapId_Object.clear();
		final ArrayList<EObject> filtered = new ArrayList<>();
		for (final EObject object : getAllEObjects()) {
			if (EmfUtil.getAttribute(object, filterByAttrName) != null) {
				filtered.add(object);
				final ViewerFilter viewerFilter = new ViewerFilter() {

					@Override
					public boolean select(Viewer viewer, Object parentElement, Object element) {
						// if filtering on attribute, always
						// reject if not defined for model
						// element
						if (EmfUtil.getAttribute((EObject) element, filterByAttrName) == null) {
							return false;
						}
						switch (emptyOption) {
						case EXCLUDE:
							if (E.isEmpty(EmfUtil.getAttributeValue((EObject) element, filterByAttrName))) {
								return false;
							}
							return filtered.contains(element);
						case ONLY:
							if (E.notEmpty(EmfUtil.getAttributeValue((EObject) element, filterByAttrName))) {
								return false;
							}
							return true;
						default:
						case INCLUDE:
							if (E.isEmpty(EmfUtil.getAttributeValue((EObject) element, filterByAttrName))) {
								return true;
							}
							return filtered.contains(element);
						}
					}
				};
				tvResults.setFilters(new ViewerFilter[] { viewerFilter });
				filterByAttribute.setText(Messages.ListTab_filterByAttribute + ELIPSIS + "(" + filterByAttrName + ")"); //$NON-NLS-1$//$NON-NLS-2$
				filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS);

			}
		}
		final TableViewerColumn viewerColumn = addColumn(filterByAttrName).getTableViewerColumn();
		viewerColumn.getColumn().pack();
	}

	@Override
	public void autosizeContent() {
		for (final TableColumn col : tvResults.getTable().getColumns()) {
			col.pack();
			if (col.getWidth() < 10) {
				col.setWidth(10);
			}
		}
	}

	@Override
	public void resetToDefault() {
		for (final EAttributeTableViewerColumn col : optionalColumns.values()) {
			col.dispose();
		}
		optionalColumns.clear();

		TableViewerUtil.resetColumnOrder(tvResults);
		TableViewerUtil.packAllColumns(tvResults);
	}

}
