/*=============================================================================#
 # Copyright (c) 2000, 2020 IBM Corporation 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.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     IBM Corporation - org.eclipse.jdt: initial API and implementation
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.dialogs.QuickTreeInformationControl;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
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.ISourceElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.sourceediting.actions.OpenDeclaration;


/**
 * Show outline in light-weight control.
 */
public abstract class QuickOutlineInformationControl extends QuickTreeInformationControl {
	
	
	protected static final String INHERITED_COLOR_NAME= "org.eclipse.jdt.ui.ColoredLabels.inherited"; //$NON-NLS-1$
	
	
	protected class OutlineContent implements OutlineContentProvider.IOutlineContent {
		
		
		public OutlineContent() {
		}
		
		
		@Override
		public ISourceUnitModelInfo getModelInfo(final Object input) {
			return QuickOutlineInformationControl.this.getModelInfo(input);
		}
		@Override
		public Filter getContentFilter() {
			return QuickOutlineInformationControl.this.getContentFilter();
		}
		
	}
	
	
	private final OpenDeclaration opener;
	
	private OutlineContentProvider contentProvider;
	
	private boolean requireFullName;
	
	
	/**
	 * Creates a new outline information control.
	 *
	 * @param parent the parent shell
	 * @param shellStyle the additional styles for the shell
	 * @param commandId the id of the command that invoked this control or <code>null</code>
	 */
	public QuickOutlineInformationControl(final Shell parent,
			final String commandId, final int pageCount,
			final OpenDeclaration opener) {
		super(parent, SWT.RESIZE, true, commandId, pageCount);
		
		this.opener= opener;
	}
	
	
	public abstract String getModelTypeId();
	
	@Override
	protected IDialogSettings getDialogSettings() {
		return DialogUtils.getSection(LTKUIPlugin.getInstance().getDialogSettings(), "EditorStructurePopup"); //$NON-NLS-1$
	}
	
	@Override
	protected String getDescription(final int page) {
		if (getCommandId() == LTKUI.SHOW_QUICK_SOURCE_OUTLINE_COMMAND_ID) {
			return "Document Outline";
		}
		if (getCommandId() == LTKUI.SHOW_QUICK_ELEMENT_OUTLINE_COMMAND_ID) {
			return "Object Outline";
		}
		return ""; //$NON-NLS-1$
	}
	
	
	@Override
	protected void setMatcherString(final String pattern, final boolean update) {
		this.requireFullName= (pattern.indexOf('*') >= 0);
		super.setMatcherString(pattern, update);
	}
	
	@Override
	protected String getElementName(final IAdaptable element) {
		if (element instanceof IModelElement && !this.requireFullName) {
			return ((IModelElement) element).getElementName().getSegmentName();
		}
		return super.getElementName(element);
	}
	
	
	@Override
	protected void configureViewer(final TreeViewer viewer) {
		this.contentProvider= createContentProvider();
		viewer.setContentProvider(this.contentProvider);
	}
	
	protected OutlineContentProvider createContentProvider() {
		return new OutlineContentProvider(new OutlineContent());
	}
	
	protected ISourceUnitModelInfo getModelInfo(final Object input) {
		if (input instanceof ISourceUnit) {
			return ((ISourceUnit) input).getModelInfo(getModelTypeId(), 0, null);
		}
		return null;
	}
	
	protected IModelElement.Filter getContentFilter() {
		return null;
	}
	
	
	protected int getInitialIterationPage(final ISourceElement element) {
		return 0;
	}
	
	@Override
	public void setInput(final Object information) {
		if (information instanceof ISourceElement) {
			final ISourceElement element= (ISourceElement) information;
			final ISourceUnit su= element.getSourceUnit();
			if (su != null) {
				inputChanged(getInitialIterationPage(element), su, element);
				return;
			}
		}
		
		inputChanged(0, null, null);
	}
	
	@Override
	protected void openElement(final Object element) throws CoreException {
		if (element instanceof ISourceElement) {
			this.opener.open((ISourceElement) element, true);
		}
	}
	
}
