/*******************************************************************************
 * Copyright (c) 2004, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     WindRiver - Bug 192028 [Memory View] Memory view does not
 *                 display memory blocks that do not reference IDebugTarget
 *     ARM - Bug 192028 [Memory View] Memory view does not
 *                 display memory blocks that do not reference IDebugTarget
 *     WindRiver - Bug 216509 [Memory View] typo, s/isMeomryBlockRemoved/isMemoryBlockRemoved
 *     Wind River Systems - Ted Williams - [Memory View] Memory View: Workflow Enhancements (Bug 215432)
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.memory;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.views.memory.renderings.CreateRendering;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.memory.IMemoryRendering;
import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
import org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService;
import org.eclipse.debug.ui.memory.IResettableMemoryRendering;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Adapter;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.UIJob;

/**
 * Represents a rendering view pane in the Memory View. This hosts the memory
 * view tabs in the view.
 *
 * @since 3.1
 *
 */
public class RenderingViewPane extends AbstractMemoryViewPane implements IMemoryRenderingContainer {

	public static final String RENDERING_VIEW_PANE_ID = DebugUIPlugin.getUniqueIdentifier() + ".MemoryView.RenderingViewPane"; //$NON-NLS-1$

	private Hashtable<IMemoryBlock, CTabFolder> fTabFolderForMemoryBlock = new Hashtable<>();
	private Hashtable<CTabFolder, IMemoryBlock> fMemoryBlockFromTabFolder = new Hashtable<>();

	private ViewPaneRenderingMgr fRenderingMgr;

	private IMemoryRenderingSite fRenderingSite;
	private Set<IMemoryRendering> fAddedRenderings = new HashSet<>();
	private Set<IMemoryBlock> fAddedMemoryBlocks = new HashSet<>();

	private boolean fCanAddRendering = true;
	private boolean fCanRemoveRendering = true;

	/**
	 * @param parent is the view hosting this view pane
	 * @param paneId is the identifier assigned by the Memory View
	 *
	 *            Pane id is assigned with the following format. Rendering view
	 *            pane created has its id assigned to
	 *            org.eclipse.debug.ui.MemoryView.RenderingViewPane.#. # is a
	 *            number indicating the order of which the rendering view pane
	 *            is created. First rendering view pane created will have its id
	 *            assigned to
	 *            org.eclipse.debug.ui.MemoryView.RenderingViewPane.1. Second
	 *            rendering view pane created will have its id assigned to
	 *            org.eclipse.debug.ui.MemoryView.RenderingViewPane.2. and so
	 *            on. View pane are created from left to right by the Memory
	 *            View.
	 *
	 */
	public RenderingViewPane(IViewPart parent) {
		super(parent);

		if (parent instanceof IMemoryRenderingSite) {
			fRenderingSite = (IMemoryRenderingSite) parent;
		} else {
			DebugUIPlugin.logErrorMessage("Parent for the rendering view pane is invalid."); //$NON-NLS-1$
		}
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.internal.core.memory.IMemoryBlockListener#MemoryBlockAdded
	 * (org.eclipse.debug.core.model.IMemoryBlock)
	 */
	@Override
	public void memoryBlocksAdded(final IMemoryBlock[] memoryBlocks) {
		Display.getDefault().asyncExec(() -> {

			if (isDisposed()) {
				return;
			}

			// check condition before doing anything
			if (memoryBlocks == null || memoryBlocks.length <= 0) {
				return;
			}

			for (int i = 0; i < memoryBlocks.length; i++) {
				IMemoryBlock memory = memoryBlocks[i];

				if (!fTabFolderForMemoryBlock.containsKey(memory)) {
					createFolderForMemoryBlock(memory);
				}
				fAddedMemoryBlocks.add(memory);
				updateToolBarActionsEnablement();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.memory.IMemoryBlockListener#
	 * MemoryBlockRemoved(org.eclipse.debug.core.model.IMemoryBlock)
	 */
	@Override
	public void memoryBlocksRemoved(final IMemoryBlock[] memoryBlocks) {
		Display.getDefault().asyncExec(() -> {
			for (int j = 0; j < memoryBlocks.length; j++) {
				IMemoryBlock mbRemoved = memoryBlocks[j];
				if (fTabFolderForMemoryBlock == null) {
					return;
				}

				// get all renderings from this memory block and remove them
				// from the view
				IMemoryRendering[] renderings = fRenderingMgr.getRenderingsFromMemoryBlock(mbRemoved);

				for (int k = 0; k < renderings.length; k++) {
					removeMemoryRendering(renderings[k]);
				}

				// remove a the tab folder if the memory block is removed
				CTabFolder tabFolder = fTabFolderForMemoryBlock.get(mbRemoved);

				if (tabFolder == null) {
					continue;
				}

				fTabFolderForMemoryBlock.remove(mbRemoved);
				fMemoryBlockFromTabFolder.remove(tabFolder);
				IMemoryBlockRetrieval retrieve = MemoryViewUtil.getMemoryBlockRetrieval(mbRemoved);
				if (retrieve != null) {
					if (fTabFolderForDebugView.contains(tabFolder)) {
						fTabFolderForDebugView.remove(MemoryViewUtil.getHashCode(retrieve));
					}
				}

				if (!tabFolder.isDisposed()) {
					// dispose all view tabs belonging to the tab folder
					CTabItem[] items = tabFolder.getItems();

					for (int i = 0; i < items.length; i++) {
						disposeTab(items[i]);
					}

					// dispose the tab folder
					tabFolder.dispose();

					// if this is the top control
					if (tabFolder == fStackLayout.topControl) {

						// if memory view is visible and have a selection
						// follow memory view's selection

						ISelection selection = DebugUIPlugin.getActiveWorkbenchWindow().getSelectionService()
								.getSelection(IDebugUIConstants.ID_MEMORY_VIEW);
						IMemoryBlock mbToSelect = getMemoryBlock(selection);

						if (mbToSelect != null) {
							// memory view may not have got the event and is
							// still displaying
							// the deleted memory block
							if (mbToSelect != mbRemoved) {
								handleMemoryBlockSelection(null, mbToSelect);
							} else if ((MemoryViewUtil.getMemoryBlockManager().getMemoryBlocks(retrieve).length > 0)) {
								mbToSelect = MemoryViewUtil.getMemoryBlockManager().getMemoryBlocks(retrieve)[0];
								handleMemoryBlockSelection(null, mbToSelect);
							} else {
								emptyFolder();
							}
						} else if (MemoryViewUtil.getMemoryBlockManager().getMemoryBlocks(retrieve).length > 0) { // get
																													// to
																													// the
																													// next
																													// folder
							mbToSelect = MemoryViewUtil.getMemoryBlockManager().getMemoryBlocks(retrieve)[0];
							handleMemoryBlockSelection(null, mbToSelect);
						} else {
							emptyFolder();

						}
					}

					// if not the top control
					// no need to do anything
				}

				fAddedMemoryBlocks.remove(mbRemoved);
				updateToolBarActionsEnablement();
			}
		});

	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.
	 * IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	@Override
	public void selectionChanged(final IWorkbenchPart part, final ISelection selection) {
		if (isDisposed()) {
			return;
		}

		// do not schedule job if any of these conditions are true
		if (part == RenderingViewPane.this) {
			return;
		}

		if (!(selection instanceof IStructuredSelection)) {
			return;
		}

		if (selection == AbstractMemoryViewPane.EMPTY) {
			return;
		}

		UIJob job = new UIJob("RenderingViewPane selectionChanged") { //$NON-NLS-1$

			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {
				try {

					if (isDisposed()) {
						return Status.OK_STATUS;
					}

					if (selection.isEmpty()) {
						// if the event comes from Memory View
						// pick empty tab folder as the memory view is no longer
						// displaying anything
						if (part.getSite().getId().equals(IDebugUIConstants.ID_MEMORY_VIEW)) {
							if (part == getMemoryRenderingSite().getSite().getPart()) {
								IMemoryViewTab lastViewTab = getTopMemoryTab();

								if (lastViewTab != null) {
									lastViewTab.setEnabled(false);
								}

								emptyFolder();
							}
						}

						// do not do anything if there is no selection
						// In the case when a debug adpater fires a debug event
						// incorrectly, Launch View sets
						// selection to nothing. If the view tab is disabled, it
						// erases all the "delta" information
						// in the content. This may not be desirable as it will
						// cause memory to show up as
						// unchanged when it's actually changed. Do not disable
						// the view tab until there is a
						// valid selection.

						return Status.OK_STATUS;
					}

					// back up current view tab
					IMemoryViewTab lastViewTab = getTopMemoryTab();

					if (!(selection instanceof IStructuredSelection)) {
						return Status.OK_STATUS;
					}

					Object elem = ((IStructuredSelection) selection).getFirstElement();

					if (elem instanceof IMemoryBlock) {
						// if the selection event comes from this view
						if (part == getMemoryRenderingSite()) {
							// find the folder associated with the given
							// IMemoryBlockRetrieval
							IMemoryBlock memBlock = (IMemoryBlock) elem;

							// should never get here... added code for safety
							if (fTabFolderForMemoryBlock == null) {
								if (lastViewTab != null) {
									lastViewTab.setEnabled(false);
								}

								emptyFolder();
								return Status.OK_STATUS;
							}

							handleMemoryBlockSelection(lastViewTab, memBlock);
						}
					}
				} catch (SWTException se) {
					DebugUIPlugin.log(se);
				}
				return Status.OK_STATUS;
			}
		};
		job.setSystem(true);
		job.schedule();
	}

	public void handleMemoryBlockSelection(final IMemoryViewTab lastViewTab, final IMemoryBlock memBlock) {
		// Do not check if the debug target of mb is removed
		// We should not get into this method if the debug target of the memory
		// block is terminated
		// Memory Block Manager gets the terminate event and would have removed
		// all memory blocks
		// associated with the debug target
		// Therefore, we will never try to set a selection to a memory block
		// whose target is terminated

		// check current memory block
		CTabFolder currentFolder = (CTabFolder) fStackLayout.topControl;
		if (currentFolder != null && !currentFolder.isDisposed()) {
			IMemoryBlock currentBlk = fMemoryBlockFromTabFolder.get(currentFolder);
			if (currentBlk != null) {
				if (currentBlk == memBlock) {
					return;
				}
			}
		}

		if (getTopMemoryTab() != null) {
			if (getTopMemoryTab().getRendering().getMemoryBlock() == memBlock) {
				return;
			}
		}

		// if we've got a tabfolder to go with the IMemoryBlock, display
		// it
		if (fTabFolderForMemoryBlock.containsKey(memBlock)) {
			if (fStackLayout.topControl != fTabFolderForMemoryBlock.get(memBlock)) {
				setTabFolder(fTabFolderForMemoryBlock.get(memBlock));
				fViewPaneCanvas.layout();
			}
		} else { // otherwise, add a new one
			CTabFolder folder = createTabFolder(fViewPaneCanvas);

			fTabFolderForMemoryBlock.put(memBlock, folder);
			fMemoryBlockFromTabFolder.put(folder, memBlock);
			setTabFolder(fTabFolderForMemoryBlock.get(memBlock));
			fViewPaneCanvas.layout();
			fAddedMemoryBlocks.add(memBlock);

			newCreateRenderingForFolder(memBlock, folder);
		}

		// restore view tabs
		IMemoryRendering[] renderings = fRenderingMgr.getRenderingsFromMemoryBlock(memBlock);
		CTabFolder toDisplay = (CTabFolder) fStackLayout.topControl;

		// if only CreateRendering is present, restore renderings
		if (isRestoreViewTabs(toDisplay)) {
			restoreViewTabs(renderings);
		}

		// disable last view tab as it becomes hidden
		IMemoryViewTab newViewTab = getTopMemoryTab();

		if (lastViewTab != null && lastViewTab != newViewTab) {
			lastViewTab.setEnabled(false);
		}

		if (newViewTab != null) {
			// if new view tab is not already enabled, enable it
			if (!newViewTab.isEnabled()) {
				// if the view tab is visible, enable it
				if (fVisible) {
					newViewTab.setEnabled(fVisible);
				}
			}
		}

		IMemoryViewTab viewTab = getTopMemoryTab();
		if (viewTab != null) {
			setRenderingSelection(viewTab.getRendering());
		}

		// set toolbar actions enabled/disabled
		updateToolBarActionsEnablement();
	}

	private boolean isRestoreViewTabs(CTabFolder folder) {
		if (canAddRendering()) {
			return (folder.getItemCount() == 1 && getTopMemoryTab().getRendering() instanceof CreateRendering);
		} else {
			return (folder.getItemCount() == 0);
		}
	}

	private int getIndexOfCreateRenderingTab(CTabFolder folder) {
		for (int i = 0; i < folder.getItemCount(); i++) {
			if (folder.getItem(i).getData() instanceof MemoryViewTab && ((MemoryViewTab) folder.getItem(i).getData()).getRendering() instanceof CreateRendering) {
				return i;
			}
		}

		return -1;
	}

	public void memoryBlockRenderingAdded(final IMemoryRendering rendering) {

		Display.getDefault().asyncExec(() -> {

			if (isDisposed()) {
				return;
			}

			if (fAddedRenderings.contains(rendering)) {
				return;
			}

			IMemoryBlock memoryblk = rendering.getMemoryBlock();

			CTabFolder tabFolder = fTabFolderForMemoryBlock.get(memoryblk);

			if (tabFolder == null) {
				tabFolder = createFolderForMemoryBlock(memoryblk);
			}

			if (tabFolder == fStackLayout.topControl) {
				// disable current view tab
				if (getTopMemoryTab() != null) {
					deactivateRendering(getTopMemoryTab());
					getTopMemoryTab().setEnabled(false);
				}
			}
			fAddedRenderings.add(rendering);

			int index = getIndexOfCreateRenderingTab(tabFolder);
			if (index < 0) {
				index = 0;
			}
			CTabItem tab = createTab(tabFolder, index);

			MemoryViewTab viewTab = new MemoryViewTab(tab, rendering, getInstance());
			tabFolder.setSelection(tabFolder.indexOf(tab));

			if (tabFolder == fStackLayout.topControl) {
				setRenderingSelection(viewTab.getRendering());

				// disable top view tab if the view pane is not visible
				IMemoryViewTab top = getTopMemoryTab();
				if (top != null) {
					top.setEnabled(fVisible);
				}
			} else {
				deactivateRendering(viewTab);
				viewTab.setEnabled(false);
			}

			updateToolBarActionsEnablement();
		});
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.core.memory.IMemoryRenderingListener#
	 * MemoryBlockRenderingRemoved
	 * (org.eclipse.debug.internal.core.memory.IMemoryRendering)
	 */
	public void memoryBlockRenderingRemoved(final IMemoryRendering rendering) {
		final IMemoryBlock memory = rendering.getMemoryBlock();

		// need to run the following code on the UI Thread to avoid invalid
		// thread access exception
		Display.getDefault().asyncExec(() -> {
			if (!fAddedRenderings.contains(rendering)) {
				return;
			}

			fAddedRenderings.remove(rendering);

			CTabFolder tabFolder = (CTabFolder) fStackLayout.topControl;

			if (tabFolder.isDisposed()) {
				return;
			}

			CTabItem[] tabs = tabFolder.getItems();
			boolean foundTab = false;
			for (int i1 = 0; i1 < tabs.length; i1++) {
				IMemoryViewTab viewTab1 = (IMemoryViewTab) tabs[i1].getData();

				if (tabs[i1].isDisposed()) {
					continue;
				}

				if (viewTab1.getRendering().getMemoryBlock() == memory) {
					if (viewTab1.getRendering() == rendering) {
						foundTab = true;
						disposeTab(tabs[i1]);
						break;
					}

				}
			}

			// if a tab is not found in the current top control
			// this deletion is a result of a debug target termination
			// find memory from other folder and dispose the view tab
			if (!foundTab) {
				Enumeration<CTabFolder> enumeration = fTabFolderForMemoryBlock.elements();
				while (enumeration.hasMoreElements()) {
					CTabFolder otherTabFolder = enumeration.nextElement();
					tabs = otherTabFolder.getItems();
					IMemoryViewTab viewTab2 = null;
					for (int i2 = 0; i2 < tabs.length; i2++) {
						viewTab2 = (IMemoryViewTab) tabs[i2].getData();
						if (viewTab2.getRendering().getMemoryBlock() == memory) {
							if (viewTab2.getRendering() == rendering) {
								foundTab = true;
								disposeTab(tabs[i2]);
								break;
							}
						}
					}
				}
			}
			IMemoryViewTab top = getTopMemoryTab();

			// update selection
			if (top != null) {
				setRenderingSelection(top.getRendering());
			}

			updateToolBarActionsEnablement();
		});

	}

	/**
	 * @param viewTab
	 */
	protected void setRenderingSelection(IMemoryRendering rendering) {

		if (rendering != null) {
			fSelectionProvider.setSelection(new StructuredSelection(rendering));
		}
	}

	private void restoreViewTabs(IMemoryRendering[] renderings) {
		for (int i = 0; i < renderings.length; i++) {
			memoryBlockRenderingAdded(renderings[i]);
		}
	}

	private void handleDebugElementSelection(final IMemoryViewTab lastViewTab, final IAdaptable element) {
		// get current memory block retrieval and debug target
		IMemoryBlockRetrieval currentRetrieve = null;

		// get tab folder
		CTabFolder tabFolder = (CTabFolder) fStackLayout.topControl;

		// get memory block
		IMemoryBlock currentBlock = fMemoryBlockFromTabFolder.get(tabFolder);

		if (currentBlock != null) {
			currentRetrieve = MemoryViewUtil.getMemoryBlockRetrieval(currentBlock);

			// backup current retrieve and tab folder
			if (currentRetrieve != null && tabFolder != null) {
				fTabFolderForDebugView.put(MemoryViewUtil.getHashCode(currentRetrieve), tabFolder);
			}
		}

		// find the folder associated with the given IMemoryBlockRetrieval
		IMemoryBlockRetrieval retrieve = MemoryViewUtil.getMemoryBlockRetrieval(element);

		// if debug target has changed
		// switch to that tab folder
		if (retrieve != null && retrieve != currentRetrieve) {
			Integer key = MemoryViewUtil.getHashCode(retrieve);
			CTabFolder folder = fTabFolderForDebugView.get(key);

			if (folder != null) {
				setTabFolder(folder);
				fTabFolderForDebugView.put(key, folder);
				fViewPaneCanvas.layout();
			} else {
				// find out if there is any memory block for this debug target
				// and set up tab folder for the memory blocks
				IMemoryBlock blocks[] = MemoryViewUtil.getMemoryBlockManager().getMemoryBlocks(retrieve);

				if (blocks.length > 0) {
					handleMemoryBlockSelection(null, blocks[0]);
				} else {
					emptyFolder();
					fTabFolderForDebugView.put(key, fEmptyTabFolder);
					fViewPaneCanvas.layout();
				}
			}
		}

		// disable last view tab as it becomes hidden
		IMemoryViewTab newViewTab = getTopMemoryTab();

		if (lastViewTab != null && lastViewTab != newViewTab) {
			lastViewTab.setEnabled(false);
		}

		if (newViewTab != null) {
			// if new view tab is not already enabled, enable it
			if (!newViewTab.isEnabled()) {
				// if the view tab is visible, enable it
				if (fVisible) {
					newViewTab.setEnabled(fVisible);
				}
			}

			// should only change selection if the new view tab is different
			if (lastViewTab != newViewTab) {
				setRenderingSelection(newViewTab.getRendering());
			}
		}
		// set toolbar actions enabled/disabled
		updateToolBarActionsEnablement();
	}

	@Override
	protected void addListeners() {
		super.addListeners();

		// must directly listen for selection events from parent's selection
		// provider
		// to ensure that we get the selection event from the tree viewer pane
		// even
		// if the view does not have focuse
		fParent.getSite().getSelectionProvider().addSelectionChangedListener(this);
	}

	@Override
	protected void removeListeners() {
		super.removeListeners();
		fParent.getSite().getSelectionProvider().removeSelectionChangedListener(this);
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
	 * .events.SelectionEvent)
	 */
	@Override
	public void widgetSelected(SelectionEvent e) {

		if (getTopMemoryTab() == null) {
			return;
		}

		IMemoryRendering rendering = getTopMemoryTab().getRendering();

		if (rendering != null) {
			fSelectionProvider.setSelection(new StructuredSelection(rendering));
		}

	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse
	 * .swt.events.SelectionEvent)
	 */
	@Override
	public void widgetDefaultSelected(SelectionEvent e) {
	}

	@Override
	public Object getCurrentSelection() {
		if (getTopMemoryTab() != null) {
			if (getTopMemoryTab().getRendering() != null) {
				return getTopMemoryTab().getRendering();
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see com.ibm.debug.extended.ui.IMemoryView#getAllViewTabs()
	 */
	@Override
	public IMemoryViewTab[] getAllViewTabs() {

		// otherwise, find the view tab to display
		CTabFolder folder = (CTabFolder) fStackLayout.topControl;
		CTabItem[] items = folder.getItems();

		IMemoryViewTab[] viewTabs = new IMemoryViewTab[folder.getItemCount()];

		for (int i = 0; i < items.length; i++) {
			viewTabs[i] = (IMemoryViewTab) items[i].getData();
		}

		return viewTabs;
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * com.ibm.debug.extended.ui.IMemoryView#moveToTop(com.ibm.debug.extended
	 * .ui.IMemoryViewTab)
	 */
	@Override
	public void moveToTop(IMemoryViewTab viewTab) {

		IMemoryViewTab lastViewTab = getTopMemoryTab();

		if (viewTab == lastViewTab) {
			return;
		}

		// otherwise, find the view tab to display
		CTabFolder folder = (CTabFolder) fStackLayout.topControl;
		CTabItem[] items = folder.getItems();

		for (int i = 0; i < items.length; i++) {
			IMemoryViewTab tab = (IMemoryViewTab) items[i].getData();
			if (viewTab == tab) {

				boolean isEnabled = lastViewTab.isEnabled();

				// switch to that viewTab
				lastViewTab.setEnabled(false);
				folder.setSelection(i);

				setRenderingSelection(tab.getRendering());

				getTopMemoryTab().setEnabled(isEnabled && fVisible);
				break;
			}
		}
	}

	private CTabFolder createTabFolder(Composite parent) {
		CTabFolder folder = new CTabFolder(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.FLAT);

		ColorRegistry reg = JFaceResources.getColorRegistry();
		Color c1 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_START"), //$NON-NLS-1$
		c2 = reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_BG_END"); //$NON-NLS-1$
		folder.setSelectionBackground(new Color[] { c1, c2 }, new int[] { 100 }, true);
		folder.setSelectionForeground(reg.get("org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR")); //$NON-NLS-1$
		folder.setSimple(PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
		folder.setBorderVisible(true);
		folder.setFont(fViewPaneCanvas.getFont());

		folder.addCTabFolder2Listener(new CTabFolder2Adapter() {
			@Override
			public void close(CTabFolderEvent event) {
				if (event.item.getData() instanceof MemoryViewTab) {
					RenderingViewPane.this.removeMemoryRendering(((MemoryViewTab) event.item.getData()).getRendering());
				}
				event.doit = false;
			}
		});
		return folder;
	}

	@Override
	public void restoreViewPane() {

		// get current selection from memory view

		ISelection selection = null;
		if (fParent.getSite().getSelectionProvider() != null) {
			selection = fParent.getSite().getSelectionProvider().getSelection();
		}

		IMemoryBlock memoryBlock = null;
		if (selection != null) {
			memoryBlock = getMemoryBlock(selection);
		}

		if (memoryBlock == null) {
			// get selection from this view
			selection = fSelectionProvider.getSelection();

			if (MemoryViewUtil.isValidSelection(selection)) {
				Object elem = ((IStructuredSelection) selection).getFirstElement();

				if (!(elem instanceof IMemoryBlock)) {
					return;
				}

				memoryBlock = (IMemoryBlock) elem;
			}
		}

		if (memoryBlock == null) {
			// get a memory block from current debug context
			IAdaptable context = DebugUITools.getPartDebugContext(fParent.getSite());
			if (context != null) {
				IMemoryBlockRetrieval retrieval = MemoryViewUtil.getMemoryBlockRetrieval(context);

				if (retrieval != null) {
					IMemoryBlock[] blocks = DebugPlugin.getDefault().getMemoryBlockManager().getMemoryBlocks(retrieval);
					if (blocks.length > 0) {
						memoryBlock = blocks[0];
					}
				}
			}
		}

		if (memoryBlock != null) {
			if (!fTabFolderForMemoryBlock.containsKey(memoryBlock)) {
				// create tab folder if a tab folder does not already exist
				// for the memory block
				CTabFolder folder = createTabFolder(fViewPaneCanvas);

				fTabFolderForMemoryBlock.put(memoryBlock, folder);
				fMemoryBlockFromTabFolder.put(folder, memoryBlock);
				setTabFolder(fTabFolderForMemoryBlock.get(memoryBlock));
				IMemoryBlockRetrieval retrieval = MemoryViewUtil.getMemoryBlockRetrieval(memoryBlock);
				if (retrieval != null) {
					fTabFolderForDebugView.put(MemoryViewUtil.getHashCode(retrieval), fTabFolderForMemoryBlock.get(memoryBlock));
				} else {
					DebugUIPlugin.logErrorMessage("Memory block retrieval for memory block is null."); //$NON-NLS-1$
				}

				fViewPaneCanvas.layout();
				fAddedMemoryBlocks.add(memoryBlock);

				// every time we create a folder, we have to create a
				// CreateRendering
				newCreateRenderingForFolder(memoryBlock, folder);
			}

			if (fTabFolderForMemoryBlock.containsKey(memoryBlock)) {
				CTabFolder toDisplay = fTabFolderForMemoryBlock.get(memoryBlock);

				if (toDisplay != null) {
					setTabFolder(toDisplay);
					IMemoryBlockRetrieval retrieval = MemoryViewUtil.getMemoryBlockRetrieval(memoryBlock);

					if (retrieval != null) {
						fTabFolderForDebugView.put(MemoryViewUtil.getHashCode(retrieval), toDisplay);
					} else {
						DebugUIPlugin.logErrorMessage("Memory block retrieval is null for memory block."); //$NON-NLS-1$
					}

					fViewPaneCanvas.layout();

					// restore view tabs
					IMemoryRendering[] renderings = fRenderingMgr.getRenderingsFromMemoryBlock(memoryBlock);

					// if only CreateRendering is present, restore renderings
					if (isRestoreViewTabs(toDisplay)) {
						restoreViewTabs(renderings);
					}
				}
			}

			// disable current storag block

			IMemoryViewTab top = getTopMemoryTab();

			if (top != null) {
				top.setEnabled(fVisible);
			}
		}
	}

	@Override
	public void dispose() {
		super.dispose();

		fTabFolderForMemoryBlock.clear();
		fTabFolderForMemoryBlock = null;

		fMemoryBlockFromTabFolder.clear();
		fMemoryBlockFromTabFolder = null;

		fRenderingMgr.dispose();
		fRenderingMgr = null;

		fAddedMemoryBlocks.clear();
		fAddedRenderings.clear();
	}

	public Control createViewPane(Composite parent, String paneId, String label, boolean canAddRendering, boolean canRemoveRendering) {
		return doCreateViewPane(parent, paneId, label, canAddRendering, canRemoveRendering);
	}

	@Override
	public Control createViewPane(Composite parent, String paneId, String label) {
		return doCreateViewPane(parent, paneId, label, true, true);
	}

	/**
	 * @param parent
	 * @param paneId
	 * @param label
	 * @param canAddRendering
	 * @param canRemoveRendering
	 * @return
	 */
	private Control doCreateViewPane(Composite parent, String paneId, String label, boolean canAddRendering, boolean canRemoveRendering) {
		Control control = super.createViewPane(parent, paneId, label);
		fCanAddRendering = canAddRendering;
		fCanRemoveRendering = canRemoveRendering;
		fRenderingMgr = new ViewPaneRenderingMgr(this);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IDebugUIConstants.PLUGIN_ID + ".MemoryRenderingView_context"); //$NON-NLS-1$
		return control;
	}

	@Override
	public IAction[] getActions() {
		return new IAction[0];
	}

	// enable/disable toolbar action
	protected void updateToolBarActionsEnablement() {
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.internal.ui.views.memory.AbstractMemoryViewPane#emptyFolder
	 * ()
	 */
	@Override
	protected void emptyFolder() {
		super.emptyFolder();
		updateToolBarActionsEnablement();
		fSelectionProvider.setSelection(AbstractMemoryViewPane.EMPTY);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.views.memory.IRenderingViewPane#
	 * addMemoryRendering
	 * (org.eclipse.debug.internal.ui.views.memory.IMemoryRendering)
	 */
	@Override
	public void addMemoryRendering(IMemoryRendering rendering) {

		if (rendering == null) {
			return;
		}

		memoryBlockRenderingAdded(rendering);
		fRenderingMgr.addMemoryBlockRendering(rendering);

	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.views.memory.IRenderingViewPane#
	 * removeMemoryRendering
	 * (org.eclipse.debug.internal.ui.views.memory.IMemoryRendering)
	 */
	@Override
	public void removeMemoryRendering(IMemoryRendering rendering) {

		if (rendering == null) {
			return;
		}

		memoryBlockRenderingRemoved(rendering);

		if (fRenderingMgr != null) {
			fRenderingMgr.removeMemoryBlockRendering(rendering);
		}

	}

	private RenderingViewPane getInstance() {
		return this;
	}

	private IMemoryBlock getMemoryBlock(ISelection selection) {
		if (!(selection instanceof IStructuredSelection)) {
			return null;
		}

		// only single selection of PICLDebugElements is allowed for this action
		if (selection.isEmpty() || ((IStructuredSelection) selection).size() > 1) {
			return null;
		}

		Object elem = ((IStructuredSelection) selection).getFirstElement();

		if (elem instanceof IMemoryBlock) {
			return (IMemoryBlock) elem;
		} else if (elem instanceof IMemoryRendering) {
			return ((IMemoryRendering) elem).getMemoryBlock();
		} else {
			return null;
		}
	}

	private void deactivateRendering(IMemoryViewTab viewTab) {
		if (viewTab == null) {
			return;
		}

		if (!viewTab.isDisposed()) {
			viewTab.getRendering().deactivated();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.views.memory.IRenderingViewPane#
	 * getMemoryRenderingSite()
	 */
	@Override
	public IMemoryRenderingSite getMemoryRenderingSite() {
		return fRenderingSite;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRenderingContainer#getId()
	 */
	@Override
	public String getId() {
		return getPaneId();
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.ui.memory.IMemoryRenderingContainer#getRenderings()
	 */
	@Override
	public IMemoryRendering[] getRenderings() {
		return fRenderingMgr.getRenderings();
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.ui.memory.IMemoryRenderingContainer#getActiveRendering
	 * ()
	 */
	@Override
	public IMemoryRendering getActiveRendering() {
		if (getTopMemoryTab() == null) {
			return null;
		}
		return getTopMemoryTab().getRendering();
	}

	/**
	 * Reset the memory renderings within this view pane.
	 *
	 * @param memoryBlock - reset renderings associated with the given memory
	 *            block
	 * @param resetVisible - reset what's currently visible if the parameter is
	 *            true. Otherwise, the view pane will reset all renderings
	 *            associated with the given memory block.
	 */
	public void resetRenderings(IMemoryBlock memoryBlock, boolean resetVisible) {
		// if we only reset what's visible and the view pane is not visible
		// do nothing.
		if (resetVisible && !isVisible()) {
			return;
		}

		if (resetVisible) {
			IMemoryRendering rendering = getActiveRendering();
			if (rendering != null) {
				if (rendering.getMemoryBlock() == memoryBlock) {
					if (rendering instanceof IResettableMemoryRendering) {
						IResettableMemoryRendering resettableRendering = (IResettableMemoryRendering) rendering;
						try {
							resettableRendering.resetRendering();
						} catch (DebugException e) {
							// do not pop up error message
							// error message is annoying where there are
							// multiple rendering
							// panes and renderings to reset
						}
					}
				}
			}
		} else {
			// get all renderings associated with the given memory block
			IMemoryRendering[] renderings = fRenderingMgr.getRenderingsFromMemoryBlock(memoryBlock);

			// back up current synchronization provider
			IMemoryRendering originalProvider = null;
			IMemoryRenderingSynchronizationService service = getMemoryRenderingSite().getSynchronizationService();
			if (service != null) {
				originalProvider = service.getSynchronizationProvider();
			}

			for (int i = 0; i < renderings.length; i++) {
				if (renderings[i] instanceof IResettableMemoryRendering) {
					try {

						// This is done to allow user to select multiple memory
						// monitors and
						// reset their renderings.
						// In this case, a hidden rendering will not be the sync
						// provider to the sync
						// service. When the reset happens, the top visible
						// address and selected
						// address is not updated in the sync service. When the
						// rendering later
						// becomes visible, the rendering gets the sync info
						// from the sync service
						// and will try to sync up with old information, giving
						// user the impression
						// that the rendering was never reset. By forcing the
						// rendering that we
						// are trying to reset as the synchronization provider,
						// we ensure that
						// the rendering is able to update its sync info even
						// though the rendering
						// is currently hidden.
						if (service != null) {
							service.setSynchronizationProvider(renderings[i]);
						}
						((IResettableMemoryRendering) renderings[i]).resetRendering();
					} catch (DebugException e) {
						// do not pop up error message
						// error message is annoying where there are multiple
						// rendering
						// panes and renderings to reset
					}
				}
			}

			// restore synchronization provider
			if (service != null) {
				service.setSynchronizationProvider(originalProvider);
			}
		}
	}

	public void showCreateRenderingTab() {
		IMemoryRendering activeRendering = RenderingViewPane.this.getActiveRendering();
		if (activeRendering == null) {
			return;
		}

		IMemoryBlock memoryblk = activeRendering.getMemoryBlock();

		final CTabFolder tabFolder = fTabFolderForMemoryBlock.get(memoryblk);
		if (tabFolder != null) {
			Display.getDefault().asyncExec(() -> {
				int index = getIndexOfCreateRenderingTab(tabFolder);
				if (index >= 0) {
					tabFolder.setSelection(index);
				}
			});
		}
	}

	public void contextActivated(final ISelection selection) {

		UIJob job = new UIJob("contextActivated") { //$NON-NLS-1$
			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {
				if (isDisposed()) {
					return Status.OK_STATUS;
				}

				IMemoryViewTab lastViewTab = getTopMemoryTab();

				if (MemoryViewUtil.isValidSelection(selection)) {
					if (!(selection instanceof IStructuredSelection)) {
						return Status.OK_STATUS;
					}

					Object elem = ((IStructuredSelection) selection).getFirstElement();

					if (elem instanceof IAdaptable) {
						handleDebugElementSelection(lastViewTab, (IAdaptable) elem);
					}
				} else {
					if (lastViewTab != null) {
						lastViewTab.setEnabled(false);
					}

					if (fStackLayout.topControl != fEmptyTabFolder) {
						emptyFolder();
					}

				}
				return Status.OK_STATUS;
			}
		};
		job.setSystem(true);
		job.schedule();
	}

	/**
	 * @param memory
	 */
	private CTabFolder createFolderForMemoryBlock(IMemoryBlock memory) {
		CTabFolder folder = createTabFolder(fViewPaneCanvas);

		fTabFolderForMemoryBlock.put(memory, folder);
		fMemoryBlockFromTabFolder.put(folder, memory);

		IMemoryBlockRetrieval retrieval = MemoryViewUtil.getMemoryBlockRetrieval(memory);
		if (retrieval != null) {
			fTabFolderForDebugView.put(MemoryViewUtil.getHashCode(retrieval), folder);
		} else {
			DebugUIPlugin.logErrorMessage("Memory block retrieval for memory block is null"); //$NON-NLS-1$
		}

		newCreateRenderingForFolder(memory, folder);

		return folder;
	}

	private void newCreateRenderingForFolder(IMemoryBlock memory, CTabFolder folder) {

		if (!canAddRendering()) {
			return;
		}

		CTabItem newItem = new CTabItem(folder, SWT.NONE);
		CreateRendering rendering = new CreateRendering(getInstance());
		rendering.init(getInstance(), memory);
		new MemoryViewTab(newItem, rendering, getInstance());
		folder.setSelection(0);
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener
	 * #contextEvent
	 * (org.eclipse.debug.internal.ui.contexts.provisional.DebugContextEvent)
	 */
	@Override
	public void debugContextChanged(DebugContextEvent event) {
		if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
			contextActivated(event.getContext());
		}
	}

	/**
	 * @return whether this container allows user to add rendering manually
	 * @since 3.4
	 */
	public boolean canAddRendering() {
		return fCanAddRendering;
	}

	/**
	 * @return whether this container allows user to remove rendering manually
	 * @since 3.4
	 */
	public boolean canRemoveRendering() {
		return fCanRemoveRendering;
	}

	/**
	 * @param tabFolder
	 * @param index
	 * @return
	 */
	private CTabItem createTab(CTabFolder tabFolder, int index) {
		int swtStyle = SWT.CLOSE;
		if (!canRemoveRendering()) {
			swtStyle = SWT.NONE;
		}
		CTabItem tab = new CTabItem(tabFolder, swtStyle, index);
		return tab;
	}
}
