/*******************************************************************************
 * Copyright (c) 2002, 2016 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) and others.
 *
 * This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug fixes
 *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49380, bug 34548, bug 53547
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor.outline;

import java.util.List;

import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
import org.eclipse.ant.internal.ui.editor.AntEditor;
import org.eclipse.ant.internal.ui.editor.actions.TogglePresentationAction;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntImportNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntModelContentProvider;
import org.eclipse.ant.internal.ui.model.AntModelCore;
import org.eclipse.ant.internal.ui.model.AntModelLabelProvider;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntPropertyNode;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.AntTaskNode;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.ant.internal.ui.model.IAntModelListener;
import org.eclipse.ant.internal.ui.views.actions.AntOpenWithMenu;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;

/**
 * Content outline page for the Ant Editor.
 */
public class AntEditorContentOutlinePage extends ContentOutlinePage implements IShowInSource, IAdaptable {

	private static final int EXPAND_TO_LEVEL = 2;

	private Menu fMenu;
	private AntOpenWithMenu fOpenWithMenu;

	private IAntModelListener fListener;
	private IAntModel fModel;
	private AntModelCore fCore;
	private ListenerList<ISelectionChangedListener> fPostSelectionChangedListeners = new ListenerList<>();
	private boolean fIsModelEmpty = true;
	private boolean fFilterInternalTargets;
	private boolean fFilterImportedElements;
	private boolean fFilterProperties;
	private boolean fFilterTopLevel;
	private boolean fSort;

	private ViewerComparator fComparator;

	private AntEditor fEditor;

	private TogglePresentationAction fTogglePresentation;

	/**
	 * A viewer filter for the Ant Content Outline
	 */
	private class AntOutlineFilter extends ViewerFilter {

		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof AntElementNode) {
				AntElementNode node = (AntElementNode) element;
				if (fFilterTopLevel && (node instanceof AntTaskNode && parentElement instanceof AntProjectNode)) {
					return false;
				}
				if (fFilterImportedElements && (node.getImportNode() != null || node.isExternal())) {
					if (node instanceof AntTargetNode && ((AntTargetNode) node).isDefaultTarget()) {
						return true;
					}
					return false;
				}
				if (fFilterInternalTargets && node instanceof AntTargetNode) {
					return !((AntTargetNode) node).isInternal();
				}
				if (fFilterProperties && node instanceof AntPropertyNode) {
					return false;
				}
				if (!node.isStructuralNode()) {
					return false;
				}
			}
			return true;
		}
	}

	private class AntOutlineComparator extends ViewerComparator {
		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			if (!(e1 instanceof AntElementNode && e2 instanceof AntElementNode)) {
				return super.compare(viewer, e1, e2);
			}
			String name1 = ((AntElementNode) e1).getLabel();
			String name2 = ((AntElementNode) e2).getLabel();
			return getComparator().compare(name1, name2);
		}
	}

	/**
	 * Sets whether internal targets should be filtered out of the outline.
	 * 
	 * @param filter
	 *            whether or not internal targets should be filtered out
	 */
	protected void setFilterInternalTargets(boolean filter) {
		fFilterInternalTargets = filter;
		setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_INTERNAL_TARGETS);
	}

	/**
	 * Sets whether imported elements should be filtered out of the outline.
	 * 
	 * @param filter
	 *            whether or not imported elements should be filtered out
	 */
	protected void setFilterImportedElements(boolean filter) {
		fFilterImportedElements = filter;
		setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_IMPORTED_ELEMENTS);
	}

	private void setFilter(boolean filter, String name) {
		if (name != null) {
			AntUIPlugin.getDefault().getPreferenceStore().setValue(name, filter);
		}
		// filter has been changed
		getTreeViewer().refresh();
	}

	/**
	 * Sets whether properties should be filtered out of the outline.
	 * 
	 * @param filter
	 *            whether or not properties should be filtered out
	 */
	protected void setFilterProperties(boolean filter) {
		fFilterProperties = filter;
		setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_PROPERTIES);
	}

	/**
	 * Sets whether internal targets should be filtered out of the outline.
	 * 
	 * @param filter
	 *            whether or not internal targets should be filtered out
	 */
	protected void setFilterTopLevel(boolean filter) {
		fFilterTopLevel = filter;
		setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_TOP_LEVEL);
	}

	/**
	 * Returns whether internal targets are currently being filtered out of the outline.
	 * 
	 * @return whether or not internal targets are being filtered out
	 */
	protected boolean filterInternalTargets() {
		return fFilterInternalTargets;
	}

	/**
	 * Returns whether imported elements are currently being filtered out of the outline.
	 * 
	 * @return whether or not imported elements are being filtered out
	 */
	protected boolean filterImportedElements() {
		return fFilterImportedElements;
	}

	/**
	 * Returns whether properties are currently being filtered out of the outline.
	 * 
	 * @return whether or not properties are being filtered out
	 */
	protected boolean filterProperties() {
		return fFilterProperties;
	}

	/**
	 * Returns whether top level tasks/types are currently being filtered out of the outline.
	 * 
	 * @return whether or not top level tasks/types are being filtered out
	 */
	protected boolean filterTopLevel() {
		return fFilterTopLevel;
	}

	/**
	 * Sets whether elements should be sorted in the outline.
	 * 
	 * @param sort
	 *            whether or not elements should be sorted
	 */
	protected void setSort(boolean sort) {
		fSort = sort;
		if (sort) {
			if (fComparator == null) {
				fComparator = new AntOutlineComparator();
			}
			getTreeViewer().setComparator(fComparator);
		} else {
			getTreeViewer().setComparator(null);
		}
		AntUIPlugin.getDefault().getPreferenceStore().setValue(IAntUIPreferenceConstants.ANTEDITOR_SORT, sort);
	}

	/**
	 * Returns whether elements are currently being sorted.
	 * 
	 * @return whether elements are currently being sorted
	 */
	protected boolean isSort() {
		return fSort;
	}

	/**
	 * Creates a new AntEditorContentOutlinePage.
	 */
	public AntEditorContentOutlinePage(AntModelCore core, AntEditor editor) {
		super();
		fCore = core;
		fFilterInternalTargets = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_INTERNAL_TARGETS);
		fFilterImportedElements = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_IMPORTED_ELEMENTS);
		fFilterProperties = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_PROPERTIES);
		fFilterTopLevel = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_TOP_LEVEL);
		fSort = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_SORT);
		fEditor = editor;

		fTogglePresentation = new TogglePresentationAction();
		fTogglePresentation.setEditor(editor);
	}

	@Override
	public void dispose() {
		if (fMenu != null) {
			fMenu.dispose();
		}
		if (fOpenWithMenu != null) {
			fOpenWithMenu.dispose();
		}
		if (fListener != null) {
			fCore.removeAntModelListener(fListener);
			fListener = null;
		}
		fTogglePresentation.setEditor(null);

		super.dispose();
	}

	/**
	 * Creates the control (outline view) for this page
	 */
	@Override
	public void createControl(Composite parent) {
		super.createControl(parent);

		TreeViewer viewer = getTreeViewer();

		viewer.setContentProvider(new AntModelContentProvider());
		setSort(fSort);

		viewer.setLabelProvider(new AntModelLabelProvider());
		viewer.addFilter(new AntOutlineFilter());
		if (fModel != null) {
			setViewerInput(fModel);
		}

		MenuManager manager = new MenuManager("#PopUp"); //$NON-NLS-1$
		manager.setRemoveAllWhenShown(true);
		manager.addMenuListener(this::contextMenuAboutToShow);
		fMenu = manager.createContextMenu(viewer.getTree());
		viewer.getTree().setMenu(fMenu);

		IPageSite site = getSite();
		site.registerContextMenu(IAntUIConstants.PLUGIN_ID + ".antEditorOutline", manager, viewer); //$NON-NLS-1$

		IToolBarManager tbm = site.getActionBars().getToolBarManager();
		tbm.add(new ToggleSortAntOutlineAction(this));
		tbm.add(new FilterInternalTargetsAction(this));
		tbm.add(new FilterPropertiesAction(this));
		tbm.add(new FilterImportedElementsAction(this));
		tbm.add(new FilterTopLevelAction(this));

		IMenuManager viewMenu = site.getActionBars().getMenuManager();
		viewMenu.add(new ToggleLinkWithEditorAction(fEditor));

		fOpenWithMenu = new AntOpenWithMenu(this.getSite().getPage());

		viewer.addPostSelectionChangedListener(event -> firePostSelectionChanged(event.getSelection()));

		site.getActionBars().setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
	}

	private void setViewerInput(Object newInput) {
		TreeViewer tree = getTreeViewer();
		Object oldInput = tree.getInput();

		boolean isAntModel = (newInput instanceof AntModel);
		boolean wasAntModel = (oldInput instanceof AntModel);

		if (isAntModel && !wasAntModel) {
			if (fListener == null) {
				fListener = createAntModelChangeListener();
			}
			fCore.addAntModelListener(fListener);
		} else if (!isAntModel && wasAntModel && fListener != null) {
			fCore.removeAntModelListener(fListener);
			fListener = null;
		}

		tree.setInput(newInput);

		if (isAntModel) {
			updateTreeExpansion();
		}
	}

	public void setPageInput(AntModel xmlModel) {
		fModel = xmlModel;
		if (getTreeViewer() != null) {
			setViewerInput(fModel);
		}
	}

	private IAntModelListener createAntModelChangeListener() {
		return event -> {
			if (event.getModel() == fModel && !getControl().isDisposed()) {
				getControl().getDisplay().asyncExec(() -> {
					Control ctrl = getControl();
					if (ctrl != null && !ctrl.isDisposed()) {
						getTreeViewer().refresh();
						updateTreeExpansion();
					}
				});
			}
		};
	}

	public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
		fPostSelectionChangedListeners.add(listener);
	}

	public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
		fPostSelectionChangedListeners.remove(listener);
	}

	private void updateTreeExpansion() {
		boolean wasModelEmpty = fIsModelEmpty;
		fIsModelEmpty = fModel == null || fModel.getProjectNode() == null;
		if (wasModelEmpty && !fIsModelEmpty) {
			getTreeViewer().expandToLevel(EXPAND_TO_LEVEL);
		}
	}

	private void firePostSelectionChanged(ISelection selection) {
		// create an event
		SelectionChangedEvent event = new SelectionChangedEvent(this, selection);

		// fire the event
		for (ISelectionChangedListener iSelectionChangedListener : fPostSelectionChangedListeners) {
			iSelectionChangedListener.selectionChanged(event);
		}
	}

	private void contextMenuAboutToShow(IMenuManager menuManager) {
		if (shouldAddOpenWithMenu()) {
			addOpenWithMenu(menuManager);
		}
		menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	private void addOpenWithMenu(IMenuManager menuManager) {
		AntElementNode element = getSelectedNode();
		IFile file = null;
		if (element != null) {
			file = element.getIFile();
		}
		if (file != null) {
			menuManager.add(new Separator("group.open")); //$NON-NLS-1$
			IMenuManager submenu = new MenuManager(AntOutlineMessages.AntEditorContentOutlinePage_Open_With_1);
			fOpenWithMenu.setNode(element);
			submenu.add(fOpenWithMenu);
			menuManager.appendToGroup("group.open", submenu); //$NON-NLS-1$
		}
	}

	private boolean shouldAddOpenWithMenu() {
		AntElementNode node = getSelectedNode();
		if (node instanceof AntImportNode) {
			return true;
		}
		if (node != null && node.isExternal()) {
			String path = node.getFilePath();
			if (path != null && path.length() > 0) {
				return true;
			}
		}
		return false;
	}

	private AntElementNode getSelectedNode() {
		ISelection iselection = getSelection();
		if (iselection instanceof IStructuredSelection) {
			IStructuredSelection selection = (IStructuredSelection) iselection;
			if (selection.size() == 1) {
				Object selected = selection.getFirstElement();
				if (selected instanceof AntElementNode) {
					return (AntElementNode) selected;
				}
			}
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> key) {
		if (key == IShowInSource.class) {
			return (T) this;
		}
		return null;
	}

	@Override
	public ShowInContext getShowInContext() {
		IFile file = null;
		if (fModel != null) {
			AntElementNode node = getSelectedNode();
			if (node != null) {
				file = node.getIFile();
			}
		}
		if (file != null) {
			ISelection selection = new StructuredSelection(file);
			return new ShowInContext(null, selection);
		}
		return null;
	}

	public void select(AntElementNode node) {
		if (getTreeViewer() != null) {
			ISelection s = getTreeViewer().getSelection();
			if (s instanceof IStructuredSelection) {
				IStructuredSelection ss = (IStructuredSelection) s;
				List<?> nodes = ss.toList();
				if (!nodes.contains(node)) {
					s = (node == null ? StructuredSelection.EMPTY : new StructuredSelection(node));
					getTreeViewer().setSelection(s, true);
				}
			}
		}
	}
}
