/*=============================================================================#
 # 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.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.presentation.IPresentationDamager;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.IPresentationRepairer;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssist;
import org.eclipse.statet.ltk.ui.sourceediting.assist.MultiContentSectionQuickAssistProcessor;


/**
 * Configuration for source viewers supporting multiple document content section types.
 */
public class MultiContentSectionSourceViewerConfiguration extends SourceEditorViewerConfiguration {
	
	
	private class LazyPresentationReconciler extends PresentationReconciler {
		
		
		private IDocument document;
		
		
		public LazyPresentationReconciler() {
		}
		
		
		@Override
		public void setDamager(final IPresentationDamager damager, final String contentType) {
			if (damager != null && this.document != null) {
				damager.setDocument(this.document);
			}
			super.setDamager(damager, contentType);
		}
		
		@Override
		public void setRepairer(final IPresentationRepairer repairer, final String contentType) {
			if (repairer != null && this.document != null) {
				repairer.setDocument(this.document);
			}
			super.setRepairer(repairer, contentType);
		}
		
		@Override
		public IPresentationDamager getDamager(final String contentType) {
			IPresentationDamager damager= super.getDamager(contentType);
			if (damager == null && checkInit(
					MultiContentSectionSourceViewerConfiguration.this.sections.getTypeByPartition(contentType) )) {
				damager= super.getDamager(contentType);
			}
			if (DEBUG && damager == null) {
				StatusManager.getManager().handle(new Status(IStatus.WARNING, LTKUIPlugin.BUNDLE_ID,
						"No presentation damager for contentType= " + contentType + "." ));
			}
			return damager;
		}
		
		@Override
		public IPresentationRepairer getRepairer(final String contentType) {
			IPresentationRepairer repairer= super.getRepairer(contentType);
			if (repairer == null && checkInit(
					MultiContentSectionSourceViewerConfiguration.this.sections.getTypeByPartition(contentType) )) {
				repairer= super.getRepairer(contentType);
			}
			if (DEBUG && repairer == null) {
				StatusManager.getManager().handle(new Status(IStatus.WARNING, LTKUIPlugin.BUNDLE_ID,
						"No presentation repairer for contentType= " + contentType + "." ));
			}
			return repairer;
		}
		
		@Override
		protected void setDocumentToDamagers(final IDocument document) {
			this.document= document;
			super.setDocumentToDamagers(document);
		}
		
	}
	
	private class LazyContentAssist extends ContentAssist {
		
		
		public LazyContentAssist() {
		}
		
		
		@Override
		public IContentAssistProcessor getContentAssistProcessor(final String contentType) {
			IContentAssistProcessor processor= super.getContentAssistProcessor(contentType);
			if (processor == null && checkInit(
					MultiContentSectionSourceViewerConfiguration.this.sections.getTypeByPartition(contentType) )) {
				processor= super.getContentAssistProcessor(contentType);
			}
			return processor;
		}
		
	}
	
	
	private final DocContentSections sections;
	
	private SourceEditorViewerConfiguration primaryConfig;
	private final Map<String, SourceEditorViewerConfiguration> secondaryConfigs= new IdentityHashMap<>(8);
	private final Map<String, Integer> secondaryConfigStates= new IdentityHashMap<>();
	
	
	public MultiContentSectionSourceViewerConfiguration(final DocContentSections sections, final int flags,
			final ISourceEditor sourceEditor) {
		super(sections, flags, sourceEditor);
		
		this.sections= sections;
	}
	
	
	protected void registerConfig(final String sectionType, final SourceEditorViewerConfiguration config) {
		if (sectionType == null) {
			throw new NullPointerException("sectionType"); //$NON-NLS-1$
		}
		if (sectionType == this.sections.getPrimaryType()) {
			this.primaryConfig= config;
		}
		else {
			this.secondaryConfigs.put(sectionType, config);
		}
	}
	
	protected final SourceEditorViewerConfiguration getConfig(final String sectionType) {
		if (sectionType == this.sections.getPrimaryType()) {
			return this.primaryConfig;
		}
		else {
			return this.secondaryConfigs.get(sectionType);
		}
	}
	
	protected final SourceEditorViewerConfiguration getConfigSafe(final String sectionType) {
		if (sectionType == null || sectionType == this.sections.getPrimaryType()) {
			return this.primaryConfig;
		}
		final SourceEditorViewerConfiguration config= this.secondaryConfigs.get(sectionType);
		return (config != null) ? config : this.primaryConfig;
	}
	
	
	protected boolean checkInit(final String type) {
		if (type == null) {
			return false;
		}
		
		final SourceEditorViewerConfiguration config= this.secondaryConfigs.get(type);
		if (config != null) {
			final Integer state= this.secondaryConfigStates.put(type, Integer.valueOf(1));
			if (state == null) {
				config.initPresentationReconciler(getPresentationReconciler());
				
				{	final ContentAssist contentAssist= getContentAssist();
					if (contentAssist instanceof LazyContentAssist) {
						config.initContentAssist(contentAssist);
					}
				}
				
				return true;
			}
		}
		
		return false;
	}
	
	
	@Override
	public List<ISourceEditorAddon> getAddOns() {
		final List<ISourceEditorAddon> addOns= super.getAddOns();
		
		addOns.addAll(this.primaryConfig.getAddOns());
		for (final SourceEditorViewerConfiguration config : this.secondaryConfigs.values()) {
			addOns.addAll(config.getAddOns());
		}
		
		return addOns;
	}
	
	@Override
	public void handleSettingsChanged(final Set<String> groupIds, final Map<String, Object> options) {
		for (final SourceEditorViewerConfiguration config : this.secondaryConfigs.values()) {
			config.handleSettingsChanged(groupIds, options);
		}
		this.primaryConfig.handleSettingsChanged(groupIds, options);
		
		super.handleSettingsChanged(groupIds, options);
	}
	
	
	@Override
	protected IPresentationReconciler createPresentationReconciler() {
		final PresentationReconciler reconciler= new LazyPresentationReconciler();
		reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
		
		initPresentationReconciler(reconciler);
		
		return reconciler;
	}
	
	@Override
	protected void initPresentationReconciler(final PresentationReconciler reconciler) {
		this.primaryConfig.initPresentationReconciler(reconciler);
		// secondary are initialized lazily
	}
	
	
	@Override
	public int getTabWidth(final ISourceViewer sourceViewer) {
		final SourceEditorViewerConfiguration config= getConfigSafe(null);
		return config.getTabWidth(sourceViewer);
	}
	
	@Override
	public String[] getDefaultPrefixes(final ISourceViewer sourceViewer, final String contentType) {
		final SourceEditorViewerConfiguration config= getConfigSafe(this.sections.getTypeByPartition(contentType));
		return config.getDefaultPrefixes(sourceViewer, contentType);
	}
	
	@Override
	public String[] getIndentPrefixes(final ISourceViewer sourceViewer, final String contentType) {
		final SourceEditorViewerConfiguration config= getConfig(this.sections.getTypeByPartition(contentType));
		if (config != null) {
			return config.getIndentPrefixes(sourceViewer, contentType);
		}
		return null;
	}
	
	
	@Override
	public boolean isSmartInsertSupported() {
		final SourceEditorViewerConfiguration config= getConfigSafe(null);
		return config.isSmartInsertSupported();
	}
	
	@Override
	public boolean isSmartInsertByDefault() {
		final SourceEditorViewerConfiguration config= getConfigSafe(null);
		return config.isSmartInsertByDefault();
	}
	
	
	@Override
	public IAutoEditStrategy[] getAutoEditStrategies(final ISourceViewer sourceViewer, final String contentType) {
		final SourceEditorViewerConfiguration config= getConfig(this.sections.getTypeByPartition(contentType));
		if (config != null) {
			return config.getAutoEditStrategies(sourceViewer, contentType);
		}
		return null;
	}
	
	
	@Override
	protected ContentAssist createContentAssistant(final ISourceViewer sourceViewer) {
		if (getSourceEditor() != null) {
			final ContentAssist assistant= new LazyContentAssist();
			assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(null));
			assistant.setRestoreCompletionProposalSize(DialogUtils.getDialogSettings(LTKUIPlugin.getInstance(), "ContentAssist.Proposal.size")); //$NON-NLS-1$
			
			initContentAssist(assistant);
			return assistant;
		}
		return null;
	}
	
	@Override
	protected void initContentAssist(final ContentAssist assistant) {
		this.primaryConfig.initContentAssist(assistant);
		
		// secondary are initialized lazily
		if (!this.secondaryConfigStates.isEmpty()) {
			// a secondary type is already initialized?
			for (final String type : this.secondaryConfigStates.keySet()) {
				// this.secondaryConfigStates.get(type) > 0
				this.secondaryConfigs.get(type).initContentAssist(assistant);
			}
		}
	}
	
	@Override
	protected IQuickAssistProcessor createQuickAssistProcessor() {
		return new MultiContentSectionQuickAssistProcessor(this.sections) {
			@Override
			protected IQuickAssistProcessor createProcessor(final String sectionType) {
				final SourceEditorViewerConfiguration config= getConfig(sectionType);
				if (config != null) {
					return config.createQuickAssistProcessor();
				}
				return null;
			}
		};
	}
	
	
	@Override
	protected int[] getInfoHoverStateMasks(final String contentType) {
		final SourceEditorViewerConfiguration config= getConfig(this.sections.getTypeByPartition(contentType));
		if (config != null) {
			return config.getInfoHoverStateMasks(contentType);
		}
		return null;
	}
	
	@Override
	protected ITextHover getInfoHover(final ISourceViewer sourceViewer, final String contentType,
			final int stateMask) {
		final SourceEditorViewerConfiguration config= getConfig(this.sections.getTypeByPartition(contentType));
		if (config != null) {
			return config.getTextHover(sourceViewer, contentType, stateMask);
		}
		return null;
	}
	
	@Override
	protected IInformationProvider getInformationProvider() {
		return new MultiContentSectionInformationProvider(this.sections) {
			@Override
			protected EditorInformationProvider createHandler(final String sectionType) {
				final SourceEditorViewerConfiguration config= getConfig(sectionType);
				if (config != null) {
					final IInformationProvider provider= config.getInformationProvider();
					if (provider instanceof EditorInformationProvider) {
						return (EditorInformationProvider) provider;
					}
				}
				return null;
			}
		};
	}
	
	
	@Override
	protected void collectHyperlinkDetectorTargets(final java.util.Map<String, IAdaptable> targets, final ISourceViewer sourceViewer) {
		this.primaryConfig.collectHyperlinkDetectorTargets(targets, sourceViewer);
		for (final SourceEditorViewerConfiguration config : this.secondaryConfigs.values()) {
			config.collectHyperlinkDetectorTargets(targets, sourceViewer);
		}
	}
	
}
