/*******************************************************************************
 * Copyright (c) 2006, 2017 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
 *******************************************************************************/
package org.eclipse.team.ui;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareViewerPane;
import org.eclipse.compare.IContentChangeListener;
import org.eclipse.compare.IContentChangeNotifier;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.Splitter;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.progress.IProgressService;

/**
 * Abstract class for hosting a page based structure input view for the purposes
 * of feeding compare viewers.
 * <p>
 * This class is not intended to be subclassed by clients outside of the Team framework.
 *
 * @since 3.3
 */
public abstract class PageCompareEditorInput extends CompareEditorInput implements IContentChangeListener {

	private CompareViewerPane pagePane;
	private ICompareInput hookedInput;

	/**
	 * Create a page compare editor input.
	 * @param configuration the compare configuration
	 */
	protected PageCompareEditorInput(CompareConfiguration configuration) {
		super(configuration);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.compare.CompareEditorInput#createStructureInputPane(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected CompareViewerPane createStructureInputPane(Composite parent) {
		pagePane = new CompareViewerPane(parent, SWT.BORDER | SWT.FLAT) {
			@Override
			public void selectionChanged(SelectionChangedEvent ev) {
				ISelection selection = ev.getSelection();
				StructuredSelection newSelection = convertSelection(selection, false);
				SelectionChangedEvent newEv = new SelectionChangedEvent(pagePane, newSelection);
				super.selectionChanged(newEv);
			}
			private StructuredSelection convertSelection(ISelection selection, boolean prepare) {
				ICompareInput ci = asCompareInput(selection);
				StructuredSelection newSelection;
				if (ci != null) {
					if (prepare)
						prepareCompareInput(ci);
					newSelection = new StructuredSelection(ci);
				} else {
					newSelection = StructuredSelection.EMPTY;
				}
				return newSelection;
			}
			@Override
			public ISelection getSelection() {
				return convertSelection(getSelectionProvider().getSelection(), false);
			}
			@Override
			public Object getInput() {
				return PageCompareEditorInput.this.getCompareResult();
			}
			@Override
			public void open(OpenEvent event) {
				ISelection selection = event.getSelection();
				StructuredSelection newSelection = convertSelection(selection, true);
				super.open(new OpenEvent((Viewer)event.getSource(), newSelection));
			}
			@Override
			public void doubleClick(DoubleClickEvent event) {
				ISelection selection = event.getSelection();
				StructuredSelection newSelection = convertSelection(selection, true);
				super.doubleClick(new DoubleClickEvent((Viewer)event.getSource(), newSelection));
			}

			@Override
			public void setInput(Object input) {
				super.setInput(input);
				Composite c = getParent();
				if (c instanceof Splitter)
					((Splitter)c).setVisible(this, true);
				layout(true);
			}
		};
		ToolBarManager toolBarManager = CompareViewerPane.getToolBarManager(pagePane);
		IPage page = createPage(pagePane, toolBarManager);
		pagePane.setContent(page.getControl());
		if (parent instanceof Splitter)
			((Splitter)parent).setVisible(pagePane, false);
		hookupListeners();
		return pagePane;
	}

	/**
	 * Create the page for this part and return the top level control
	 * for the page.
	 * @param parent the parent composite
	 * @param toolBarManager the toolbar manager for the page
	 * @return the top-level control for the page
	 */
	protected abstract IPage createPage(CompareViewerPane parent, IToolBarManager toolBarManager);

	/**
	 * Return the selection provider for the page. This method is
	 * called after the page is created in order to register a
	 * selection listener on the page.
	 * @return the selection provider for the page
	 */
	protected abstract ISelectionProvider getSelectionProvider();

	/**
	 * Set the title of the page's page to the given text. The title
	 * will appear in the header of the pane containing the page.
	 * @param title the page's title
	 */
	protected void setPageDescription(String title) {
		pagePane.setText(title);
	}

	@Override
	protected void handleDispose() {
		super.handleDispose();
		cleanupListeners();
		unhookContentChangeListener();
	}

	private void hookupListeners() {
		ISelectionProvider selectionProvider = getSelectionProvider();
		if (selectionProvider != null)
			selectionProvider.addSelectionChangedListener(pagePane);
		if (selectionProvider instanceof StructuredViewer) {
			StructuredViewer sv = (StructuredViewer) selectionProvider;
			sv.addOpenListener(pagePane);
			sv.addDoubleClickListener(pagePane);
		}
	}

	private void cleanupListeners() {
		ISelectionProvider selectionProvider = getSelectionProvider();
		if (selectionProvider != null)
			selectionProvider.removeSelectionChangedListener(pagePane);
		if (selectionProvider instanceof StructuredViewer) {
			StructuredViewer sv = (StructuredViewer) selectionProvider;
			sv.removeOpenListener(pagePane);
			sv.removeDoubleClickListener(pagePane);
		}
	}

	private void hookContentChangeListener(ICompareInput node) {
		if (hookedInput == node)
			return;
		unhookContentChangeListener();
		hookedInput = node;
		ITypedElement left = node.getLeft();
		if(left instanceof IContentChangeNotifier) {
			((IContentChangeNotifier)left).addContentChangeListener(this);
		}
		ITypedElement right = node.getRight();
		if(right instanceof IContentChangeNotifier) {
			((IContentChangeNotifier)right).addContentChangeListener(this);
		}
	}

	private void unhookContentChangeListener() {
		if (hookedInput != null) {
			ITypedElement left = hookedInput.getLeft();
			if(left instanceof IContentChangeNotifier) {
				((IContentChangeNotifier)left).addContentChangeListener(this);
			}
			ITypedElement right = hookedInput.getRight();
			if(right instanceof IContentChangeNotifier) {
				((IContentChangeNotifier)right).addContentChangeListener(this);
			}
		}
	}

	/**
	 * Return a compare input that represents the selection.
	 * This input is used to feed the structure and content
	 * viewers. By default, a compare input is returned if the selection is
	 * of size 1 and the selected element implements <code>ICompareInput</code>.
	 * Subclasses may override.
	 * @param selection the selection
	 * @return a compare input representing the selection
	 */
	protected ICompareInput asCompareInput(ISelection selection) {
		if (selection != null && selection instanceof IStructuredSelection) {
			IStructuredSelection ss= (IStructuredSelection) selection;
			if (ss.size() == 1) {
				Object o = ss.getFirstElement();
				if(o instanceof ICompareInput) {
					return (ICompareInput)o;
				}
			}
		}
		return null;
	}

	/**
	 * Convenience method that calls {@link #prepareInput(ICompareInput, CompareConfiguration, IProgressMonitor)}
	 * with a progress monitor.
	 * @param input the compare input to be prepared
	 */
	protected final void prepareCompareInput(final ICompareInput input) {
		if (input == null)
			return;
		// Don't allow the use of shared documents with PageSaveableParts
		Object left = input.getLeft();
		if (left instanceof LocalResourceTypedElement) {
			LocalResourceTypedElement lrte = (LocalResourceTypedElement) left;
			lrte.enableSharedDocument(false);
		}
		IProgressService manager = PlatformUI.getWorkbench().getProgressService();
		try {
			// TODO: we need a better progress story here (i.e. support for cancellation) bug 127075
			manager.busyCursorWhile(monitor -> {
			    prepareInput(input, getCompareConfiguration(), monitor);
			    hookContentChangeListener(input);
			});
		} catch (InvocationTargetException e) {
			Utils.handle(e);
		} catch (InterruptedException e) {
			// Ignore
		}
	}

	@Override
	public void contentChanged(IContentChangeNotifier source) {
		setDirty(true);
	}

	@Override
	public boolean canRunAsJob() {
		return true;
	}

	/**
	 * Prepare the compare input for display in a content viewer. This method is
	 * called from {@link #prepareCompareInput(ICompareInput)} and may be called
	 * from a non-UI thread. This method should not be called by others.
	 * @param input the input
	 * @param configuration the compare configuration
	 * @param monitor a progress monitor
	 * @throws InvocationTargetException
	 */
	protected abstract void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException;


}
