/*******************************************************************************
 * Copyright (c) 2016, 2020 Chalmers | University of Gothenburg, rt-labs and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *   
 * SPDX-License-Identifier: EPL-2.0
 *   
 * Contributors:
 *     Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
 *     Chalmers | University of Gothenburg - additional features, updated API
 *     Fredrik Johansson and Themistoklis Ntoukolis - initial implementation of the Matrix View
 *******************************************************************************/
package org.eclipse.capra.ui.matrix.views;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.eclipse.capra.core.adapters.Connection;
import org.eclipse.capra.core.adapters.TraceMetaModelAdapter;
import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
import org.eclipse.capra.core.handlers.IArtifactHandler;
import org.eclipse.capra.core.handlers.IArtifactUnpacker;
import org.eclipse.capra.core.helpers.ArtifactHelper;
import org.eclipse.capra.core.helpers.EMFHelper;
import org.eclipse.capra.core.helpers.ExtensionPointHelper;
import org.eclipse.capra.ui.helpers.SelectionSupportHelper;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixBodyToolTip;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixColumnHeaderDataProvider;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixDataProvider;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixHeaderToolTip;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixRowHeaderDataProvider;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommand;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hover.HoverLayer;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.resize.action.ColumnResizeCursorAction;
import org.eclipse.nebula.widgets.nattable.resize.action.RowResizeCursorAction;
import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEventMatcher;
import org.eclipse.nebula.widgets.nattable.resize.event.RowResizeEventMatcher;
import org.eclipse.nebula.widgets.nattable.resize.mode.ColumnResizeDragMode;
import org.eclipse.nebula.widgets.nattable.resize.mode.RowResizeDragMode;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.ui.action.IMouseAction;
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.ViewPart;

/**
 * Provides a traceability matrix view, i.e., a tabular view of how the
 * different artifacts are related.
 * <p>
 * The traceability matrix shows all selected artifacts and the artifacts they
 * are directly connected to via trace links. It also displays the type of link
 * between the artifacts, allows navigating to the artifact by double-clicking
 * the column header, and shows information about the artifact and the trace
 * link as a tool-tip. It is also possible to export the currently viewed
 * traceability matrix as a Microsoft Excel file.
 * <p>
 * The implementation uses NatTable.
 * 
 * @author Fredrik Johansson
 * @author Themistoklis Ntoukolis
 * @author Jan-Philipp Steghöfer
 *
 */
public class TraceabilityMatrixView extends ViewPart {

	/**
	 * The ID of the view as specified by the extension.
	 */
	public static final String ID = "org.eclipse.capra.ui.matrix.views.TraceabilityMatrixView";

	private static final String SAME_LABEL = "SAME"; // When column header and row header are the same
	private static final String LINK_LABEL = "LINKED"; // When there is a link between

	private NatTable traceMatrixTable;
	private Action refreshAction, showAllAction, exportExcelAction;
	private Composite parent;

	private ResourceSet resourceSet = new ResourceSetImpl();

	private final TraceMetaModelAdapter traceAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
	private TraceMetaModelAdapter metamodelAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
	private TracePersistenceAdapter persistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get();
	private EObject traceModel = null;
	private EObject artifactModel = null;
	private ArtifactHelper artifactHelper;

	private TraceabilityMatrixDataProvider bodyDataProvider;
	private BodyLayerStack bodyLayer;

	private List<Object> selectedModels = new ArrayList<>();
	private boolean selectionModified = false;

	/**
	 * Listener to detect changes in the selection of other views. Redraws the table
	 * if necessary.
	 */
	private ISelectionListener selectionListener = new ISelectionListener() {
		@Override
		public void selectionChanged(IWorkbenchPart part, ISelection selection) {
			populateSelectedModels(part, selection);
			if (traceMatrixTable != null && selectionModified) {
				updateTraceabilityMatrix();
			}
		}
	};

	/**
	 * Color configuration. First changing the background color for the labels.
	 * After that is the coloring for hovering.
	 */
	private AbstractRegistryConfiguration capraNatTableStyleConfiguration = new AbstractRegistryConfiguration() {
		@Override
		public void configureRegistry(IConfigRegistry configRegistry) {
			// Black background for cells where there should not be any links
			Style cellStyle = new Style();
			cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_BLACK);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle, DisplayMode.NORMAL,
					SAME_LABEL);

			// Green background for cells where there is a link.
			cellStyle = new Style();
			cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_GREEN);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle, DisplayMode.NORMAL,
					LINK_LABEL);

			// Style that is applied when cells are hovered
			Style style = new Style();
			style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_YELLOW);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, style, DisplayMode.HOVER);

			// Style that is applied when selected cells are hovered
			style = new Style();
			style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_GREEN);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, style, DisplayMode.SELECT_HOVER);
		}
	};

	/**
	 * Making it possible to resize columns and rows.
	 */
	private AbstractUiBindingConfiguration capraUiBindingConfiguration = new AbstractUiBindingConfiguration() {

		@Override
		public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
			uiBindingRegistry.registerFirstMouseMoveBinding(
					new ColumnResizeEventMatcher(SWT.NONE, GridRegion.ROW_HEADER, 0), new ColumnResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(
					new ColumnResizeEventMatcher(SWT.NONE, GridRegion.ROW_HEADER, 1), new ColumnResizeDragMode());
			uiBindingRegistry.registerFirstMouseMoveBinding(
					new RowResizeEventMatcher(SWT.NONE, GridRegion.COLUMN_HEADER, 0), new RowResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(
					new RowResizeEventMatcher(SWT.NONE, GridRegion.COLUMN_HEADER, 1), new RowResizeDragMode());
			// Make the corner on the top left also resizable
			uiBindingRegistry.registerFirstMouseMoveBinding(
					new ColumnResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 0), new ColumnResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(new ColumnResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 1),
					new ColumnResizeDragMode());
			uiBindingRegistry.registerFirstMouseMoveBinding(new RowResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 0),
					new RowResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(new RowResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 1),
					new RowResizeDragMode());
		}
	};

	/**
	 * Setting labels based on links and later use the labels for customized layout.
	 */
	private IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
		@Override
		public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
			int columnIndex = bodyLayer.getColumnIndexByPosition(columnPosition);
			int rowIndex = bodyLayer.getRowIndexByPosition(rowPosition);
			if (sameElement(bodyDataProvider.getRow(rowIndex), bodyDataProvider.getColumn(columnIndex))) {
				configLabels.addLabel(SAME_LABEL);
			} else {
				String cell_text = (String) bodyDataProvider.getDataValue(columnIndex, rowIndex);
				if (!cell_text.equals("")) {
					configLabels.addLabel(LINK_LABEL);
				}
			}
		}
	};

	@Override
	public void createPartControl(Composite parent) {
		this.parent = parent;
		updateTraceabilityMatrix();

		makeActions();
		contributeToActionBars();

		// Adding support to react to selections in other views
		getViewSite().getPage().addSelectionListener(selectionListener);

	}

	@Override
	public void dispose() {
		getViewSite().getPage().removeSelectionListener(selectionListener);
		traceMatrixTable.dispose();
		traceMatrixTable = null;
		super.dispose();
	}

	@Override
	public void setFocus() {
		if (traceMatrixTable != null) {
			traceMatrixTable.setFocus();
		}
	}

	/**
	 * Updates the traceability matrix with data from the current selection or with
	 * data from all traced artifacts if the selection is empty. In essence, it
	 * disposes of the current table and creates a new one with the current data.
	 * Also layouts the parent to make sure the table is displayed correctly.
	 */
	@SuppressWarnings("unchecked")
	protected void updateTraceabilityMatrix() {
		EObject selectedObject;
		List<Connection> traces = new ArrayList<>();

		this.artifactModel = persistenceAdapter.getArtifactWrappers(resourceSet);
		this.artifactHelper = new ArtifactHelper(this.artifactModel);
		this.traceModel = persistenceAdapter.getTraceModel(resourceSet);

		if (!selectedModels.isEmpty()) {
			// Show the matrix for the selected objects
			for (Object model : selectedModels) {
				IArtifactHandler<Object> handler = (IArtifactHandler<Object>) this.artifactHelper.getHandler(model)
						.orElse(null);
				if (handler != null) {
					Object unpackedElement = null;
					if (handler instanceof IArtifactUnpacker) {
						unpackedElement = IArtifactUnpacker.class.cast(handler).unpack(model);
					} else {
						unpackedElement = model;
					}
					EObject wrappedElement = handler.createWrapper(unpackedElement, this.artifactModel);
					if (isInTraceModel(wrappedElement)) {
						selectedObject = wrappedElement;
						traces.addAll(this.traceAdapter.getConnectedElements(selectedObject, this.traceModel));
					}
				}
			}
		} else {
			// Without a selection, show a matrix of all traces
			if (traceModel != null) {
				traces = metamodelAdapter.getAllTraceLinks(traceModel);
			}
		}
		// If the current selection does not contain elements from the trace model, it
		// is possible that the list of traces is empty. By catching this case, we only
		// update the traceability matrix when there is actually something to show.
		if (!traces.isEmpty()) {
			if (traceMatrixTable != null) {
				traceMatrixTable.dispose();
				traceMatrixTable = null;
			}
			// Creating data providers for body, column and row. The data provider for the
			// body provides the data which will be shown in the cells. For columns and
			// rows, the labels are created.
			this.bodyDataProvider = new TraceabilityMatrixDataProvider(traces, this.traceModel, this.traceAdapter);
			IDataProvider colHeaderDataProvider = new TraceabilityMatrixColumnHeaderDataProvider(
					this.bodyDataProvider.getColumns(), artifactHelper);
			IDataProvider rowHeaderDataProvider = new TraceabilityMatrixRowHeaderDataProvider(
					this.bodyDataProvider.getRows(), artifactHelper);

			// Putting the data providers to their respective stacks
			this.bodyLayer = new BodyLayerStack(this.bodyDataProvider);
			ColumnHeaderLayerStack columnHeaderLayer = new ColumnHeaderLayerStack(colHeaderDataProvider);
			RowHeaderLayerStack rowHeaderLayer = new RowHeaderLayerStack(rowHeaderDataProvider);
			DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(colHeaderDataProvider,
					rowHeaderDataProvider);
			CornerLayer cornerLayer = new CornerLayer(new DataLayer(cornerDataProvider), rowHeaderLayer,
					columnHeaderLayer);

			// Adding the labels to the body (cells).
			bodyLayer.setConfigLabelAccumulator(cellLabelAccumulator);

			// Putting all the layers to the grid.
			GridLayer gridLayer = new GridLayer(this.bodyLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);
			gridLayer.addConfiguration(capraUiBindingConfiguration);

			// Creating the table
			traceMatrixTable = new NatTable(parent, gridLayer, false);

			// Adding Configuration to the table
			traceMatrixTable.addConfiguration(new DefaultNatTableStyleConfiguration());
			traceMatrixTable.addConfiguration(this.capraNatTableStyleConfiguration);
			traceMatrixTable.configure();

			// Adding the tool tips
			attachToolTip();

			// Finally, make sure everything is in the right place.
			parent.layout();
		}
	}

	// ********************************************************************

	/**
	 * Populates the {@link #selectedModels} property with the objects included in
	 * the provided selection.
	 * 
	 * @param part      the workbench part whose selection provider is used
	 * @param selection the selection from which the elements are extracted
	 */
	private void populateSelectedModels(IWorkbenchPart part, ISelection selection) {
		List<Object> newSelectedObjects = SelectionSupportHelper.extractSelectedElements(selection, part);
		if (!listEqualsIgnoreOrder(selectedModels, newSelectedObjects)) {
			selectionModified = true;
			selectedModels.clear();
			selectedModels.addAll(newSelectedObjects);
		} else {
			selectionModified = false;
		}
	}

	/**
	 * Compares to lists ignoring order and duplicates.
	 * 
	 * @param <T>   the type of the two lists
	 * @param list1 the first list to compare
	 * @param list2 the second list to compare
	 * @return <code>true</code> if the lists are the same, <code>false</code>
	 *         otherwise
	 */
	private <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
		return new HashSet<>(list1).equals(new HashSet<>(list2));
	}

	/**
	 * Create the tool tip instances.
	 */
	private void attachToolTip() {
		new TraceabilityMatrixBodyToolTip(this.traceMatrixTable, this.bodyDataProvider, this.artifactHelper);
		new TraceabilityMatrixHeaderToolTip(this.traceMatrixTable, this.bodyDataProvider, this.artifactHelper);
	}

	/**
	 * Opens an editor for the provided {@code element} based on the URL stored in
	 * the artifact.
	 * 
	 * @param element the element for which an editor should be opened
	 * @throws PartInitException if the editor could not be initialised
	 */
	private void openEditor(EObject element) throws PartInitException {
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		try {
			URI uri = new URI(artifactHelper.getArtifactLocation(element));
			IPath artifactPath = new Path(uri.getPath());
			artifactPath = artifactPath.removeFirstSegments(1);
			IFile artifactFile = ResourcesPlugin.getWorkspace().getRoot().getFile(artifactPath);
			IDE.openEditor(page, artifactFile);
		} catch (URISyntaxException e) {
		}
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(refreshAction);
		manager.add(showAllAction);
		manager.add(new Separator());
		manager.add(exportExcelAction);
	}

	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(refreshAction);
		manager.add(showAllAction);
	}

	private void makeActions() {
		refreshAction = new Action() {
			@Override
			public void run() {
				updateTraceabilityMatrix();
			}
		};
		refreshAction.setText("Refresh");
		refreshAction.setToolTipText("Refresh");

		showAllAction = new Action() {
			@Override
			public void run() {
				selectedModels.clear();
				updateTraceabilityMatrix();
			}
		};
		showAllAction.setText("Show all");
		showAllAction.setToolTipText("Show all");

		exportExcelAction = new Action() {
			@Override
			public void run() {
				ExportCommand cmd = new ExportCommand(traceMatrixTable.getConfigRegistry(),
						traceMatrixTable.getShell());
				traceMatrixTable.doCommand(cmd);
			}
		};
		exportExcelAction.setText("Export to Excel...");
		exportExcelAction.setToolTipText("Exports the currently shown traceability matrix as an Excel file.");

	}

	private boolean sameElement(EObject first, EObject second) {
		return EMFHelper.getIdentifier(first).equals(EMFHelper.getIdentifier(second));
	}

	private boolean isElementInList(List<EObject> list, EObject obj) {
		for (EObject next : list) {
			if (sameElement(obj, next)) {
				return true;
			}
		}
		return false;
	}

	private List<EObject> getAllUniqueElements(List<Connection> traces) {
		List<EObject> inserted = new ArrayList<>();
		for (Connection trace : traces) {
			EObject element = trace.getOrigin();
			if (inserted.isEmpty()) {
				inserted.add(element);
			} else {
				if (!isElementInList(inserted, element)) {
					inserted.add(element);
				}
			}
			List<EObject> targets = trace.getTargets();
			for (EObject target : targets) {
				if (!isElementInList(inserted, target)) {
					inserted.add(target);
				}
			}
		}
		return inserted;
	}

	/**
	 * Checks if the given {@code artifact} is part of the trace model.
	 * 
	 * @param artifact the artifact whose presence is checked
	 * @return {@code true} if the artifact is contained in the trace model,
	 *         {@code false} otherwise
	 */
	private boolean isInTraceModel(EObject artifact) {
		List<EObject> artifacts = getAllUniqueElements(metamodelAdapter.getAllTraceLinks(traceModel));

		if (isElementInList(artifacts, artifact)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Class for the column stack
	 */
	private class ColumnHeaderLayerStack extends AbstractLayerTransform {

		public ColumnHeaderLayerStack(IDataProvider dataProvider) {
			DataLayer dataLayer = new DataLayer(dataProvider);
			ColumnHeaderLayer colHeaderLayer = new ColumnHeaderLayer(dataLayer, TraceabilityMatrixView.this.bodyLayer,
					TraceabilityMatrixView.this.bodyLayer.getSelectionLayer());

			// Adding double click to the column header
			colHeaderLayer.addConfiguration(new AbstractUiBindingConfiguration() {

				@Override
				public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
					uiBindingRegistry.registerDoubleClickBinding(MouseEventMatcher.columnHeaderLeftClick(0),
							new IMouseAction() {

								@Override
								public void run(NatTable natTable, MouseEvent event) {
									try {
										int columnPosition = natTable.getColumnPositionByX(event.x);
										int columnIndex = natTable.getColumnIndexByPosition(columnPosition);
										EObject element = bodyDataProvider.getColumn(columnIndex);
										openEditor(element);
									} catch (PartInitException e) {
										// Deliberately do nothing.
									}
								}
							});
				}
			});

			setUnderlyingLayer(colHeaderLayer);
		}
	}

	/**
	 * Class for the row stack
	 */
	private class RowHeaderLayerStack extends AbstractLayerTransform {

		public RowHeaderLayerStack(IDataProvider dataProvider) {
			DataLayer dataLayer = new DataLayer(dataProvider, 50, 20);
			RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(dataLayer, TraceabilityMatrixView.this.bodyLayer,
					TraceabilityMatrixView.this.bodyLayer.getSelectionLayer());

			// Adding double click to the row header
			rowHeaderLayer.addConfiguration(new AbstractUiBindingConfiguration() {

				@Override
				public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
					uiBindingRegistry.registerDoubleClickBinding(MouseEventMatcher.rowHeaderLeftClick(0),
							new IMouseAction() {

								@Override
								public void run(NatTable natTable, MouseEvent event) {
									try {
										int rowPosition = natTable.getRowPositionByY(event.y);
										int rowIndex = natTable.getRowIndexByPosition(rowPosition);
										EObject element = bodyDataProvider.getRow(rowIndex);
										openEditor(element);
									} catch (PartInitException e) {
										// Deliberately do nothing.
									}
								}

							});
				}
			});
			setUnderlyingLayer(rowHeaderLayer);
		}
	}

	/**
	 * Class for the body stack
	 */
	private class BodyLayerStack extends AbstractLayerTransform {
		private SelectionLayer selectionLayer;

		public BodyLayerStack(IDataProvider dataProvider) {
			DataLayer bodyDataLayer = new DataLayer(dataProvider);
			HoverLayer bodyHoverLayer = new HoverLayer(bodyDataLayer);
			this.selectionLayer = new SelectionLayer(bodyHoverLayer);
			ViewportLayer viewportLayer = new ViewportLayer(this.selectionLayer);
			setUnderlyingLayer(viewportLayer);
		}

		public SelectionLayer getSelectionLayer() {
			return this.selectionLayer;
		}
	}
}
