/*=============================================================================#
 # Copyright (c) 2005, 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.internal.r.ui.editors;

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

import java.util.Collection;
import java.util.List;

import org.eclipse.core.commands.IHandler2;
import org.eclipse.help.IContextProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
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.jface.text.Region;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.events.HelpEvent;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.PlatformUI;
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.ecommons.ui.SharedUIResources;

import org.eclipse.statet.base.ui.IStatetUIMenuIds;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.r.ui.help.IRUIHelpContextIds;
import org.eclipse.statet.ltk.ast.core.util.AstSelection;
import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement;
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.ISourceEditorAddon;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceFragmentEditorInput;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1;
import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1OutlinePage;
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.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.RModel;
import org.eclipse.statet.r.core.rsource.ast.FDef;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.core.source.IRDocumentConstants;
import org.eclipse.statet.r.core.source.RDocumentContentInfo;
import org.eclipse.statet.r.launching.RCodeLaunching;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.RUIHelp;
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.REditorOptions;
import org.eclipse.statet.r.ui.editors.RMarkOccurrencesLocator;
import org.eclipse.statet.r.ui.sourceediting.InsertAssignmentHandler;
import org.eclipse.statet.r.ui.sourceediting.RSourceViewerConfiguration;
import org.eclipse.statet.r.ui.sourceediting.RSourceViewerConfigurator;
import org.eclipse.statet.rj.renv.core.REnv;


public class REditor extends SourceEditor1 implements IRSourceEditor {
	
	
	private static final ImList<String> KEY_CONTEXTS= ImCollections.newIdentityList(
			"org.eclipse.statet.r.contexts.REditor" ); //$NON-NLS-1$
	
	private static final ImList<String> CONTEXT_IDS= ImCollections.concatList(
			ACTION_SET_CONTEXT_IDS, KEY_CONTEXTS );
	
	
	private static class MarkOccurrencesProvider extends AbstractMarkOccurrencesProvider {
		
		
		private final RMarkOccurrencesLocator locator= new RMarkOccurrencesLocator();
		
		
		public MarkOccurrencesProvider(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 {
			this.locator.run(run, info, astSelection, orgSelection);
		}
		
	}
	
	
	private RSourceViewerConfigurator rConfig;
	
	private IContextProvider helpContextProvider;
	
	
	public REditor() {
		super(RCore.R_CONTENT_TYPE);
	}
	
	
	@Override
	protected void initializeEditor() {
		super.initializeEditor();
		
		setHelpContextId(IRUIHelpContextIds.R_EDITOR);
		setEditorContextMenuId("org.eclipse.statet.r.menus.REditorContextMenu"); //$NON-NLS-1$
		setRulerContextMenuId("org.eclipse.statet.r.menus.REditorRulerMenu"); //$NON-NLS-1$
	}
	
	
	@Override
	protected SourceEditorViewerConfigurator createConfiguration() {
		setDocumentProvider(RUIPlugin.getInstance().getRDocumentProvider());
		
		enableStructuralFeatures(RModel.getRModelManager(),
				REditorOptions.FOLDING_ENABLED_PREF,
				REditorOptions.PREF_MARKOCCURRENCES_ENABLED );
		
		final IRCoreAccess initAccess= RCore.WORKBENCH_ACCESS;
		this.rConfig= new RSourceViewerConfigurator(initAccess,
				new RSourceViewerConfiguration(RDocumentContentInfo.INSTANCE, 0, this,
						null, null, null ));
		return this.rConfig;
	}
	
	@Override
	protected SourceEditorViewerConfigurator createInfoConfigurator() {
		return new RSourceViewerConfigurator(getRCoreAccess(),
				new RSourceViewerConfiguration(0, null, SharedUIResources.getColors()) );
	}
	
	@Override
	protected void setDocumentProvider(final IEditorInput input) {
		if (input instanceof ISourceFragmentEditorInput) {
			setDocumentProvider(RUIPlugin.getInstance().getRFragmentDocumentProvider());
			overwriteTitleImage(input.getImageDescriptor());
		}
		else {
			setDocumentProvider(RUIPlugin.getInstance().getRDocumentProvider());
			overwriteTitleImage(null);
		}
	}
	
	@Override
	protected Image getDefaultImage() {
		return RUIPlugin.getInstance().getImageRegistry().get(RUI.IMG_OBJ_R_SCRIPT);
	}
	
	@Override
	public void createPartControl(final Composite parent) {
		super.createPartControl(parent);
		
		// Editor Help:
		final SourceViewer viewer= (SourceViewer) getSourceViewer();
		this.helpContextProvider= RUIHelp.createEnrichedRHelpContextProvider(this, IRUIHelpContextIds.R_EDITOR);
		viewer.getTextWidget().addHelpListener(new HelpListener() {
			@Override
			public void helpRequested(final HelpEvent e) {
				PlatformUI.getWorkbench().getHelpSystem().displayHelp(REditor.this.helpContextProvider.getContext(null));
			}
		});
	}
	
	@Override
	protected ISourceEditorAddon createCodeFoldingProvider() {
		return new FoldingEditorAddon(new RDefaultFoldingProvider());
	}
	
	@Override
	protected ISourceEditorAddon createMarkOccurrencesProvider() {
		return new MarkOccurrencesProvider(this);
	}
	
	
	@Override
	public IRSourceUnit getSourceUnit() {
		return (IRSourceUnit) super.getSourceUnit();
	}
	
	@Override
	public IRCoreAccess getRCoreAccess() {
		return this.rConfig.getRCoreAccess();
	}
	
	@Override
	protected void setupConfiguration(final IEditorInput newInput) {
		super.setupConfiguration(newInput);
		
		final IRSourceUnit su= getSourceUnit();
		this.rConfig.setSource((su != null) ? su.getRCoreAccess() : RCore.WORKBENCH_ACCESS);
	}
	
	
	@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;
	}
	
	@Override
	protected Collection<String> getContextIds() {
		return CONTEXT_IDS;
	}
	
	@Override
	protected void collectContextMenuPreferencePages(final List<String> pageIds) {
		super.collectContextMenuPreferencePages(pageIds);
		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);
		}
		{	final Action action= new RDoubleCommentAction(this, getRCoreAccess());
			setAction(action.getId(), action);
			markAsStateDependentAction(action.getId(), true);
		}
		{	final IHandler2 handler= new RStripCommentsHandler(this);
			handlerService.activateHandler(LTKUI.STRIP_COMMENTS_COMMAND_ID, handler);
		}
	}
	
	@Override
	protected IHandler2 createCorrectIndentHandler() {
		final IHandler2 handler= new RCorrectIndentHandler(this);
		markAsStateDependentHandler(handler, true);
		return handler;
	}
	
	@Override
	protected void editorContextMenuAboutToShow(final IMenuManager m) {
		super.editorContextMenuAboutToShow(m);
		final IRSourceUnit su= getSourceUnit();
		
		m.insertBefore(ADDITIONS_GROUP_ID, new Separator("search")); //$NON-NLS-1$
		
		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)));
		if (su != null && !su.isReadOnly()) {
			m.appendToGroup(IStatetUIMenuIds.GROUP_SUBMIT_MENU_ID, new CommandContributionItem(new CommandContributionItemParameter(
					getSite(), null, RCodeLaunching.SUBMIT_SELECTION_PASTEOUTPUT_COMMAND_ID, CommandContributionItem.STYLE_PUSH)));
		}
	}
	
	@Override
	protected IRegion getRangeToReveal(final ISourceUnitModelInfo modelInfo, final ISourceStructElement element) {
		final FDef def= element.getAdapter(FDef.class);
		if (def != null) {
			final RAstNode cont= def.getContChild();
			final int offset= element.getSourceRange().getStartOffset();
			int length= cont.getStartOffset() - offset;
			if (cont.getLength() > 0) {
				length++;
			}
			return new Region(offset, length);
		}
		return null;
	}
	
	
	@Override
	protected SourceEditor1OutlinePage createOutlinePage() {
		return new ROutlinePage(this);
	}
	
	@Override
	protected ITemplatesPage createTemplatesPage() {
		return new REditorTemplatesPage(this, getSourceViewer());
	}
	
	@Override
	public String[] getShowInTargetIds() {
		return new String[] { IPageLayout.ID_PROJECT_EXPLORER, IPageLayout.ID_OUTLINE, RUI.R_HELP_VIEW_ID };
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(final Class<T> adapterType) {
		if (adapterType == REnv.class) {
			return (T) getRCoreAccess().getREnv();
		}
		if (adapterType == IContextProvider.class) {
			return (T) this.helpContextProvider;
		}
		return super.getAdapter(adapterType);
	}
	
}
