/*******************************************************************************
 * Copyright (c) 2005, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.text;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.ElementChangedEvent;
import org.eclipse.dltk.core.IElementChangedListener;
import org.eclipse.dltk.core.IModelElementDelta;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.internal.ui.editor.EditorUtility;
import org.eclipse.dltk.internal.ui.editor.ScriptEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.MonoReconciler;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.spelling.SpellingService;

public class ScriptReconciler extends MonoReconciler {

	/**
	 * Creates a new reconciler.
	 *
	 * @param editor
	 *            the editor
	 * @param strategy
	 *            the reconcile strategy
	 * @param isIncremental
	 *            <code>true</code> if this is an incremental reconciler
	 */
	public ScriptReconciler(ITextEditor editor, IReconcilingStrategy strategy,
			boolean isIncremental) {
		super(strategy, isIncremental);
		fTextEditor = editor;

		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=63898
		// when re-using editors, a new reconciler is set up by the source
		// viewer
		// and the old one uninstalled. However, the old reconciler may still be
		// running.
		// To avoid having to reconcilers calling
		// CompilationUnitEditor.reconciled,
		// we synchronized on a lock object provided by the editor.
		// The critical section is really the entire run() method of the
		// reconciler
		// thread, but synchronizing process() only will keep
		// JavaReconcilingStrategy
		// from running concurrently on the same editor.
		// TODO remove once we have ensured that there is only one reconciler
		// per editor.
		if (editor instanceof ScriptEditor)
			fMutex = ((ScriptEditor) editor).getReconcilerLock();
		else
			fMutex = new Object(); // Null Object
	}

	/**
	 * Internal part listener for activating the reconciler.
	 */
	private class PartListener implements IPartListener {

		@Override
		public void partActivated(IWorkbenchPart part) {
			if (part == fTextEditor) {
				if (hasModelChanged())
					ScriptReconciler.this.forceReconciling();
				setEditorActive(true);
			}
		}

		@Override
		public void partBroughtToTop(IWorkbenchPart part) {
		}

		@Override
		public void partClosed(IWorkbenchPart part) {
		}

		@Override
		public void partDeactivated(IWorkbenchPart part) {
			if (part == fTextEditor) {
				setModelChanged(false);
				setEditorActive(false);
			}
		}

		@Override
		public void partOpened(IWorkbenchPart part) {
		}
	}

	/**
	 * Internal Shell activation listener for activating the reconciler.
	 */
	private class ActivationListener extends ShellAdapter {

		private Control fControl;

		public ActivationListener(Control control) {
			Assert.isNotNull(control);
			fControl = control;
		}

		@Override
		public void shellActivated(ShellEvent e) {
			if (!fControl.isDisposed() && fControl.isVisible()) {
				if (hasModelChanged())
					ScriptReconciler.this.forceReconciling();
				setEditorActive(true);
			}
		}

		@Override
		public void shellDeactivated(ShellEvent e) {
			if (!fControl.isDisposed() && fControl.getShell() == e.getSource()) {
				setModelChanged(false);
				setEditorActive(false);
			}
		}
	}

	/**
	 * Internal script element changed listener
	 *
	 * @since 3.0
	 */
	private class ElementChangedListener implements IElementChangedListener {
		@Override
		public void elementChanged(ElementChangedEvent event) {
			if (isRunningInReconcilerThread())
				return;

			if (canIgnore(event.getDelta().getAffectedChildren()))
				return;

			setModelChanged(true);
			if (isEditorActive())
				ScriptReconciler.this.forceReconciling();
		}

		/**
		 * Check whether the given delta has been sent when saving this
		 * reconciler's editor.
		 *
		 * @param delta
		 *            the deltas
		 * @return <code>true</code> if the given delta
		 * @since 5.0
		 */
		private boolean canIgnore(IModelElementDelta[] delta) {
			if (delta.length != 1)
				return false;

			// become working copy
			if (delta[0].getFlags() == IModelElementDelta.F_PRIMARY_WORKING_COPY)
				return true;

			// save
			if (delta[0].getFlags() == IModelElementDelta.F_PRIMARY_RESOURCE
					&& delta[0].getElement().equals(fReconciledElement))
				return true;

			return canIgnore(delta[0].getAffectedChildren());
		}

	}

	/**
	 * Internal resource change listener.
	 *
	 * @since 3.0
	 */
	class ResourceChangeListener implements IResourceChangeListener {

		private IResource getResource() {
			IEditorInput input = fTextEditor.getEditorInput();
			if (input instanceof IFileEditorInput) {
				IFileEditorInput fileInput = (IFileEditorInput) input;
				return fileInput.getFile();
			}
			return null;
		}

		@Override
		public void resourceChanged(IResourceChangeEvent e) {
			if (isRunningInReconcilerThread())
				return;

			IResourceDelta delta = e.getDelta();
			IResource resource = getResource();
			if (delta != null && resource != null) {
				IResourceDelta child = delta.findMember(resource.getFullPath());
				if (child != null) {
					IMarkerDelta[] deltas = child.getMarkerDeltas();
					int i = deltas.length;
					while (--i >= 0) {
						if (deltas[i].isSubtypeOf(IMarker.PROBLEM)) {
							forceReconciling();
							return;
						}
					}
				}
			}
		}
	}

	/** The reconciler's editor */
	private ITextEditor fTextEditor;
	/** The part listener */
	private IPartListener fPartListener;
	/** The shell listener */
	private ShellListener fActivationListener;
	/**
	 * The mutex that keeps us from running multiple reconcilers on one editor.
	 */
	private Object fMutex;
	/**
	 * The script element changed listener.
	 *
	 * @since 3.0
	 */
	private IElementChangedListener fScriptElementChangedListener;
	/**
	 * Tells whether the script model sent out a changed event.
	 *
	 * @since 3.0
	 */
	private volatile boolean fHasModelChanged = true;
	/**
	 * Tells whether this reconciler's editor is active.
	 *
	 * @since 3.1
	 */
	private volatile boolean fIsEditorActive = true;
	/**
	 * The resource change listener.
	 *
	 * @since 3.0
	 */
	private IResourceChangeListener fResourceChangeListener;
	/**
	 * The property change listener.
	 *
	 * @since 3.3
	 */
	private IPropertyChangeListener fPropertyChangeListener;

	private boolean fIninitalProcessDone = false;

	/**
	 * The element that this reconciler reconciles.
	 *
	 * @since 3.4
	 */
	private ISourceModule fReconciledElement;

	@Override
	public void install(ITextViewer textViewer) {
		super.install(textViewer);

		fPartListener = new PartListener();
		IWorkbenchPartSite site = fTextEditor.getSite();
		IWorkbenchWindow window = site.getWorkbenchWindow();
		window.getPartService().addPartListener(fPartListener);

		fActivationListener = new ActivationListener(textViewer.getTextWidget());
		Shell shell = window.getShell();
		shell.addShellListener(fActivationListener);

		fScriptElementChangedListener = new ElementChangedListener();
		DLTKCore.addElementChangedListener(fScriptElementChangedListener);

		fResourceChangeListener = new ResourceChangeListener();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(
				fResourceChangeListener);

		final IPreferenceStore store = getCombinedPreferenceStore();
		if (store != null) {
			fPropertyChangeListener = event -> {
				if (SpellingService.PREFERENCE_SPELLING_ENABLED
						.equals(event.getProperty())
						|| SpellingService.PREFERENCE_SPELLING_ENGINE
								.equals(event.getProperty()))
					forceReconciling();
			};
			store.addPropertyChangeListener(fPropertyChangeListener);
		}

		fReconciledElement = EditorUtility.getEditorInputModelElement(
				fTextEditor, false);
	}

	protected IPreferenceStore getCombinedPreferenceStore() {
		// JavaPlugin.getDefault().getCombinedPreferenceStore()
		// TODO implement when needed
		return null;
	}

	@Override
	public void uninstall() {

		IWorkbenchPartSite site = fTextEditor.getSite();
		IWorkbenchWindow window = site.getWorkbenchWindow();
		window.getPartService().removePartListener(fPartListener);
		fPartListener = null;

		Shell shell = window.getShell();
		if (shell != null && !shell.isDisposed())
			shell.removeShellListener(fActivationListener);
		fActivationListener = null;

		DLTKCore.removeElementChangedListener(fScriptElementChangedListener);
		fScriptElementChangedListener = null;

		ResourcesPlugin.getWorkspace().removeResourceChangeListener(
				fResourceChangeListener);
		fResourceChangeListener = null;

		if (fPropertyChangeListener != null) {
			final IPreferenceStore store = getCombinedPreferenceStore();
			if (store != null) {
				store.removePropertyChangeListener(fPropertyChangeListener);
			}
			fPropertyChangeListener = null;
		}

		super.uninstall();
	}

	@Override
	protected void forceReconciling() {
		if (!fIninitalProcessDone)
			return;

		super.forceReconciling();
		ScriptCompositeReconcilingStrategy strategy = (ScriptCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
		strategy.notifyListeners(false);
	}

	@Override
	protected void aboutToBeReconciled() {
		ScriptCompositeReconcilingStrategy strategy = (ScriptCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
		strategy.aboutToBeReconciled();
	}

	@Override
	protected void reconcilerReset() {
		super.reconcilerReset();
		ScriptCompositeReconcilingStrategy strategy = (ScriptCompositeReconcilingStrategy) getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
		strategy.notifyListeners(true);
	}

	@Override
	protected void initialProcess() {
		synchronized (fMutex) {
			super.initialProcess();
		}
		fIninitalProcessDone = true;
	}

	/**
	 * Tells whether the script Model has changed or not.
	 *
	 * @return <code>true</code> iff the script Model has changed
	 * @since 3.0
	 */
	private synchronized boolean hasModelChanged() {
		return fHasModelChanged;
	}

	/**
	 * Sets whether the script Model has changed or not.
	 *
	 * @param state
	 *            <code>true</code> iff the script model has changed
	 * @since 3.0
	 */
	private synchronized void setModelChanged(boolean state) {
		fHasModelChanged = state;
	}

	/**
	 * Tells whether this reconciler's editor is active.
	 *
	 * @return <code>true</code> iff the editor is active
	 * @since 3.1
	 */
	private synchronized boolean isEditorActive() {
		return fIsEditorActive;
	}

	/**
	 * Sets whether this reconciler's editor is active.
	 *
	 * @param state
	 *            <code>true</code> iff the editor is active
	 * @since 3.1
	 */
	private synchronized void setEditorActive(boolean state) {
		fIsEditorActive = state;
	}
}
