/*=============================================================================#
 # Copyright (c) 2007, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.spelling.SpellingProblem;

import org.eclipse.statet.ecommons.text.IIndentSettings;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.text.ui.presentation.ITextPresentationConstants;
import org.eclipse.statet.ecommons.text.ui.settings.DecorationPreferences;
import org.eclipse.statet.ecommons.ui.ISettingsChangedHandler;


/**
 * Controls the configuration of an {@link ISourceEditor}.
 */
public abstract class SourceEditorViewerConfigurator implements ISettingsChangedHandler,
		PropertyChangeListener {
	
	
	private final SourceEditorViewerConfiguration configuration;
	
	private ISourceEditor sourceEditor;
	
	private final List<ISourceEditorAddon> addons= new ArrayList<>();
	private List<ISourceEditorAddon> configurationAddons;
	
	protected boolean isConfigured;
	
	protected boolean updateCompleteConfig;
	protected boolean updateTextPresentation;
	protected boolean updateTabSize;
	protected boolean updateIndent;
	protected boolean updateInfoHovers;
	
	
	protected SourceEditorViewerConfigurator(final SourceEditorViewerConfiguration config) {
		if (config == null) {
			throw new NullPointerException("config");
		}
		this.configuration= config;
	}
	
	
	/**
	 * A setup participant for the document of the editor.
	 * 
	 * @return a document setup participant or <code>null</code>.
	 */
	public abstract IDocumentSetupParticipant getDocumentSetupParticipant();
	
	public final DocContentSections getDocumentContentInfo() {
		return this.configuration.getDocumentContentInfo();
	}
	
	protected abstract Set<String> getResetGroupIds();
	
	public SourceEditorViewerConfiguration getSourceViewerConfiguration() {
		return this.configuration;
	}
	
	public void configureSourceViewerDecorationSupport(final SourceViewerDecorationSupport support) {
		final ICharacterPairMatcher pairMatcher= this.configuration.getPairMatcher();
		final DecorationPreferences preferences= this.configuration.getDecorationPreferences();
		if (pairMatcher != null && preferences != null) {
			support.setCharacterPairMatcher(pairMatcher);
			support.setMatchingCharacterPainterPreferenceKeys(
					preferences.getMatchingBracketsEnabled().getKey(),
					preferences.getMatchingBracketsColor().getKey() );
		}
	}
	
	
	public void setTarget(final ISourceEditor sourceEditor) {
		assert (sourceEditor != null);
		this.sourceEditor= sourceEditor;
		if (!(this.sourceEditor instanceof AbstractDecoratedTextEditor)) {
			this.sourceEditor.getViewer().getControl().addDisposeListener(new DisposeListener() {
				@Override
				public void widgetDisposed(final DisposeEvent e) {
					if (SourceEditorViewerConfigurator.this.isConfigured) {
						uninstallCurrentAddons();
					}
				}
			});
			configureTarget();
		}
		else {
			this.isConfigured= true;
			installCurrentAddons();
		}
		handleSettingsChanged(null, null);
	}
	
	protected ISourceViewer getSourceViewer() {
		if (this.sourceEditor != null) {
			return this.sourceEditor.getViewer();
		}
		return null;
	}
	
	public final void unconfigureTarget() {
		if (this.sourceEditor != null) {
			this.isConfigured= false;
			uninstallCurrentAddons();
			this.sourceEditor.getViewer().unconfigure();
		}
	}
	
	public final void configureTarget() {
		if (this.sourceEditor != null) {
			this.isConfigured= true;
			this.sourceEditor.getViewer().configure(this.configuration);
			installCurrentAddons();
		}
	}
	
	private void installCurrentAddons() {
		this.configurationAddons= getSourceViewerConfiguration().getAddOns();
		for (final ISourceEditorAddon addon : this.configurationAddons) {
			addon.install(this.sourceEditor);
		}
		for (final ISourceEditorAddon addon : this.addons) {
			addon.install(this.sourceEditor);
		}
	}
	
	private void uninstallCurrentAddons() {
		for (final ISourceEditorAddon addon : this.addons) {
			addon.uninstall();
		}
		if (this.configurationAddons != null) {
			for (final ISourceEditorAddon addon : this.configurationAddons) {
				addon.uninstall();
			}
			this.configurationAddons= null;
		}
	}
	
	public final void installAddon(final ISourceEditorAddon installable) {
		this.addons.add(installable);
		if (this.isConfigured) {
			installable.install(this.sourceEditor);
		}
	}
	
	@Override
	public void propertyChange(final PropertyChangeEvent event) {
		final String name= event.getPropertyName();
		if (name.equals(IIndentSettings.TAB_SIZE_PROP)) {
			this.updateTabSize= true;
			this.updateIndent= true;
			return;
		}
		if (name.equals(IIndentSettings.INDENT_SPACES_COUNT_PROP)
				|| name.equals(IIndentSettings.INDENT_DEFAULT_TYPE_PROP)) {
			this.updateIndent= true;
			return;
		}
	}
	
	@Override
	public void handleSettingsChanged(Set<String> groupIds, Map<String, Object> options) {
		final SourceViewer viewer;
		if (this.sourceEditor == null || (viewer= this.sourceEditor.getViewer()) == null) {
			return;
		}
		final Point selectedRange= viewer.getSelectedRange();
		if (groupIds == null) {
			groupIds= getResetGroupIds();
		}
		if (options == null) {
			options= new HashMap<>();
		}
		options.put(ISettingsChangedHandler.VIEWER_KEY, viewer);
		
		checkSettingsChanges(groupIds, options);
		
		if (options.containsKey(ITextPresentationConstants.SETTINGSCHANGE_AFFECTSPRESENTATION_KEY)) {
			this.updateTextPresentation= true;
		}
		
		updateSourceViewer(viewer);
		viewer.setSelectedRange(selectedRange.x, selectedRange.y);
	}
	
	protected void checkSettingsChanges(final Set<String> groupIds, final Map<String, Object> options) {
		this.configuration.handleSettingsChanged(groupIds, options);
	}
	
	
	protected void updateSourceViewer(final ISourceViewer viewer) {
		if (!this.isConfigured) {
			return;
		}
		if (this.updateCompleteConfig) {
			if (this.sourceEditor instanceof ITextEditor) {
				SpellingProblem.removeAllInActiveEditor((ITextEditor) this.sourceEditor, null);
			}
			reconfigureSourceViewer();
		}
		else {
			if (this.updateTabSize) {
				viewer.getTextWidget().setTabs(getSourceViewerConfiguration().getTabWidth(viewer));
			}
			if (this.updateTextPresentation) {
				viewer.invalidateTextPresentation();
			}
			if (this.updateIndent && this.sourceEditor instanceof SourceEditor1) {
				((SourceEditor1) this.sourceEditor).updateIndentSettings();
			}
			if (this.updateInfoHovers) {
				updateConfiguredInfoHovers();
			}
		}
		
		this.updateCompleteConfig= false;
		this.updateTextPresentation= false;
		this.updateTabSize= false;
		this.updateIndent= false;
	}
	
	private final void reconfigureSourceViewer() {
		if (this.isConfigured) {
			this.isConfigured= false;
			this.sourceEditor.getViewer().unconfigure();
			this.isConfigured= true;
			this.sourceEditor.getViewer().configure(this.configuration);
		}
	}
	
	private void updateConfiguredInfoHovers() {
		final SourceViewer viewer= this.sourceEditor.getViewer();
		final String[] contentTypes= this.configuration.getConfiguredContentTypes(viewer);
		for (final String contentType : contentTypes) {
			((ITextViewerExtension2)viewer).removeTextHovers(contentType);
			final int[] stateMasks= this.configuration.getConfiguredTextHoverStateMasks(viewer, contentType);
			if (stateMasks != null) {
				for (int j= 0; j < stateMasks.length; j++)	{
					final int stateMask= stateMasks[j];
					final ITextHover textHover= this.configuration.getTextHover(viewer, contentType, stateMask);
					if (textHover != null) {
						viewer.setTextHover(textHover, contentType, stateMask);
					}
				}
			}
			else {
				final ITextHover textHover= this.configuration.getTextHover(viewer, contentType);
				if (textHover != null) {
					viewer.setTextHover(textHover, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
				}
			}
		}
	}
	
}
