/*******************************************************************************
 * 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 java.util.ArrayList;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.CompareViewerPane;
import org.eclipse.compare.CompareViewerSwitchingPane;
import org.eclipse.compare.IContentChangeListener;
import org.eclipse.compare.IContentChangeNotifier;
import org.eclipse.compare.IPropertyChangeNotifier;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.Splitter;
import org.eclipse.compare.contentmergeviewer.IFlushable;
import org.eclipse.compare.internal.CompareEditor;
import org.eclipse.compare.internal.CompareEditorInputNavigator;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
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.Shell;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;
import org.eclipse.team.internal.ui.synchronize.SynchronizePageConfiguration;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;

/**
 * Abstract class for hosting a page based structure input view for the purposes
 * of feeding compare viewers.
 * <p>
 *
 * @since 3.2
 * @noextend This class is not intended to be subclassed by clients outside of the Team framework.
 * @deprecated Clients should use a subclass of {@link CompareEditorInput}
 *      and {@link CompareUI#openCompareDialog(org.eclipse.compare.CompareEditorInput)}
 */
@Deprecated
public abstract class PageSaveablePart extends SaveablePartAdapter implements IContentChangeListener{

	private CompareConfiguration cc;
	Shell shell;

	// Tracking of dirty state
	private boolean fDirty= false;
	private ArrayList<Object> fDirtyViewers= new ArrayList<>();
	private IPropertyChangeListener fDirtyStateListener;

	//	 SWT controls
	private CompareViewerSwitchingPane fContentPane;
	private CompareViewerPane fEditionPane;
	private CompareViewerSwitchingPane fStructuredComparePane;
	private Control control;

	// Configuration options
	private boolean showContentPanes = true;

	/**
	 * Create a saveable part.
	 * @param shell the shell for the part
	 * @param compareConfiguration the compare configuration
	 */
	protected PageSaveablePart(Shell shell, CompareConfiguration compareConfiguration){
		this.shell = shell;
		this.cc = compareConfiguration;

		fDirtyStateListener= e -> {
			String propertyName= e.getProperty();
			if (CompareEditorInput.DIRTY_STATE.equals(propertyName)) {
				boolean changed= false;
				Object newValue= e.getNewValue();
				if (newValue instanceof Boolean)
					changed= ((Boolean)newValue).booleanValue();
				setDirty(e.getSource(), changed);
			}
		};
	}

	@Override
	public boolean isDirty() {
		return fDirty || fDirtyViewers.size() > 0;
	}

	@Override
	public void createPartControl(Composite parent) {
		Composite composite = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.verticalSpacing = 0;
		GridData data = new GridData(GridData.FILL_BOTH);
		data.grabExcessHorizontalSpace = true;
		composite.setLayout(layout);
		composite.setLayoutData(data);

		shell = parent.getShell();

		Splitter vsplitter = new Splitter(composite, SWT.VERTICAL);
		vsplitter.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
		// we need two panes: the left for the elements, the right one for the structured diff
		Splitter hsplitter = new Splitter(vsplitter, SWT.HORIZONTAL);
		fEditionPane = new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
		fStructuredComparePane = new CompareViewerSwitchingPane(hsplitter, SWT.BORDER | SWT.FLAT, true) {
			@Override
			protected Viewer getViewer(Viewer oldViewer, Object input) {
				if (input instanceof ICompareInput)
					return findStructureViewer(this, oldViewer, (ICompareInput)input);
				return null;
			}
		};
		fStructuredComparePane.addSelectionChangedListener(e -> feedInput2(e.getSelection()));
		fEditionPane.setText(TeamUIMessages.ParticipantPageSaveablePart_0);
		fContentPane = new CompareViewerSwitchingPane(vsplitter, SWT.BORDER | SWT.FLAT) {
			@Override
			protected Viewer getViewer(Viewer oldViewer, Object input) {
				if (!(input instanceof ICompareInput))
					return null;
				Viewer newViewer= findContentViewer(this, oldViewer, (ICompareInput)input);
				boolean isNewViewer= newViewer != oldViewer;
				if (isNewViewer && newViewer instanceof IPropertyChangeNotifier) {
					final IPropertyChangeNotifier dsp= (IPropertyChangeNotifier) newViewer;
					dsp.addPropertyChangeListener(fDirtyStateListener);
					Control c= newViewer.getControl();
					c.addDisposeListener(
						e -> dsp.removePropertyChangeListener(fDirtyStateListener)
					);
					hookContentChangeListener((ICompareInput)input);
				}
				return newViewer;
			}
		};
		vsplitter.setWeights(new int[]{30, 70});

		control = composite;

		ToolBarManager toolBarManager = CompareViewerPane.getToolBarManager(fEditionPane);
		Control c = createPage(fEditionPane, toolBarManager);
		fEditionPane.setContent(c);

		if(! showContentPanes) {
			hsplitter.setMaximizedControl(fEditionPane);
		}

		getSelectionProvider().addSelectionChangedListener(event -> {
			ICompareInput input = getCompareInput(event.getSelection());
			if (input != null)
				prepareCompareInput(input);
			setInput(input);
		});
	}

	/**
	 * 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();

	/**
	 * 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 Control createPage(Composite parent, ToolBarManager toolBarManager);

	/**
	 * 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) {
		fEditionPane.setText(title);
	}

	/**
	 * Set the saveable part's dirty state to the given state.
	 * @param dirty the dirty state
	 */
	protected void setDirty(boolean dirty) {
		boolean confirmSave= true;
		Object o= cc.getProperty(CompareEditor.CONFIRM_SAVE_PROPERTY);
		if (o instanceof Boolean)
			confirmSave= ((Boolean)o).booleanValue();

		if (!confirmSave) {
			fDirty= dirty;
			if (!fDirty)
				fDirtyViewers.clear();
		}
	}

	private void setDirty(Object source, boolean dirty) {
		Assert.isNotNull(source);
		if (dirty)
			fDirtyViewers.add(source);
		else
			fDirtyViewers.remove(source);
	}

	/**
	 * Feeds input from the page into the content and structured viewers.
	 * @param input the input
	 */
	private void setInput(Object input) {
		CompareViewerPane pane = fContentPane;
		if (pane != null && !pane.isDisposed())
			fContentPane.setInput(input);
		if (fStructuredComparePane != null && !fStructuredComparePane.isDisposed())
			fStructuredComparePane.setInput(input);
	}

	/*
	 * Feeds selection from structure viewer to content viewer.
	 */
	private void feedInput2(ISelection sel) {
		ICompareInput input = getCompareInput(sel);
		prepareCompareInput(input);
		if (input != null)
			fContentPane.setInput(input);
	}

	/**
	 * Convenience method that calls {@link #prepareInput(ICompareInput, CompareConfiguration, IProgressMonitor)}
	 * with a progress monitor.
	 * @param input the compare input to be prepared
	 */
	protected 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
		}
	}

	/**
	 * 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 if an error occurs
	 */
	protected abstract void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException;

	private void hookContentChangeListener(ICompareInput node) {
		// TODO: there is no unhook which may lead to a leak
		ITypedElement left = node.getLeft();
		if(left instanceof IContentChangeNotifier) {
			((IContentChangeNotifier)left).addContentChangeListener(this);
		}
		ITypedElement right = node.getRight();
		if(right instanceof IContentChangeNotifier) {
			((IContentChangeNotifier)right).addContentChangeListener(this);
		}
	}

	/**
	 * Return the parent shell of this part.
	 * @return the parent shell of this part
	 */
	protected Shell getShell() {
		return shell;
	}

	/**
	 * This method is internal to the framework and should not be called by clients
	 * outside of the framework.
	 */
	protected void setNavigator(ISynchronizePageConfiguration configuration) {
			configuration.setProperty(SynchronizePageConfiguration.P_NAVIGATOR, new CompareEditorInputNavigator(
				new Object[] {
					configuration.getProperty(SynchronizePageConfiguration.P_ADVISOR),
					fStructuredComparePane,
					fContentPane
				}
			));
	}

	/*
	 * Find a viewer that can provide a structure view for the given compare input.
	 * Return <code>null</code> if a suitable viewer could not be found.
	 * @param parent the parent composite for the viewer
	 * @param oldViewer the viewer that is currently a child of the parent
	 * @param input the compare input to be viewed
	 * @return a viewer capable of displaying a structure view of the input or
	 * <code>null</code> if such a viewer is not available.
	 */
	private Viewer findStructureViewer(Composite parent, Viewer oldViewer, ICompareInput input) {
		return CompareUI.findStructureViewer(oldViewer, input, parent, cc);
	}

	/*
	 * Find a viewer that can provide a content compare view for the given compare input.
	 * Return <code>null</code> if a suitable viewer could not be found.
	 * @param parent the parent composite for the viewer
	 * @param oldViewer the viewer that is currently a child of the parent
	 * @param input the compare input to be viewed
	 * @return a viewer capable of displaying a content compare view of the input or
	 * <code>null</code> if such a viewer is not available.
	 */
	private Viewer findContentViewer(Composite parent, Viewer oldViewer, ICompareInput input) {
		return CompareUI.findContentViewer(oldViewer, input, parent, cc);
	}

	/**
	 * 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 getCompareInput(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;
	}

	/**
	 * Set whether the file contents panes should be shown. If they are not,
	 * only the page will be shown.
	 *
	 * @param showContentPanes whether to show contents pane
	 */
	public void setShowContentPanes(boolean showContentPanes) {
		this.showContentPanes = showContentPanes;
	}

	/**
	 * Returns the primary control for this part.
	 *
	 * @return the primary control for this part.
	 */
	public Control getControl() {
		return control;
	}

	/**
	 * Return the compare configuration.
	 * @return the compare configuration
	 */
	private CompareConfiguration getCompareConfiguration() {
		return cc;
	}

	/**
	 * This method flushes the content in any viewers. Subclasses should
	 * override if they need to perform additional processing when a save is
	 * performed.
	 *
	 * @param monitor
	 *            a progress monitor
	 */
	@Override
	public void doSave(IProgressMonitor monitor) {
		flushViewers(monitor);
	}

	private void flushViewers(IProgressMonitor monitor) {
		for (Object element : fDirtyViewers) {
			IFlushable flushable = Adapters.adapt(element, IFlushable.class);
			if (flushable != null)
				flushable.flush(monitor);
		}
	}

}
