/*=============================================================================#
 # Copyright (c) 2007, 2019 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.redocs.wikitext.r.ui.editors;

import static org.eclipse.statet.ecommons.ui.actions.UIActions.ADDITIONS_GROUP_ID;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.commands.IHandler2;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.templates.ITemplatesPage;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.base.ui.IStatetUIMenuIds;
import org.eclipse.statet.docmlet.base.ui.DocmlBaseUI;
import org.eclipse.statet.docmlet.base.ui.markuphelp.MarkupHelpContextProvider;
import org.eclipse.statet.docmlet.base.ui.processing.actions.RunDocProcessingOnSaveExtension;
import org.eclipse.statet.docmlet.base.ui.sourceediting.DocEditor;
import org.eclipse.statet.docmlet.wikitext.core.WikitextCore;
import org.eclipse.statet.docmlet.wikitext.core.ast.WikitextAstNode;
import org.eclipse.statet.docmlet.wikitext.core.model.WikitextModel;
import org.eclipse.statet.docmlet.wikitext.ui.WikitextUI;
import org.eclipse.statet.docmlet.wikitext.ui.editors.WikidocDefaultFoldingProvider;
import org.eclipse.statet.docmlet.wikitext.ui.editors.WikitextMarkOccurrencesLocator;
import org.eclipse.statet.docmlet.wikitext.ui.sourceediting.WikitextEditingSettings;
import org.eclipse.statet.internal.redocs.wikitext.r.RedocsWikitextRPlugin;
import org.eclipse.statet.internal.redocs.wikitext.r.ui.editors.WikidocRweaveEditorTemplatesPage;
import org.eclipse.statet.internal.redocs.wikitext.r.ui.editors.WikidocRweaveOutlinePage;
import org.eclipse.statet.ltk.ast.core.util.AstSelection;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.sourceediting.AbstractMarkOccurrencesProvider;
import org.eclipse.statet.ltk.ui.sourceediting.ForwardSourceDocumentProvider;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorAddon;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1OutlinePage;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditorViewer;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditorViewerConfigurator;
import org.eclipse.statet.ltk.ui.sourceediting.folding.FoldingEditorAddon;
import org.eclipse.statet.r.core.IRCoreAccess;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
import org.eclipse.statet.r.launching.RCodeLaunching;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.editors.IRSourceEditor;
import org.eclipse.statet.r.ui.editors.RCorrectIndentHandler;
import org.eclipse.statet.r.ui.editors.RDefaultFoldingProvider;
import org.eclipse.statet.r.ui.editors.RMarkOccurrencesLocator;
import org.eclipse.statet.r.ui.sourceediting.InsertAssignmentHandler;
import org.eclipse.statet.redocs.r.core.source.DocContentSectionsRweaveExtension;
import org.eclipse.statet.redocs.r.ui.RedocsRUI;
import org.eclipse.statet.redocs.r.ui.sourceediting.actions.RweaveToggleCommentHandler;
import org.eclipse.statet.redocs.wikitext.r.core.model.WikidocRweaveSourceUnit;
import org.eclipse.statet.redocs.wikitext.r.core.source.RweaveMarkupLanguage;
import org.eclipse.statet.redocs.wikitext.r.core.source.WikidocRweaveDocumentContentInfo;
import org.eclipse.statet.redocs.wikitext.r.core.source.WikidocRweaveDocumentSetupParticipant;
import org.eclipse.statet.redocs.wikitext.r.ui.WikitextRweaveUI;
import org.eclipse.statet.redocs.wikitext.r.ui.sourceediting.WikidocRweaveSourceViewerConfiguration;
import org.eclipse.statet.redocs.wikitext.r.ui.sourceediting.WikidocRweaveSourceViewerConfigurator;
import org.eclipse.statet.rj.renv.core.REnv;


/**
 * Editor for Wikitext-R documents.
 */
public abstract class WikidocRweaveDocEditor extends SourceEditor1 implements WikidocRweaveEditor,
		DocEditor, MarkupHelpContextProvider {
	
	
	private static final ImList<String> KEY_CONTEXTS= ImCollections.newIdentityList(
			WikitextUI.EDITOR_CONTEXT_ID,
			DocmlBaseUI.DOC_EDITOR_CONTEXT_ID,
			RedocsRUI.RWEAVE_EDITOR_CONTEXT_ID );
	
	private static final ImList<String> CONTEXT_IDS= ImCollections.concatList(
			ACTION_SET_CONTEXT_IDS, KEY_CONTEXTS );
	
	
	private static class ThisMarkOccurrencesProvider extends AbstractMarkOccurrencesProvider {
		
		
		private final WikitextMarkOccurrencesLocator docLocator= new WikitextMarkOccurrencesLocator();
		private final RMarkOccurrencesLocator rLocator= new RMarkOccurrencesLocator();
		
		
		public ThisMarkOccurrencesProvider(final SourceEditor1 editor) {
			super(editor, IRDocumentConstants.R_DEFAULT_CONTENT_CONSTRAINT);
		}
		
		@Override
		protected void doUpdate(final RunData run, final ISourceUnitModelInfo info,
				final AstSelection astSelection, final ITextSelection orgSelection)
				throws BadLocationException, BadPartitioningException, UnsupportedOperationException {
			if (astSelection.getCovering() instanceof WikitextAstNode) {
				this.docLocator.run(run, info, astSelection, orgSelection);
			}
			else if (astSelection.getCovering() instanceof RAstNode) {
				this.rLocator.run(run, info, astSelection, orgSelection);
			}
		}
		
	}
	
	private static class ThisCorrectIndentHandler extends RCorrectIndentHandler {
		
		public ThisCorrectIndentHandler(final IRSourceEditor editor) {
			super(editor);
		}
		
		@Override
		protected List<? extends TextRegion> getCodeRanges(final AbstractDocument document,
				final ITextSelection selection) throws BadLocationException {
			return WikidocRweaveDocumentContentInfo.INSTANCE.getRChunkCodeRegions(document,
					selection.getOffset(), selection.getLength() );
		}
		
	}
	
	
	private final WikidocRweaveDocumentSetupParticipant documentSetup;
	
	private WikidocRweaveSourceViewerConfigurator combinedConfig;
	
	private final RunDocProcessingOnSaveExtension autoDocProcessing;
	
	
	public WikidocRweaveDocEditor(final IContentType contentType,
			final WikidocRweaveDocumentSetupParticipant documentSetup) {
		super(contentType);
		if (documentSetup == null) {
			throw new NullPointerException("documentSetup"); //$NON-NLS-1$
		}
		this.documentSetup= documentSetup;
		
		this.autoDocProcessing= new RunDocProcessingOnSaveExtension(this);
		
		initializeEditor();
	}
	
	
	@Override
	protected void initializeEditor() {
		if (this.documentSetup == null) {
			return;
		}
		
		super.initializeEditor();
		
		setEditorContextMenuId("org.eclipse.statet.redocs.menus.WikidocRweaveEditorContextMenu"); //$NON-NLS-1$
		setRulerContextMenuId("org.eclipse.statet.redocs.menus.WikidocRweaveEditorRulerMenu"); //$NON-NLS-1$
	}
	
	@Override
	protected SourceEditorViewerConfigurator createConfiguration() {
		setDocumentProvider(new ForwardSourceDocumentProvider(
				RedocsWikitextRPlugin.getInstance().getDocRDocumentProvider(),
				this.documentSetup ));
		
		enableStructuralFeatures(WikitextModel.getWikidocModelManager(),
				WikitextEditingSettings.FOLDING_ENABLED_PREF,
				WikitextEditingSettings.MARKOCCURRENCES_ENABLED_PREF );
		
		this.combinedConfig= new WikidocRweaveSourceViewerConfigurator(
				this.documentSetup,
				WikitextCore.WORKBENCH_ACCESS, RCore.WORKBENCH_ACCESS,
				new WikidocRweaveSourceViewerConfiguration(0, this, null, null, null) );
		return this.combinedConfig;
	}
	
	@Override
	protected int getSourceViewerFlags() {
		return SourceEditorViewer.VARIABLE_LINE_HEIGHT;
	}
	
	@Override
	protected Collection<String> getContextIds() {
		return CONTEXT_IDS;
	}
	
	@Override
	protected ISourceEditorAddon createCodeFoldingProvider() {
		return new FoldingEditorAddon(new WikidocDefaultFoldingProvider(Collections.singletonMap(
				RweaveMarkupLanguage.EMBEDDED_R, new RDefaultFoldingProvider() )));
	}
	
	@Override
	protected ISourceEditorAddon createMarkOccurrencesProvider() {
		return new ThisMarkOccurrencesProvider(this);
	}
	
	
	@Override
	public IRCoreAccess getRCoreAccess() {
		return this.combinedConfig.getRCoreAccess();
	}
	
	@Override
	public DocContentSectionsRweaveExtension getDocumentContentInfo() {
		return (DocContentSectionsRweaveExtension) super.getDocumentContentInfo();
	}
	
	@Override
	public WikidocRweaveSourceUnit getSourceUnit() {
		return (WikidocRweaveSourceUnit) super.getSourceUnit();
	}
	
	@Override
	protected void setupConfiguration(final IEditorInput newInput) {
		super.setupConfiguration(newInput);
		
		final WikidocRweaveSourceUnit su= getSourceUnit();
		this.combinedConfig.setSource(
				(su != null) ? su.getWikitextCoreAccess() : WikitextCore.WORKBENCH_ACCESS,
				(su != null) ? su.getRCoreAccess() : RCore.WORKBENCH_ACCESS );
		
		this.autoDocProcessing.setAutoRunEnabled(false);
	}
	
	
	@Override
	protected void handlePreferenceStoreChanged(final org.eclipse.jface.util.PropertyChangeEvent event) {
		if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH.equals(event.getProperty())
				|| AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS.equals(event.getProperty())) {
			return;
		}
		super.handlePreferenceStoreChanged(event);
	}
	
	
	@Override
	protected boolean isTabsToSpacesConversionEnabled() {
		return false;
	}
	
	public void updateSettings(final boolean indentChanged) {
		if (indentChanged) {
			updateIndentPrefixes();
		}
	}
	
	
	@Override
	protected void collectContextMenuPreferencePages(final List<String> pageIds) {
		super.collectContextMenuPreferencePages(pageIds);
		pageIds.add(WikitextRweaveUI.EDITOR_PREF_PAGE_ID);
		pageIds.add(WikitextUI.EDITOR_PREF_PAGE_ID);
		pageIds.add("org.eclipse.mylyn.internal.wikitext.ui.editor.preferences.WikiTextTemplatePreferencePage"); //$NON-NLS-1$
		pageIds.add("org.eclipse.statet.docmlet.preferencePages.WikitextCodeStyle"); //$NON-NLS-1$
		pageIds.add("org.eclipse.statet.r.preferencePages.REditorOptions"); //$NON-NLS-1$
		pageIds.add("org.eclipse.statet.r.preferencePages.RTextStyles"); //$NON-NLS-1$
		pageIds.add("org.eclipse.statet.r.preferencePages.REditorTemplates"); //$NON-NLS-1$
		pageIds.add("org.eclipse.statet.r.preferencePages.RCodeStyle"); //$NON-NLS-1$
	}
	
	@Override
	protected void createActions() {
		super.createActions();
		final IHandlerService handlerService= getServiceLocator()
				.getService(IHandlerService.class);
		
		{	final IHandler2 handler= new InsertAssignmentHandler(this);
			handlerService.activateHandler(LTKUI.INSERT_ASSIGNMENT_COMMAND_ID, handler);
			markAsStateDependentHandler(handler, true);
		}
	}
	
	@Override
	protected IHandler2 createToggleCommentHandler() {
		final IHandler2 handler= new RweaveToggleCommentHandler(this) {
			@Override
			protected Pattern getPrefixPattern(final String contentType, final String prefix) {
				if (prefix.equals("<!--")) { //$NON-NLS-1$
					return HTML_SPACE_PREFIX_PATTERN;
				}
				return super.getPrefixPattern(contentType, prefix);
			}
			@Override
			protected Pattern getPostfixPattern(final String contentType, final String prefix) {
				if (prefix.equals("<!--")) { //$NON-NLS-1$
					return HTML_SPACE_POSTFIX_PATTERN;
				}
				return super.getPostfixPattern(contentType, prefix);
			}
			@Override
			protected void doPrefixPrimary(final AbstractDocument document, final IRegion block)
					throws BadLocationException, BadPartitioningException {
				doPrefix(document, block, "<!-- ", " -->"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		};
		markAsStateDependentHandler(handler, true);
		return handler;
	}
	
	@Override
	protected IHandler2 createCorrectIndentHandler() {
		final IHandler2 handler= new ThisCorrectIndentHandler(this);
		markAsStateDependentHandler(handler, true);
		return handler;
	}
	
	@Override
	protected void editorContextMenuAboutToShow(final IMenuManager m) {
		super.editorContextMenuAboutToShow(m);
		final WikidocRweaveSourceUnit su= getSourceUnit();
		
		m.insertBefore(ADDITIONS_GROUP_ID, new Separator(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID));
		final IContributionItem additions= m.find(ADDITIONS_GROUP_ID);
		if (additions != null) {
			additions.setVisible(false);
		}
		
		m.remove(ITextEditorActionConstants.SHIFT_RIGHT);
		m.remove(ITextEditorActionConstants.SHIFT_LEFT);
		
		m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, new CommandContributionItem(
				new CommandContributionItemParameter(getSite(), null,
						RCodeLaunching.SUBMIT_SELECTION_COMMAND_ID,
						CommandContributionItem.STYLE_PUSH )));
		m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, new CommandContributionItem(
				new CommandContributionItemParameter(getSite(), null,
						RCodeLaunching.SUBMIT_UPTO_SELECTION_COMMAND_ID,
						CommandContributionItem.STYLE_PUSH )));
		
		m.appendToGroup(ITextEditorActionConstants.GROUP_SETTINGS, new CommandContributionItem(
				new CommandContributionItemParameter(getSite(), null,
						DocmlBaseUI.CONFIGURE_MARKUP_COMMAND_ID, null,
						null, null, null,
						"Configure Markup...", "M", null,
						CommandContributionItem.STYLE_PUSH, null, false )));
	}
	
	
	@Override
	protected void editorSaved() {
		super.editorSaved();
		
		this.autoDocProcessing.onEditorSaved();
	}
	
	
	@Override
	protected SourceEditor1OutlinePage createOutlinePage() {
		return new WikidocRweaveOutlinePage(this);
	}
	
	@Override
	protected ITemplatesPage createTemplatesPage() {
		return new WikidocRweaveEditorTemplatesPage(this, getSourceViewer());
	}
	
	@Override
	public String[] getShowInTargetIds() {
		return new String[] { IPageLayout.ID_PROJECT_EXPLORER, IPageLayout.ID_OUTLINE, RUI.R_HELP_VIEW_ID };
	}
	
	@Override
	public @Nullable String getHelpContentId() {
		return WikitextUI.getMarkupHelpContentIdFor(this.documentSetup.getMarkupLanguage());
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(final Class<T> adapterType) {
		if (adapterType == MarkupHelpContextProvider.class) {
			return (T) this;
		}
		if (adapterType == RunDocProcessingOnSaveExtension.class) {
			return (T) this.autoDocProcessing;
		}
		if (adapterType == REnv.class) {
			return (T) getRCoreAccess().getREnv();
		}
		return super.getAdapter(adapterType);
	}
	
}
