/*=============================================================================#
 # 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 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.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.AbstractEditorOutlinePage;

import org.eclipse.statet.internal.ltk.ui.EditingMessages;
import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.ltk.core.ISourceModelStamp;
import org.eclipse.statet.ltk.model.core.IModelElementDelta;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.IModelElement.Filter;
import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.IModelElementInputListener;
import org.eclipse.statet.ltk.ui.ISelectionWithElementInfoListener;
import org.eclipse.statet.ltk.ui.LTKInputData;


/**
 * Abstract content outline page for a {@link SourceEditor1} with model info.
 */
public abstract class SourceEditor1OutlinePage extends AbstractEditorOutlinePage
		implements IContentOutlinePage, IAdaptable, ISourceEditorAssociated,
			IShowInSource, IShowInTargetList, IShowInTarget,
			IPostSelectionProvider, IModelElementInputListener {
	
	
	protected class OutlineContent implements OutlineContentProvider.IOutlineContent {
		
		
		public OutlineContent() {
		}
		
		
		@Override
		public ISourceUnitModelInfo getModelInfo(final Object input) {
			return SourceEditor1OutlinePage.this.getModelInfo(input);
		}
		@Override
		public Filter getContentFilter() {
			return SourceEditor1OutlinePage.this.getContentFilter();
		}
		
	}
	
	public class AstContentProvider extends OutlineContentProvider {
		
		
		public AstContentProvider() {
			super(new OutlineContent());
		}
		
		
		@Override
		public ISourceModelStamp getStamp(final Object inputElement) {
			if (inputElement instanceof ISourceUnit) {
				final AstInfo ast= ((ISourceUnit) 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 ISourceUnit) {
				final AstInfo ast= ((ISourceUnit) 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 ISourceModelStamp currentModelStamp;
	
	private IModelElement inputUnit;
	
	private SyncWithEditorAction syncWithEditorAction;
	
	
	public SourceEditor1OutlinePage(final SourceEditor1 editor, final String mainType, final String contextMenuId) {
		super(contextMenuId);
		if (editor == null) {
			throw new NullPointerException();
		}
		if (mainType == null) {
			throw new NullPointerException();
		}
		this.editor= editor;
		this.mainType= mainType;
	}
	
	
	@Override
	public void init(final IPageSite pageSite) {
		super.init(pageSite);
		pageSite.setSelectionProvider(this);
	}
	
	protected boolean isUpToDate(final ISourceModelStamp stamp) {
		final ISourceModelStamp current= this.currentModelStamp;
		return (current != null && current.equals(stamp));
	}
	
	protected IModelElement.Filter getContentFilter() {
		return null;
	}
	
	@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 OutlineContent());
	}
	
	@Override
	protected void configureViewer(final TreeViewer viewer) {
		this.contentProvider= createContentProvider();
		viewer.setContentProvider(this.contentProvider);
	}
	
	
	@Override
	protected void initActions(final IServiceLocator serviceLocator, final HandlerCollection 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 IModelElement element) {
		this.inputUnit= element;
		this.currentModelStamp= null;
		final TreeViewer viewer= getViewer();
		if (UIAccess.isOkToUse(viewer)) {
			viewer.setInput(this.inputUnit);
		}
	}
	
	@Override
	public void elementInitialInfo(final IModelElement element) {
		elementUpdatedInfo(element, null);
	}
	
	@Override
	public void elementUpdatedInfo(final IModelElement element, final IModelElementDelta 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 
						|| !UIAccess.isOkToUse(viewer)
						|| isUpToDate(SourceEditor1OutlinePage.this.contentProvider.getStamp(element)) ) {
					return;
				}
				beginIgnoreSelection();
				try {
					viewer.refresh(true);
				}
				finally {
					endIgnoreSelection(false);
				}
			}
		});
	}
	
	protected ISourceUnitModelInfo getModelInfo(final Object input) {
		if (input instanceof ISourceUnit) {
			return ((ISourceUnit) 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(ISourceStructElement element) {
		final TreeViewer viewer= getViewer();
		if (UIAccess.isOkToUse(viewer)) {
			beginIgnoreSelection();
			try {
				final Filter filter= getContentFilter();
				Object selectedElement= null;
				final IStructuredSelection currentSelection= ((IStructuredSelection) viewer.getSelection());
				if (currentSelection.size() == 1) {
					selectedElement= currentSelection.getFirstElement();
				}
				while (element != null 
						&& (element.getElementType() & IModelElement.MASK_C2) != IModelElement.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 IModelElement parent= element.getSourceParent();
					if (parent instanceof ISourceStructElement) {
						element= (ISourceStructElement) 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 IModelElement 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> T getAdapter(final Class<T> adapterType) {
		if (adapterType == ISourceEditorAssociated.class) {
			return (T) this;
		}
		if (adapterType == IEncodingSupport.class) {
			return this.editor.getAdapter((Class<T>) IEncodingSupport.class);
		}
		if (adapterType == IContentType.class) {
			return (T) this.editor.getContentType();
		}
		return null;
	}
	
}
