/*******************************************************************************
 * 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(menuManager -> contextMenuAboutToShow(menuManager));
		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);
				}
			}
		}
	}
}
