/*=============================================================================#
 # Copyright (c) 2007, 2021 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 static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

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

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.editors.text.IEncodingSupport;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.commands.core.HandlerCollection;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.BasicEditorOutlinePage;
import org.eclipse.statet.ecommons.ui.workbench.ContextHandlers;

import org.eclipse.statet.internal.ltk.ui.EditingMessages;
import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.core.SourceModelStamp;
import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
import org.eclipse.statet.ltk.model.core.element.LtkModelElementDelta;
import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.LTKInputData;
import org.eclipse.statet.ltk.ui.ModelElementInputListener;
import org.eclipse.statet.ltk.ui.SelectionWithElementInfoListener;


/**
 * Abstract content outline page for a {@link SourceEditor1} with model info.
 */
@NonNullByDefault
public abstract class SourceEditor1OutlinePage extends BasicEditorOutlinePage
		implements IContentOutlinePage, IAdaptable, SourceEditorAssociated,
				IShowInSource, IShowInTargetList, IShowInTarget,
				IPostSelectionProvider, ModelElementInputListener<LtkModelElement<?>> {
	
	
	protected class PageOutlineContent implements OutlineContentProvider.OutlineContent {
		
		
		public PageOutlineContent() {
		}
		
		
		@Override
		public @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
			return SourceEditor1OutlinePage.this.getModelInfo(input);
		}
		
		@Override
		public @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter() {
			return SourceEditor1OutlinePage.this.getContentFilter();
		}
		
	}
	
	public class AstContentProvider extends OutlineContentProvider {
		
		
		public AstContentProvider() {
			super(new PageOutlineContent());
		}
		
		
		@Override
		public @Nullable SourceModelStamp getStamp(final Object inputElement) {
			if (inputElement instanceof SourceUnit) {
				final AstInfo ast= ((SourceUnit)inputElement).getAstInfo(
						SourceEditor1OutlinePage.this.mainType, false, null );
				if (ast != null) {
					return ast.getStamp();
				}
			}
			return null;
		}
		
		@Override
		public @NonNull Object[] getElements(final Object inputElement) {
			if (inputElement instanceof SourceUnit) {
				final AstInfo ast= ((SourceUnit)inputElement).getAstInfo(
						SourceEditor1OutlinePage.this.mainType, false, null );
				if (ast != null) {
					SourceEditor1OutlinePage.this.currentModelStamp= ast.getStamp();
					return new @NonNull Object[] { ast.getRoot() };
				}
			}
			return new @NonNull Object[0];
		}
		
	}
	
	
	/**
	 * @deprecated use {@link AbstractToggleHandler}
	 */
	@Deprecated
	protected abstract class ToggleAction extends Action {
		
		private final String settingsKey;
		private final int time;
		
		public ToggleAction(final String checkSettingsKey, final boolean checkSettingsDefault, 
				final int expensive) {
			assert (checkSettingsKey != null);
			
			this.settingsKey= checkSettingsKey;
			this.time= expensive;
			
			final IDialogSettings settings= getDialogSettings();
			final boolean on= (settings.get(this.settingsKey) == null) ?
					checkSettingsDefault : getDialogSettings().getBoolean(this.settingsKey);
			setChecked(on);
			configure(on);
		}
		
		protected void init() {
		}
		
		@Override
		public void run() {
			final Runnable runnable= new Runnable() {
				@Override
				public void run() {
					final boolean on= isChecked();
					configure(on);
					getDialogSettings().put(ToggleAction.this.settingsKey, on); 
				}
			};
			if (this.time == 0) {
				runnable.run();
			}
			else {
				BusyIndicator.showWhile(Display.getCurrent(), runnable);
			}
		}
		
		protected abstract void configure(boolean on);
		
	}
	
	private class SyncWithEditorAction extends ToggleAction implements SelectionWithElementInfoListener {
		
		public SyncWithEditorAction() {
			super("sync.editor", true, 0); //$NON-NLS-1$
			setText(EditingMessages.SyncWithEditor_label);
			setImageDescriptor(SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_SYNCHRONIZED_IMAGE_ID));
		}
		
		@Override
		protected void configure(final boolean on) {
			if (on) {
				SourceEditor1OutlinePage.this.editor.addPostSelectionWithElementInfoListener(this);
			}
			else {
				SourceEditor1OutlinePage.this.editor.removePostSelectionWithElementInfoListener(this);
			}
		}
		
		@Override
		public void inputChanged() {
		}
		
		@Override
		public void stateChanged(final LTKInputData state) {
			if (!state.isStillValid()) {
				return;
			}
			final SourceUnitModelInfo inputInfo= state.getInputInfo();
			if (inputInfo == null || !isUpToDate(inputInfo.getStamp())) {
				elementUpdatedInfo(state.getInputElement(), null);
			}
			UIAccess.getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					if (state.isStillValid() && isChecked()) {
						select(state.getModelSelection());
					}
				}
			});
		}
		
	}
	
	
	private final SourceEditor1 editor;
	private final String mainType;
	private OutlineContentProvider contentProvider;
	
	private @Nullable SourceModelStamp currentModelStamp;
	
	private @Nullable LtkModelElement<?> inputUnit;
	
	private SyncWithEditorAction syncWithEditorAction;
	
	
	public SourceEditor1OutlinePage(final SourceEditor1 editor, final String mainType, final String contextMenuId) {
		super(contextMenuId);
		this.editor= nonNullAssert(editor);
		this.mainType= nonNullAssert(mainType);
	}
	
	
	public SourceEditor1 getEditor() {
		return this.editor;
	}
	
	
	@Override
	public void init(final IPageSite pageSite) {
		super.init(pageSite);
		pageSite.setSelectionProvider(this);
	}
	
	protected boolean isUpToDate(final SourceModelStamp stamp) {
		final SourceModelStamp current= this.currentModelStamp;
		return (current != null && current.equals(stamp));
	}
	
	protected @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter() {
		return null;
	}
	
	
	@Override
	protected @Nullable TreeViewer getViewer() {
		return (TreeViewer)super.getViewer();
	}
	
	@Override
	public void createControl(final Composite parent) {
		super.createControl(parent);
		
		this.editor.getModelInputProvider().addListener(this);
		getViewer().setInput(this.inputUnit);
	}
	
	protected OutlineContentProvider createContentProvider() {
		return new OutlineContentProvider(new PageOutlineContent());
	}
	
	@Override
	protected void configureViewer(final TreeViewer viewer) {
		this.contentProvider= createContentProvider();
		viewer.setContentProvider(this.contentProvider);
	}
	
	
	@Override
	protected void initActions(final IServiceLocator serviceLocator,
			final ContextHandlers handlers) {
		super.initActions(serviceLocator, handlers);
		
		this.syncWithEditorAction= new SyncWithEditorAction();
	}
	
	@Override
	protected void contributeToActionBars(final IServiceLocator serviceLocator,
			final IActionBars actionBars, final HandlerCollection handlers) {
		super.contributeToActionBars(serviceLocator, actionBars, handlers);
		
		actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, this.editor.getAction(ITextEditorActionConstants.UNDO));
		actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, this.editor.getAction(ITextEditorActionConstants.REDO));
		
//		actionBars.setGlobalActionHandler(ITextEditorActionConstants.NEXT, this.editor.getAction(ITextEditorActionConstants.NEXT));
		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION, this.editor.getAction(ITextEditorActionConstants.NEXT));
//		actionBars.setGlobalActionHandler(ITextEditorActionConstants.PREVIOUS, this.editor.getAction(ITextEditorActionConstants.PREVIOUS));
		actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION, this.editor.getAction(ITextEditorActionConstants.PREVIOUS));
		
		final IMenuManager menuManager= actionBars.getMenuManager();
		
		menuManager.add(this.syncWithEditorAction);
		
		final IContextService contextService= nonNullAssert(serviceLocator.getService(IContextService.class));
		contextService.activateContext("org.eclipse.statet.ltk.contexts.EditSource1MenuSet"); //$NON-NLS-1$
	}
	
	@Override
	protected void contextMenuAboutToShow(final IMenuManager m) {
		final Separator additions= new Separator(ADDITIONS_GROUP_ID);
		m.add(additions);
	}
	
	
	@Override
	public void elementChanged(final @Nullable LtkModelElement<?> element) {
		this.inputUnit= element;
		this.currentModelStamp= null;
		final TreeViewer viewer= getViewer();
		if (viewer != null && UIAccess.isOkToUse(viewer.getControl())) {
			viewer.setInput(this.inputUnit);
		}
	}
	
	@Override
	public void elementInitialInfo(final @Nullable LtkModelElement<?> element) {
		elementUpdatedInfo(element, null);
	}
	
	@Override
	public void elementUpdatedInfo(final @Nullable LtkModelElement<?> element, final @Nullable LtkModelElementDelta delta) {
		if (element != this.inputUnit || (element == null && this.inputUnit == null)) {
			return;
		}
		final Display display= UIAccess.getDisplay();
		display.syncExec(new Runnable() {
			@Override
			public void run() {
				final TreeViewer viewer= getViewer();
				
				if (element != SourceEditor1OutlinePage.this.inputUnit 
						|| viewer == null || !UIAccess.isOkToUse(viewer.getControl())
						|| isUpToDate(SourceEditor1OutlinePage.this.contentProvider.getStamp(element)) ) {
					return;
				}
				beginIgnoreSelection();
				try {
					viewer.refresh(true);
				}
				finally {
					endIgnoreSelection(false);
				}
			}
		});
	}
	
	protected @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
		if (input instanceof SourceUnit) {
			return ((SourceUnit)input).getModelInfo(this.mainType, 0, null);
		}
		return null;
	}
	
	
	@Override
	public void dispose() {
		this.editor.getModelInputProvider().removeListener(this);
		this.editor.handleOutlinePageClosed();
		
		super.dispose();
	}
	
	
	@Override
	protected void selectInEditor(final ISelection selection) {
		this.editor.setSelection(selection, this.syncWithEditorAction);
	}
	
	protected void select(@Nullable SourceStructElement<?, ?> element) {
		final TreeViewer viewer= getViewer();
		if (viewer != null && UIAccess.isOkToUse(viewer.getControl())) {
			beginIgnoreSelection();
			try {
				final LtkModelElementFilter<? super SourceStructElement<?, ?>> filter= getContentFilter();
				Object selectedElement= null;
				final IStructuredSelection currentSelection= ((IStructuredSelection)viewer.getSelection());
				if (currentSelection.size() == 1) {
					selectedElement= currentSelection.getFirstElement();
				}
				while (element != null 
						&& (element.getElementType() & LtkModelElement.MASK_C2) != LtkModelElement.C2_SOURCE_FILE) {
					if (selectedElement != null && element.equals(selectedElement)) {
						return;
					}
					if (filter == null || filter.include(element)) {
						selectedElement= null;
						viewer.setSelection(new StructuredSelection(element), true);
						if (!viewer.getSelection().isEmpty()) {
							return;
						}
					}
					final LtkModelElement<?> parent= element.getSourceParent();
					if (parent instanceof SourceStructElement) {
						element= (SourceStructElement<?, ?>)parent;
						continue;
					}
					else {
						break;
					}
				}
				if (!viewer.getSelection().isEmpty()) {
					viewer.setSelection(StructuredSelection.EMPTY);
				}
			}
			finally {
				endIgnoreSelection(true);
			}
		}
	}
	
	
	@Override
	public ShowInContext getShowInContext() {
		return new ShowInContext(this.editor.getEditorInput(), null);
	}
	
	@Override
	public @NonNull String[] getShowInTargetIds() {
		return new @NonNull String[] { IPageLayout.ID_PROJECT_EXPLORER };
	}
	
	@Override
	public boolean show(final ShowInContext context) {
		final LtkModelElement<?> inputUnit= this.inputUnit;
		final ISelection selection= context.getSelection();
		if (inputUnit != null && selection instanceof LTKInputData) {
			final LTKInputData data= (LTKInputData) selection;
			data.update();
			if (inputUnit.equals(data.getInputElement())) {
				select(data.getModelSelection());
				return true;
			}
		}
		return false;
	}
	
	
	@Override
	public SourceEditor getSourceEditor() {
		return this.editor;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> @Nullable T getAdapter(final Class<T> adapterType) {
		if (adapterType == SourceEditorAssociated.class) {
			return (T)this;
		}
		if (adapterType == IEncodingSupport.class) {
			return (T)this.editor.getAdapter(IEncodingSupport.class);
		}
		if (adapterType == IContentType.class) {
			return (T)this.editor.getContentType();
		}
		return null;
	}
	
}
