/*******************************************************************************
 * Copyright (c) 2011 Eike Stepper (Berlin, Germany) and others.
 *
 * All rights reserved. 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:
 * Eike Stepper - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.ecp.ui.views;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.ecp.core.util.ECPContainer;
import org.eclipse.emf.ecp.core.util.ECPUtil;
import org.eclipse.emf.ecp.internal.ui.model.ModelContentProvider;
import org.eclipse.emf.ecp.spi.ui.UIProvider;
import org.eclipse.emf.ecp.spi.ui.UIProviderRegistry;
import org.eclipse.emf.ecp.spi.ui.util.ECPHandlerHelper;
import org.eclipse.emf.ecp.ui.common.ECPViewerFactory;
import org.eclipse.emf.ecp.ui.e3.Messages;
import org.eclipse.emf.ecp.ui.linkedView.ILinkedWithEditorView;
import org.eclipse.emf.ecp.ui.linkedView.LinkedWithEditorPartListener;
import org.eclipse.emf.ecp.ui.platform.Activator;
import org.eclipse.emf.ecp.ui.tester.ECPSavePropertySource;
import org.eclipse.emf.ecp.ui.tester.SaveButtonEnablementObserver;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.services.IEvaluationService;

/**
 * @author Eike Stepper
 * @author Eugen Neufeld
 */
public class ModelExplorerView extends TreeView implements ILinkedWithEditorView {
	private static final String VIEW_SORTER = "viewSorter"; //$NON-NLS-1$

	private static final String LINK_WITH_EDITOR_SET = "LinkWithEditorSet"; //$NON-NLS-1$

	private static final String LINK_WITH_EDITOR = "LinkWithEditor"; //$NON-NLS-1$

	/**
	 * @author Jonas
	 * @author Eugen Neufeld
	 */
	public class DoubleClickListener implements IDoubleClickListener {

		/**
		 * Opens an EObject using the ActionHelper or opens a closed ECPProject. {@inheritDoc}
		 */
		@Override
		public void doubleClick(DoubleClickEvent event) {
			if (event.getSelection() instanceof IStructuredSelection) {
				final IStructuredSelection structuredSelection = (IStructuredSelection) event.getSelection();
				final Object firstElement = structuredSelection.getFirstElement();

				if (firstElement instanceof ECPProject) {
					final ECPProject project = (ECPProject) firstElement;
					if (!project.isOpen()) {
						project.open();
					}
				} else {
					final ECPContainer context = ECPUtil
						.getModelContext(contentProvider, structuredSelection.toArray());
					ECPHandlerHelper.openModelElement(firstElement, (ECPProject) context);
				}
			}
		}
	}

	/**
	 * The id of this view.
	 */
	public static final String ID = "org.eclipse.emf.ecp.ui.ModelExplorerView"; //$NON-NLS-1$

	private final IPartListener2 linkWithEditorPartListener = new LinkedWithEditorPartListener(this);

	private boolean linkingActive = true;

	private ModelContentProvider contentProvider;

	private TreeViewer viewer;

	private Action linkWithEditorAction;

	private ECPSavePropertySource ecpSavePropertySource;

	/**
	 * Default Constructor.
	 */
	public ModelExplorerView() {
		super(ID);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.ecp.ui.views.TreeView#init(org.eclipse.ui.IViewSite)
	 */
	@Override
	public void init(IViewSite site) throws PartInitException {
		super.init(site);
		@SuppressWarnings("cast")
		// Ignore the warning and keep the cast to stay SRC compatible with Luna
		final IEvaluationService evaluationService = (IEvaluationService) site.getService(IEvaluationService.class);
		ecpSavePropertySource = new ECPSavePropertySource();
		evaluationService.addSourceProvider(ecpSavePropertySource);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
	 */
	@Override
	public void dispose() {
		@SuppressWarnings("cast")
		// Ignore the warning and keep the cast to stay SRC compatible with Luna
		final IEvaluationService evaluationService = (IEvaluationService) getSite()
			.getService(IEvaluationService.class);
		evaluationService.removeSourceProvider(ecpSavePropertySource);
		super.dispose();
	}

	@Override
	protected TreeViewer createViewer(final Composite parent) {
		viewer = ECPViewerFactory.createModelExplorerViewer(parent, true, createLabelDecorator());
		contentProvider = (ModelContentProvider) viewer.getContentProvider();
		viewer.addDoubleClickListener(new DoubleClickListener());
		viewer.addSelectionChangedListener(new ModelExplorerViewSelectionListener());
		viewer.getControl().addFocusListener(new FocusListener() {
			@Override
			public void focusGained(FocusEvent event) {
			}

			@Override
			public void focusLost(FocusEvent event) {
				ECPUtil.getECPObserverBus().notify(SaveButtonEnablementObserver.class)
					.notifyChangeButtonState(null, false);
			}

		});

		addViewerSorter(viewer);

		getSite().getWorkbenchWindow().getWorkbench().addWorkbenchListener(new IWorkbenchListener() {

			@Override
			public boolean preShutdown(IWorkbench workbench, boolean forced) {

				return ECPHandlerHelper.showDirtyProjectsDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
					.getShell());
			}

			@Override
			public void postShutdown(IWorkbench workbench) {
				// do nothing
			}
		});

		return viewer;
	}

	@SuppressWarnings("deprecation")
	private void addViewerSorter(TreeViewer viewer) {
		final IConfigurationElement[] modelExplorerSettings = Platform.getExtensionRegistry()
			.getConfigurationElementsFor("org.eclipse.emf.ecp.ui.modelExplorerSettings"); //$NON-NLS-1$
		if (modelExplorerSettings.length == 1) {
			if (modelExplorerSettings[0].getAttribute(VIEW_SORTER) != null) {
				try {
					final ViewerSorter sorter = (ViewerSorter) modelExplorerSettings[0]
						.createExecutableExtension(VIEW_SORTER);
					viewer.setSorter(sorter);
				} catch (final CoreException e) {
					Activator.log(e);
				}

			}
		}
	}

	@Override
	protected void fillLocalToolBar(IToolBarManager manager) {
		if (getDialogSettings().getBoolean(LINK_WITH_EDITOR_SET)) {
			linkingActive = getDialogSettings().getBoolean(LINK_WITH_EDITOR);
		}
		if (linkingActive) {
			getSite().getPage().addPartListener(linkWithEditorPartListener);
		}

		linkWithEditorAction = new Action(Messages.ModelExplorerView_LinkWithEditor, SWT.TOGGLE) {

			@Override
			public void run() {
				if (linkingActive) {
					linkingActive = false;
					getSite().getPage().removePartListener(linkWithEditorPartListener);
				} else {
					linkingActive = true;
					getSite().getPage().addPartListener(linkWithEditorPartListener);
					final IEditorPart editor = getSite().getPage().getActiveEditor();
					if (editor != null) {
						editorActivated(editor);
					}
				}

				getDialogSettings().put(LINK_WITH_EDITOR, isChecked());
				getDialogSettings().put(LINK_WITH_EDITOR_SET, true);
			}

		};

		linkWithEditorAction.setImageDescriptor(Activator.getImageDescriptor("icons/link_with_editor.gif")); //$NON-NLS-1$
		linkWithEditorAction.setToolTipText(Messages.ModelExplorerView_LinkWithEditor);
		linkWithEditorAction.setChecked(getDialogSettings().getBoolean(LINK_WITH_EDITOR_SET) ? getDialogSettings()
			.getBoolean(LINK_WITH_EDITOR) : true);
		manager.add(linkWithEditorAction);
	}

	private IDialogSettings getDialogSettings() {
		return Activator.getDefault().getDialogSettings();
	}

	@Override
	protected void fillContextMenu(IMenuManager manager) {
		final Object[] elements = getSelection().toArray();

		final ECPContainer context = ECPUtil.getModelContext(contentProvider, elements);
		if (context != null) {
			final UIProvider provider = UIProviderRegistry.INSTANCE.getUIProvider(context);
			if (provider != null) {
				provider.fillContextMenu(manager, context, elements);
			}
		}

		super.fillContextMenu(manager);
	}

	/** {@inheritDoc} */
	@Override
	public void editorActivated(IEditorPart activatedEditor) {
		if (!linkingActive || !getViewSite().getPage().isPartVisible(this)) {
			return;
		}
		final Object input = activatedEditor.getEditorInput().getAdapter(EObject.class);
		if (input != null) {
			viewer.setSelection(new StructuredSelection(input), true);
		}
	}

	/**
	 *
	 * @author jfaltermeier
	 *
	 */
	private class ModelExplorerViewSelectionListener implements ISelectionChangedListener {

		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			notifyAboutSaveButtonState(event);
			if (linkingActive) {
				final Object selected = ((IStructuredSelection) event.getSelection()).getFirstElement();
				if (selected instanceof EObject) {
					for (final IEditorReference editorRef : getSite().getPage().getEditorReferences()) {
						Object editorInput = null;
						try {

							editorInput = editorRef.getEditorInput().getAdapter(EObject.class);
						} catch (final PartInitException e) {
							e.printStackTrace();
						}
						if (selected.equals(editorInput)) {
							getSite().getPage().bringToTop(editorRef.getPart(true));
							return;
						}
					}
				}
			}
		}

		private void notifyAboutSaveButtonState(SelectionChangedEvent event) {
			final boolean selectedProjectIsDirty;

			final Object selected = ((IStructuredSelection) event.getSelection()).getFirstElement();
			final ECPProject project = ECPUtil.getECPProjectManager().getProject(selected);

			if (project == null) {
				selectedProjectIsDirty = false;
			} else {
				selectedProjectIsDirty = project.hasDirtyContents();
			}

			ECPUtil.getECPObserverBus().notify(SaveButtonEnablementObserver.class)
				.notifyChangeButtonState(project, selectedProjectIsDirty);
		}
	}
}
