/*=============================================================================#
 # 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.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
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.ISelectionWithElementInfoListener;
import org.eclipse.statet.ltk.ui.LTKInputData;
import org.eclipse.statet.ltk.ui.ModelElementInputListener;


/**
 * Abstract content outline page for a {@link SourceEditor1} with model info.
 */
@NonNullByDefault
public abstract class SourceEditor1OutlinePage extends BasicEditorOutlinePage
		implements IContentOutlinePage, IAdaptable, ISourceEditorAssociated,
				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 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 Object[] { ast.getRoot() };
				}
			}
			return new 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 ISelectionWithElementInfoListener {
		
		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;
			}
			if (!isUpToDate(state.getInputInfo().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 service= serviceLocator.getService(IContextService.class);
		service.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 String[] getShowInTargetIds() {
		return new String[] { IPageLayout.ID_PROJECT_EXPLORER };
	}
	
	@Override
	public boolean show(final ShowInContext context) {
		final LtkModelElement<?> inputUnit= this.inputUnit;
		final ISelection selection= context.getSelection();
		if (selection instanceof LTKInputData) {
			final LTKInputData data= (LTKInputData) selection;
			data.update();
			if (inputUnit.equals(data.getInputElement())) {
				select(data.getModelSelection());
				return true;
			}
		}
		return false;
	}
	
	
	@Override
	public ISourceEditor getSourceEditor() {
		return this.editor;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public <T> @Nullable T getAdapter(final Class<T> adapterType) {
		if (adapterType == ISourceEditorAssociated.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;
	}
	
}
