/*******************************************************************************
 * Copyright (c) 2002, 2016 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * 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.AntModelChangeEvent;
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.IMenuListener;
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 {
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
		 */
		@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);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.IPage#dispose()
	 */
	@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(new IMenuListener() {
			@Override
			public void menuAboutToShow(IMenuManager 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(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent 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 new IAntModelListener() {
			@Override
			public void antModelChanged(final AntModelChangeEvent 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;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> key) {
		if (key == IShowInSource.class) {
			return (T) this;
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.IShowInSource#getShowInContext()
	 */
	@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);
				}
			}
		}
	}
}
