/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.ui.text;

import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IParent;
import org.eclipse.dltk.internal.ui.actions.OpenActionUtil;
import org.eclipse.dltk.internal.ui.util.StringMatcher;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.actions.CustomFiltersActionGroup;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlExtension;
import org.eclipse.jface.text.IInformationControlExtension2;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ActionHandler;
import org.eclipse.ui.commands.HandlerSubmission;
import org.eclipse.ui.commands.ICommand;
import org.eclipse.ui.commands.ICommandManager;
import org.eclipse.ui.commands.IKeySequenceBinding;
import org.eclipse.ui.commands.Priority;
import org.eclipse.ui.contexts.IWorkbenchContextSupport;
import org.eclipse.ui.keys.KeySequence;

/**
 * Abstract class for Show hierarchy in light-weight controls.
 *
 *
 */
public abstract class AbstractInformationControl extends PopupDialog
		implements IInformationControl, IInformationControlExtension,
		IInformationControlExtension2, DisposeListener {

	/**
	 * The NamePatternFilter selects the elements which match the given string
	 * patterns.
	 */
	protected class NamePatternFilter extends ViewerFilter {

		public NamePatternFilter() {
		}

		@Override
		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			StringMatcher matcher = getMatcher();
			if (matcher == null || !(viewer instanceof TreeViewer))
				return true;
			TreeViewer treeViewer = (TreeViewer) viewer;

			String matchName = ((ILabelProvider) treeViewer.getLabelProvider())
					.getText(element);
			if (matchName != null && matcher.match(matchName))
				return true;

			return hasUnfilteredChild(treeViewer, element);
		}

		private boolean hasUnfilteredChild(TreeViewer viewer, Object element) {
			if (element instanceof IParent) {
				Object[] children = ((ITreeContentProvider) viewer
						.getContentProvider()).getChildren(element);
				for (int i = 0; i < children.length; i++)
					if (select(viewer, element, children[i]))
						return true;
			}
			return false;
		}
	}

	/** The control's text widget */
	private Text fFilterText;
	/** The control's tree widget */
	private TreeViewer fTreeViewer;
	/** The current string matcher */
	protected StringMatcher fStringMatcher;
	private ICommand fInvokingCommand;
	private KeySequence[] fInvokingCommandKeySequences;

	/**
	 * Fields that support the dialog menu
	 *
	 *
	 */
	private Composite fViewMenuButtonComposite;

	private CustomFiltersActionGroup fCustomFiltersActionGroup;

	private IKeyBindingService fKeyBindingService;
	private String[] fKeyBindingScopes;
	private IAction fShowViewMenuAction;
	private HandlerSubmission fShowViewMenuHandlerSubmission;

	/**
	 * Field for tree style since it must be remembered by the instance.
	 *
	 *
	 */
	private int fTreeStyle;

	/**
	 * Creates a tree information control with the given shell as parent. The
	 * given styles are applied to the shell and the tree widget.
	 *
	 * @param parent
	 *            the parent shell
	 * @param shellStyle
	 *            the additional styles for the shell
	 * @param treeStyle
	 *            the additional styles for the tree widget
	 * @param invokingCommandId
	 *            the id of the command that invoked this control or
	 *            <code>null</code>
	 * @param showStatusField
	 *            <code>true</code> iff the control has a status field at the
	 *            bottom
	 */
	public AbstractInformationControl(Shell parent, int shellStyle,
			int treeStyle, String invokingCommandId, boolean showStatusField) {
		super(parent, shellStyle, true, true, true, true, true, null, null);
		if (invokingCommandId != null) {
			ICommandManager commandManager = PlatformUI.getWorkbench()
					.getCommandSupport().getCommandManager();
			fInvokingCommand = commandManager.getCommand(invokingCommandId);
			if (fInvokingCommand != null && !fInvokingCommand.isDefined())
				fInvokingCommand = null;
			else
				// Pre-fetch key sequence - do not change because scope will
				// change later.
				getInvokingCommandKeySequences();
		}
		fTreeStyle = treeStyle;
		// Title and status text must be set to get the title label created, so
		// force empty values here.
		if (hasHeader())
			setTitleText(""); //$NON-NLS-1$
		setInfoText(""); // //$NON-NLS-1$

		// Create all controls early to preserve the life cycle of the original
		// implementation.
		if (isEarlyCreate()) {
			create();
		}

	}

	@Override
	public void create() {
		super.create();
		// Status field text can only be computed after widgets are created.
		setInfoText(getStatusFieldText());
	}

	protected boolean isEarlyCreate() {
		return true;
	}

	/**
	 * Create the main content for this information control.
	 *
	 * @param parent
	 *            The parent composite
	 * @return The control representing the main content.
	 *
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		fTreeViewer = createTreeViewer(parent, fTreeStyle);

		fCustomFiltersActionGroup = new CustomFiltersActionGroup(getId(),
				fTreeViewer);

		final Tree tree = fTreeViewer.getTree();
		tree.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.character == 0x1B) // ESC
					dispose();
			}
		});

		tree.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				gotoSelectedElement();
			}
		});

		tree.addMouseMoveListener(new MouseMoveListener() {
			TreeItem fLastItem = null;

			@Override
			public void mouseMove(MouseEvent e) {
				if (tree.equals(e.getSource())) {
					Object o = tree.getItem(new Point(e.x, e.y));
					if (o instanceof TreeItem) {
						if (!o.equals(fLastItem)) {
							fLastItem = (TreeItem) o;
							tree.setSelection(new TreeItem[] { fLastItem });
						} else if (e.y < tree.getItemHeight() / 4) {
							// Scroll up
							Point p = tree.toDisplay(e.x, e.y);
							Item item = fTreeViewer.scrollUp(p.x, p.y);
							if (item instanceof TreeItem) {
								fLastItem = (TreeItem) item;
								tree.setSelection(new TreeItem[] { fLastItem });
							}
						} else if (e.y > tree.getBounds().height
								- tree.getItemHeight() / 4) {
							// Scroll down
							Point p = tree.toDisplay(e.x, e.y);
							Item item = fTreeViewer.scrollDown(p.x, p.y);
							if (item instanceof TreeItem) {
								fLastItem = (TreeItem) item;
								tree.setSelection(new TreeItem[] { fLastItem });
							}
						}
					}
				}
			}
		});

		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {

				if (tree.getSelectionCount() < 1)
					return;

				if (e.button != 1)
					return;

				if (tree.equals(e.getSource())) {
					Object o = tree.getItem(new Point(e.x, e.y));
					TreeItem selection = tree.getSelection()[0];
					if (selection.equals(o))
						gotoSelectedElement();
				}
			}
		});

		installFilter();

		addDisposeListener(this);
		return fTreeViewer.getControl();
	}

	/**
	 * Creates a tree information control with the given shell as parent. The
	 * given styles are applied to the shell and the tree widget.
	 *
	 * @param parent
	 *            the parent shell
	 * @param shellStyle
	 *            the additional styles for the shell
	 * @param treeStyle
	 *            the additional styles for the tree widget
	 */
	public AbstractInformationControl(Shell parent, int shellStyle,
			int treeStyle) {
		this(parent, shellStyle, treeStyle, null, false);
	}

	protected abstract TreeViewer createTreeViewer(Composite parent, int style);

	/**
	 * Returns the name of the dialog settings section.
	 *
	 * @return the name of the dialog settings section
	 */
	protected abstract String getId();

	protected TreeViewer getTreeViewer() {
		return fTreeViewer;
	}

	/**
	 * Returns <code>true</code> if the control has a header, <code>false</code>
	 * otherwise.
	 * <p>
	 * The default is to return <code>false</code>.
	 * </p>
	 *
	 * @return <code>true</code> if the control has a header
	 */
	protected boolean hasHeader() {
		// default is to have no header
		return false;
	}

	protected Text getFilterText() {
		return fFilterText;
	}

	protected Text createFilterText(Composite parent) {
		fFilterText = new Text(parent, SWT.NONE);

		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		GC gc = new GC(parent);
		gc.setFont(parent.getFont());
		FontMetrics fontMetrics = gc.getFontMetrics();
		gc.dispose();

		data.heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 1);
		data.horizontalAlignment = GridData.FILL;
		data.verticalAlignment = GridData.CENTER;
		fFilterText.setLayoutData(data);

		fFilterText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == 0x0D) // return
					gotoSelectedElement();
				if (e.keyCode == SWT.ARROW_DOWN)
					fTreeViewer.getTree().setFocus();
				if (e.keyCode == SWT.ARROW_UP)
					fTreeViewer.getTree().setFocus();
				if (e.character == 0x1B) // ESC
					dispose();
			}
		});

		return fFilterText;
	}

	protected void createHorizontalSeparator(Composite parent) {
		Label separator = new Label(parent,
				SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT);
		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
	}

	protected void updateStatusFieldText() {
		setInfoText(getStatusFieldText());
	}

	/**
	 * Handles click in status field.
	 * <p>
	 * Default does nothing.
	 * </p>
	 */
	protected void handleStatusFieldClicked() {
	}

	protected String getStatusFieldText() {
		return ""; //$NON-NLS-1$
	}

	private void installFilter() {
		fFilterText.setText(""); //$NON-NLS-1$

		fFilterText.addModifyListener(e -> {
			String text = ((Text) e.widget).getText();
			int length = text.length();
			if (length > 0 && text.charAt(length - 1) != '*') {
				text = text + '*';
			}
			setMatcherString(text, true);
		});
	}

	/**
	 * The string matcher has been modified. The default implementation
	 * refreshes the view and selects the first matched element
	 */
	protected void stringMatcherUpdated() {
		// refresh viewer to re-filter
		fTreeViewer.getControl().setRedraw(false);
		fTreeViewer.refresh();
		fTreeViewer.expandAll();
		selectFirstMatch();
		fTreeViewer.getControl().setRedraw(true);
	}

	/**
	 * Sets the patterns to filter out for the receiver.
	 * <p>
	 * The following characters have special meaning: ? => any character * =>
	 * any string
	 * </p>
	 *
	 * @param pattern
	 *            the pattern
	 * @param update
	 *            <code>true</code> if the viewer should be updated
	 */
	protected void setMatcherString(String pattern, boolean update) {
		if (pattern.length() == 0) {
			fStringMatcher = null;
		} else {
			boolean ignoreCase = pattern.toLowerCase().equals(pattern);
			fStringMatcher = new StringMatcher(pattern, ignoreCase, false);
		}

		if (update)
			stringMatcherUpdated();
	}

	protected StringMatcher getMatcher() {
		return fStringMatcher;
	}

	/**
	 * Implementers can modify
	 *
	 * @return the selected element
	 */
	protected Object getSelectedElement() {
		if (fTreeViewer == null)
			return null;

		return ((IStructuredSelection) fTreeViewer.getSelection())
				.getFirstElement();
	}

	private void gotoSelectedElement() {
		Object selectedElement = getSelectedElement();
		if (selectedElement != null) {
			try {
				dispose();
				OpenActionUtil.open(selectedElement, true);
			} catch (CoreException ex) {
				DLTKUIPlugin.log(ex);
			}
		}
	}

	/**
	 * Selects the first element in the tree which matches the current filter
	 * pattern.
	 */
	protected void selectFirstMatch() {
		Tree tree = fTreeViewer.getTree();
		Object element = findElement(tree.getItems());
		if (element != null)
			fTreeViewer.setSelection(new StructuredSelection(element), true);
		else
			fTreeViewer.setSelection(StructuredSelection.EMPTY);
	}

	private IModelElement findElement(TreeItem[] items) {
		ILabelProvider labelProvider = (ILabelProvider) fTreeViewer
				.getLabelProvider();
		for (int i = 0; i < items.length; i++) {
			IModelElement element = (IModelElement) items[i].getData();
			if (fStringMatcher == null)
				return element;

			if (element != null) {
				String label = labelProvider.getText(element);
				if (fStringMatcher.match(label))
					return element;
			}

			element = findElement(items[i].getItems());
			if (element != null)
				return element;
		}
		return null;
	}

	@Override
	public void setInformation(String information) {
		// this method is ignored, see IInformationControlExtension2
	}

	@Override
	public abstract void setInput(Object information);

	/**
	 * Fills the view menu. Clients can extend or override.
	 *
	 * @param viewMenu
	 *            the menu manager that manages the menu
	 *
	 */
	protected void fillViewMenu(IMenuManager viewMenu) {
		fCustomFiltersActionGroup.fillViewMenu(viewMenu);
	}

	/*
	 * Overridden to call the old framework method.
	 *
	 * @see org.eclipse.jface.dialogs.PopupDialog#fillDialogMenu(IMenuManager)
	 */
	@Override
	protected void fillDialogMenu(IMenuManager dialogMenu) {
		super.fillDialogMenu(dialogMenu);
		fillViewMenu(dialogMenu);
	}

	protected void inputChanged(Object newInput, Object newSelection) {
		fFilterText.setText(""); //$NON-NLS-1$
		fTreeViewer.setInput(newInput);
		if (newSelection != null) {
			fTreeViewer.setSelection(new StructuredSelection(newSelection));
		}
	}

	@Override
	public void setVisible(boolean visible) {
		if (visible) {
			addHandlerAndKeyBindingSupport();
			open();
		} else {
			removeHandlerAndKeyBindingSupport();
			saveDialogBounds(getShell());
			getShell().setVisible(false);
			removeHandlerAndKeyBindingSupport();
		}
	}

	@Override
	public final void dispose() {
		close();
	}

	/**
	 * {@inheritDoc}
	 *
	 * @param event
	 *            can be null
	 *            <p>
	 *            Subclasses may extend.
	 *            </p>
	 */
	@Override
	public void widgetDisposed(DisposeEvent event) {
		removeHandlerAndKeyBindingSupport();
		fTreeViewer = null;
		fFilterText = null;
		fKeyBindingService = null;
	}

	/**
	 * Adds handler and key binding support.
	 *
	 *
	 */
	protected void addHandlerAndKeyBindingSupport() {
		// Remember current scope and then set window context.
		if (fKeyBindingScopes == null && fKeyBindingService != null) {
			fKeyBindingScopes = fKeyBindingService.getScopes();
			fKeyBindingService.setScopes(new String[] {
					IWorkbenchContextSupport.CONTEXT_ID_WINDOW });
		}

		// Register action with command support
		if (fShowViewMenuHandlerSubmission == null) {
			fShowViewMenuHandlerSubmission = new HandlerSubmission(null,
					getShell(), null,
					fShowViewMenuAction.getActionDefinitionId(),
					new ActionHandler(fShowViewMenuAction), Priority.MEDIUM);
			PlatformUI.getWorkbench().getCommandSupport()
					.addHandlerSubmission(fShowViewMenuHandlerSubmission);
		}
	}

	/**
	 * Removes handler and key binding support.
	 *
	 *
	 */
	protected void removeHandlerAndKeyBindingSupport() {
		// Remove handler submission
		if (fShowViewMenuHandlerSubmission != null)
			PlatformUI.getWorkbench().getCommandSupport()
					.removeHandlerSubmission(fShowViewMenuHandlerSubmission);

		// Restore editor's key binding scope
		if (fKeyBindingService != null && fKeyBindingScopes != null) {
			fKeyBindingService.setScopes(fKeyBindingScopes);
			fKeyBindingScopes = null;
		}
	}

	@Override
	public boolean hasContents() {
		return fTreeViewer != null && fTreeViewer.getInput() != null;
	}

	@Override
	public void setSizeConstraints(int maxWidth, int maxHeight) {
		// ignore
	}

	@Override
	public Point computeSizeHint() {
		// return the shell's size - note that it already has the persisted size
		// if persisting
		// is enabled.
		return getShell().getSize();
	}

	@Override
	public void setLocation(Point location) {
		/*
		 * If the location is persisted, it gets managed by PopupDialog - fine.
		 * Otherwise, the location is computed in Window#getInitialLocation,
		 * which will center it in the parent shell / main monitor, which is
		 * wrong for two reasons: - we want to center over the editor / subject
		 * control, not the parent shell - the center is computed via the
		 * initalSize, which may be also wrong since the size may have been
		 * updated since via min/max sizing of
		 * AbstractInformationControlManager. In that case, override the
		 * location with the one computed by the manager. Note that the call to
		 * constrainShellSize in PopupDialog.open will still ensure that the
		 * shell is entirely visible.
		 */
		if (!getPersistBounds() || getDialogSettings() == null)
			getShell().setLocation(location);
	}

	@Override
	public void setSize(int width, int height) {
		getShell().setSize(width, height);
	}

	@Override
	public void addDisposeListener(DisposeListener listener) {
		getShell().addDisposeListener(listener);
	}

	@Override
	public void removeDisposeListener(DisposeListener listener) {
		getShell().removeDisposeListener(listener);
	}

	@Override
	public void setForegroundColor(Color foreground) {
		applyForegroundColor(foreground, getContents());
	}

	@Override
	public void setBackgroundColor(Color background) {
		applyBackgroundColor(background, getContents());
	}

	@Override
	public boolean isFocusControl() {
		return fTreeViewer.getControl().isFocusControl()
				|| fFilterText.isFocusControl();
	}

	@Override
	public void setFocus() {
		getShell().forceFocus();
		fFilterText.setFocus();
	}

	@Override
	public void addFocusListener(FocusListener listener) {
		getShell().addFocusListener(listener);
	}

	@Override
	public void removeFocusListener(FocusListener listener) {
		getShell().removeFocusListener(listener);
	}

	final protected ICommand getInvokingCommand() {
		return fInvokingCommand;
	}

	final protected KeySequence[] getInvokingCommandKeySequences() {
		if (fInvokingCommandKeySequences == null) {
			if (getInvokingCommand() != null) {
				List list = getInvokingCommand().getKeySequenceBindings();
				if (!list.isEmpty()) {
					fInvokingCommandKeySequences = new KeySequence[list.size()];
					for (int i = 0; i < fInvokingCommandKeySequences.length; i++) {
						fInvokingCommandKeySequences[i] = ((IKeySequenceBinding) list
								.get(i)).getKeySequence();
					}
					return fInvokingCommandKeySequences;
				}
			}
		}
		return fInvokingCommandKeySequences;
	}

	@Override
	protected IDialogSettings getDialogSettings() {
		String sectionName = getId();

		IDialogSettings settings = DLTKUIPlugin.getDefault().getDialogSettings()
				.getSection(sectionName);
		if (settings == null)
			settings = DLTKUIPlugin.getDefault().getDialogSettings()
					.addNewSection(sectionName);

		return settings;
	}

	/*
	 * Overridden to insert the filter text into the title and menu area.
	 */
	@Override
	protected Control createTitleMenuArea(Composite parent) {
		fViewMenuButtonComposite = (Composite) super.createTitleMenuArea(
				parent);

		// If there is a header, then the filter text must be created
		// underneath the title and menu area.

		if (hasHeader()) {
			fFilterText = createFilterText(parent);
		}

		// Create a key binding for showing the dialog menu
		// Key binding service
		IWorkbenchPart part = DLTKUIPlugin.getActivePage().getActivePart();
		IWorkbenchPartSite site = part.getSite();
		fKeyBindingService = site.getKeyBindingService();

		// Create show view menu action
		fShowViewMenuAction = new Action("showViewMenu") { //$NON-NLS-1$
			/*
			 * @see org.eclipse.jface.action.Action#run()
			 */
			@Override
			public void run() {
				showDialogMenu();
			}
		};
		fShowViewMenuAction.setEnabled(true);
		fShowViewMenuAction
				.setActionDefinitionId("org.eclipse.ui.window.showViewMenu"); //$NON-NLS-1$

		addHandlerAndKeyBindingSupport();

		return fViewMenuButtonComposite;
	}

	/*
	 * Overridden to insert the filter text into the title control if there is
	 * no header specified.
	 */
	@Override
	protected Control createTitleControl(Composite parent) {
		if (hasHeader()) {
			return super.createTitleControl(parent);
		}
		fFilterText = createFilterText(parent);
		return fFilterText;
	}

	@Override
	protected void setTabOrder(Composite composite) {
		if (hasHeader()) {
			composite.setTabList(
					new Control[] { fFilterText, fTreeViewer.getTree() });
		} else {
			fViewMenuButtonComposite.setTabList(new Control[] { fFilterText });
			composite.setTabList(new Control[] { fViewMenuButtonComposite,
					fTreeViewer.getTree() });
		}
	}
}
