/*******************************************************************************
 * 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.hover;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.text.AbstractInformationControlManager;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlExtension;
import org.eclipse.jface.text.IInformationControlExtension2;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.IAnnotationAccessExtension;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.jface.text.source.IVerticalRulerListener;
import org.eclipse.jface.text.source.VerticalRulerEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;

/**
 * A control that can display a number of annotations. The control can decide
 * how it layouts the annotations to present them to the user.
 * <p>
 * This class got moved here form Platform Text since it was not used there and
 * caused discouraged access warnings. It will be moved down again once
 * annotation roll-over support is provided by Platform Text.
 * </p>
 * <p>
 * Each annotation can have its custom context menu and hover.
 * </p>
 *
 * @since 3.2
 */
public class AnnotationExpansionControl implements IInformationControl,
		IInformationControlExtension, IInformationControlExtension2 {

	public interface ICallback {
		void run(IInformationControlExtension2 control);
	}

	/**
	 * Input used by the control to display the annotations. TODO move to
	 * top-level class TODO encapsulate fields
	 *
	 * @since 3.0
	 */
	public static class AnnotationHoverInput {
		public Annotation[] fAnnotations;
		public ISourceViewer fViewer;
		public IVerticalRulerInfo fRulerInfo;
		public IVerticalRulerListener fAnnotationListener;
		public IDoubleClickListener fDoubleClickListener;
		public ICallback redoAction;
		public IAnnotationModel model;
	}

	private final class Item {
		Annotation fAnnotation;
		Canvas canvas;
		StyleRange[] oldStyles;

		public void selected() {
			Display disp = fShell.getDisplay();
			canvas.setCursor(fHandCursor);
			// TODO: shade - for now: set grey background
			canvas.setBackground(getSelectionColor(disp));

			// highlight the viewer background at its position
			oldStyles = setViewerBackground(fAnnotation);

			// set the selection
			fSelection = this;

			if (fHoverManager != null)
				fHoverManager.showInformation();

			if (fInput.fAnnotationListener != null) {
				VerticalRulerEvent event = new VerticalRulerEvent(fAnnotation);
				fInput.fAnnotationListener.annotationSelected(event);
			}

		}

		public void defaultSelected() {
			if (fInput.fAnnotationListener != null) {
				VerticalRulerEvent event = new VerticalRulerEvent(fAnnotation);
				fInput.fAnnotationListener.annotationDefaultSelected(event);
			}

			dispose();
		}

		public void deselect() {
			// hide the popup
			// fHoverManager.disposeInformationControl();

			// deselect
			fSelection = null;

			resetViewerBackground(oldStyles);
			oldStyles = null;

			Display disp = fShell.getDisplay();
			canvas.setCursor(null);
			// TODO: remove shading - for now: set standard background
			canvas.setBackground(
					disp.getSystemColor(SWT.COLOR_INFO_BACKGROUND));

		}

	}

	/**
	 * Disposes of an item
	 */
	private final static class MyDisposeListener implements DisposeListener {
		@Override
		public void widgetDisposed(DisposeEvent e) {
			Item item = (Item) ((Widget) e.getSource()).getData();
			item.deselect();
			item.canvas = null;
			item.fAnnotation = null;
			item.oldStyles = null;

			((Widget) e.getSource()).setData(null);
		}
	}

	/**
	 * Listener on context menu invocation on the items
	 */
	private final class MyMenuDetectListener implements Listener {
		@Override
		public void handleEvent(Event event) {
			if (event.type == SWT.MenuDetect) {
				// TODO: show per-item menu
				// for now: show ruler context menu
				if (fInput != null) {
					Control ruler = fInput.fRulerInfo.getControl();
					if (ruler != null && !ruler.isDisposed()) {
						Menu menu = ruler.getMenu();
						if (menu != null && !menu.isDisposed()) {
							menu.setLocation(event.x, event.y);
							menu.addMenuListener(new MenuListener() {

								@Override
								public void menuHidden(MenuEvent e) {
									dispose();
								}

								@Override
								public void menuShown(MenuEvent e) {
								}

							});
							menu.setVisible(true);
						}
					}
				}
			}
		}
	}

	/**
	 * Listener on mouse events on the items.
	 */
	private final class MyMouseListener extends MouseAdapter {
		@Override
		public void mouseDoubleClick(MouseEvent e) {
			Item item = (Item) ((Widget) e.getSource()).getData();
			if (e.button == 1 && item.fAnnotation == fInput.fAnnotations[0]
					&& fInput.fDoubleClickListener != null) {
				fInput.fDoubleClickListener.doubleClick(null);
				// special code for JDT to renew the annotation set.
				if (fInput.redoAction != null)
					fInput.redoAction.run(AnnotationExpansionControl.this);
			}
			// dispose();
			// TODO special action to invoke double-click action on the vertical
			// ruler
			// how about
			// Canvas can= (Canvas) e.getSource();
			// Annotation a= (Annotation) can.getData();
			// if (a != null) {
			// a.getDoubleClickAction().run();
			// }
		}

		@Override
		public void mouseDown(MouseEvent e) {
			Item item = (Item) ((Widget) e.getSource()).getData();
			// TODO for now, to make double click work: disable single click on
			// the first item
			// disable later when the annotationlistener selectively handles
			// input
			if (item != null && e.button == 1) // && item.fAnnotation !=
												// fInput.fAnnotations[0])
				item.defaultSelected();
		}

		/*
		 * @see
		 * org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.
		 * MouseEvent)
		 */
		// public void mouseDown(MouseEvent e) {
		// super.mouseDown(e);
		// }
	}

	/**
	 * Listener on mouse track events on the items.
	 */
	private final class MyMouseTrackListener implements MouseTrackListener {
		@Override
		public void mouseEnter(MouseEvent e) {
			Item item = (Item) ((Widget) e.getSource()).getData();
			if (item != null)
				item.selected();
		}

		@Override
		public void mouseExit(MouseEvent e) {

			Item item = (Item) ((Widget) e.getSource()).getData();
			if (item != null)
				item.deselect();

			// if the event lies outside the entire popup, dispose
			org.eclipse.swt.graphics.Region region = fShell.getRegion();
			Canvas can = (Canvas) e.getSource();
			Point p = can.toDisplay(e.x, e.y);
			if (region == null) {
				Rectangle bounds = fShell.getBounds();
				// p= fShell.toControl(p);
				if (!bounds.contains(p))
					dispose();
			} else {
				p = fShell.toControl(p);
				if (!region.contains(p))
					dispose();
			}

		}

		@Override
		public void mouseHover(MouseEvent e) {
			if (fHoverManager == null) {
				fHoverManager = new HoverManager();
				fHoverManager.takesFocusWhenVisible(false);
				fHoverManager.install(fComposite);
				fHoverManager.showInformation();
			}
		}
	}

	/**
	 *
	 *
	 * @since 3.0
	 */
	public class LinearLayouter {

		private static final int ANNOTATION_SIZE = 14;
		private static final int BORDER_WIDTH = 2;

		public Layout getLayout(int itemCount) {
			// simple layout: a row of items
			GridLayout layout = new GridLayout(itemCount, true);
			layout.horizontalSpacing = 1;
			layout.verticalSpacing = 0;
			layout.marginHeight = 1;
			layout.marginWidth = 1;
			return layout;
		}

		public Object getLayoutData() {
			GridData gridData = new GridData(ANNOTATION_SIZE + 2 * BORDER_WIDTH,
					ANNOTATION_SIZE + 2 * BORDER_WIDTH);
			gridData.horizontalAlignment = GridData.CENTER;
			gridData.verticalAlignment = GridData.CENTER;
			return gridData;
		}

		public int getAnnotationSize() {
			return ANNOTATION_SIZE;
		}

		public int getBorderWidth() {
			return BORDER_WIDTH;
		}

		public org.eclipse.swt.graphics.Region getShellRegion(int itemCount) {
			// no special region - set to null for default shell size
			return null;
		}

	}

	/**
	 * Listener on paint events on the items. Paints the annotation image on the
	 * given <code>GC</code>.
	 */
	private final class MyPaintListener implements PaintListener {
		@Override
		public void paintControl(PaintEvent e) {
			Canvas can = (Canvas) e.getSource();
			Annotation a = ((Item) can.getData()).fAnnotation;
			if (a != null) {
				Rectangle rect = new Rectangle(fLayouter.getBorderWidth(),
						fLayouter.getBorderWidth(),
						fLayouter.getAnnotationSize(),
						fLayouter.getAnnotationSize());
				if (fAnnotationAccessExtension != null)
					fAnnotationAccessExtension.paint(a, e.gc, can, rect);
			}
		}
	}

	/**
	 * Our own private hover manager used to shop per-item pop-ups.
	 */
	private final class HoverManager extends AbstractInformationControlManager {

		/**
		 *
		 */
		public HoverManager() {
			super(parent -> new DefaultInformationControl(parent));

			setMargins(5, 10);
			setAnchor(ANCHOR_BOTTOM);
			setFallbackAnchors(
					new Anchor[] { ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT });
		}

		@Override
		protected void computeInformation() {
			if (fSelection != null) {
				Rectangle subjectArea = fSelection.canvas.getBounds();
				Annotation annotation = fSelection.fAnnotation;
				String msg;
				if (annotation != null)
					msg = annotation.getText();
				else
					msg = null;

				setInformation(msg, subjectArea);
			}
		}

	}

	/** Model data. */
	protected AnnotationHoverInput fInput;
	/** The control's shell */
	private Shell fShell;
	/** The composite combining all the items. */
	protected Composite fComposite;
	/** The hand cursor. */
	private Cursor fHandCursor;
	/**
	 * The currently selected item, or <code>null</code> if none is selected.
	 */
	private Item fSelection;
	/** The hover manager for the per-item hovers. */
	private HoverManager fHoverManager;
	/** The annotation access extension. */
	private IAnnotationAccessExtension fAnnotationAccessExtension;

	/* listener legion */
	private final MyPaintListener fPaintListener;
	private final MyMouseTrackListener fMouseTrackListener;
	private final MyMouseListener fMouseListener;
	private final MyMenuDetectListener fMenuDetectListener;
	private final DisposeListener fDisposeListener;
	private final IViewportListener fViewportListener;

	private LinearLayouter fLayouter;

	/**
	 * Creates a new control.
	 *
	 * @param parent
	 * @param shellStyle
	 * @param access
	 */
	public AnnotationExpansionControl(Shell parent, int shellStyle,
			IAnnotationAccess access) {
		fPaintListener = new MyPaintListener();
		fMouseTrackListener = new MyMouseTrackListener();
		fMouseListener = new MyMouseListener();
		fMenuDetectListener = new MyMenuDetectListener();
		fDisposeListener = new MyDisposeListener();
		fViewportListener = verticalOffset -> dispose();
		fLayouter = new LinearLayouter();

		if (access instanceof IAnnotationAccessExtension)
			fAnnotationAccessExtension = (IAnnotationAccessExtension) access;

		fShell = new Shell(parent, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP);
		Display display = fShell.getDisplay();
		fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
		fComposite = new Composite(fShell,
				SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM);
		// fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE
		// | SWT.NO_TRIM | SWT.V_SCROLL);

		GridLayout layout = new GridLayout(1, true);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		fShell.setLayout(layout);

		GridData data = new GridData(GridData.FILL_BOTH);
		data.heightHint = fLayouter.getAnnotationSize()
				+ 2 * fLayouter.getBorderWidth() + 4;
		fComposite.setLayoutData(data);
		fComposite.addMouseTrackListener(new MouseTrackAdapter() {

			@Override
			public void mouseExit(MouseEvent e) {
				if (fComposite == null)
					return;
				Control[] children = fComposite.getChildren();
				Rectangle bounds = null;
				for (int i = 0; i < children.length; i++) {
					if (bounds == null)
						bounds = children[i].getBounds();
					else
						bounds.add(children[i].getBounds());
					if (bounds.contains(e.x, e.y))
						return;
				}

				// if none of the children contains the event, we leave the
				// popup
				dispose();
			}

		});

		// fComposite.getVerticalBar().addListener(SWT.Selection, new Listener()
		// {
		//
		// public void handleEvent(Event event) {
		// Rectangle bounds= fShell.getBounds();
		// int x= bounds.x - fLayouter.getAnnotationSize() -
		// fLayouter.getBorderWidth();
		// int y= bounds.y;
		// fShell.setBounds(x, y, bounds.width, bounds.height);
		// }
		//
		// });

		fHandCursor = new Cursor(display, SWT.CURSOR_HAND);
		fShell.setCursor(fHandCursor);
		fComposite.setCursor(fHandCursor);

		setInfoSystemColor();
	}

	private void setInfoSystemColor() {
		Display display = fShell.getDisplay();
		setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
		setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
	}

	@Override
	public void setInformation(String information) {
		setInput(null);
	}

	@Override
	public void setInput(Object input) {
		if (fInput != null && fInput.fViewer != null)
			fInput.fViewer.removeViewportListener(fViewportListener);

		if (input instanceof AnnotationHoverInput)
			fInput = (AnnotationHoverInput) input;
		else
			fInput = null;

		inputChanged(fInput, null);
	}

	protected void inputChanged(Object newInput, Object newSelection) {
		refresh();
	}

	protected void refresh() {
		adjustItemNumber();

		if (fInput == null)
			return;

		if (fInput.fAnnotations == null)
			return;

		if (fInput.fViewer != null)
			fInput.fViewer.addViewportListener(fViewportListener);

		fShell.setRegion(fLayouter.getShellRegion(fInput.fAnnotations.length));

		Layout layout = fLayouter.getLayout(fInput.fAnnotations.length);
		fComposite.setLayout(layout);

		Control[] children = fComposite.getChildren();
		for (int i = 0; i < fInput.fAnnotations.length; i++) {
			Canvas canvas = (Canvas) children[i];
			Item item = new Item();
			item.canvas = canvas;
			item.fAnnotation = fInput.fAnnotations[i];
			canvas.setData(item);
			canvas.redraw();
		}

	}

	protected void adjustItemNumber() {
		if (fComposite == null)
			return;

		Control[] children = fComposite.getChildren();
		int oldSize = children.length;
		int newSize = fInput == null ? 0 : fInput.fAnnotations.length;

		Display display = fShell.getDisplay();

		// add missing items
		for (int i = oldSize; i < newSize; i++) {
			Canvas canvas = new Canvas(fComposite, SWT.NONE);
			Object gridData = fLayouter.getLayoutData();
			canvas.setLayoutData(gridData);
			canvas.setBackground(
					display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));

			canvas.addPaintListener(fPaintListener);

			canvas.addMouseTrackListener(fMouseTrackListener);

			canvas.addMouseListener(fMouseListener);

			canvas.addListener(SWT.MenuDetect, fMenuDetectListener);

			canvas.addDisposeListener(fDisposeListener);
		}

		// dispose of exceeding resources
		for (int i = oldSize; i > newSize; i--) {
			Item item = (Item) children[i - 1].getData();
			item.deselect();
			children[i - 1].dispose();
		}

	}

	@Override
	public void setVisible(boolean visible) {
		fShell.setVisible(visible);
	}

	@Override
	public void dispose() {
		if (fShell != null) {
			if (!fShell.isDisposed())
				fShell.dispose();
			fShell = null;
			fComposite = null;
			if (fHandCursor != null)
				fHandCursor.dispose();
			fHandCursor = null;
			if (fHoverManager != null)
				fHoverManager.dispose();
			fHoverManager = null;
			fSelection = null;
		}
	}

	@Override
	public boolean hasContents() {
		return fInput.fAnnotations != null && fInput.fAnnotations.length > 0;
	}

	@Override
	public void setSizeConstraints(int maxWidth, int maxHeight) {
		// fMaxWidth= maxWidth;
		// fMaxHeight= maxHeight;
	}

	@Override
	public Point computeSizeHint() {
		return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
	}

	@Override
	public void setLocation(Point location) {
		fShell.setLocation(location);
	}

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

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

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

	@Override
	public void setForegroundColor(Color foreground) {
		fComposite.setForeground(foreground);
	}

	@Override
	public void setBackgroundColor(Color background) {
		fComposite.setBackground(background);
	}

	@Override
	public boolean isFocusControl() {
		if (fComposite.isFocusControl())
			return true;

		Control[] children = fComposite.getChildren();
		for (int i = 0; i < children.length; i++) {
			if (children[i].isFocusControl())
				return true;
		}
		return false;
	}

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

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

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

	private StyleRange[] setViewerBackground(Annotation annotation) {
		StyledText text = fInput.fViewer.getTextWidget();
		if (text == null || text.isDisposed())
			return null;

		Display disp = text.getDisplay();

		Position pos = fInput.model.getPosition(annotation);
		if (pos == null)
			return null;

		IRegion region = ((TextViewer) fInput.fViewer)
				.modelRange2WidgetRange(new Region(pos.offset, pos.length));
		if (region == null)
			return null;

		StyleRange[] ranges = text.getStyleRanges(region.getOffset(),
				region.getLength());

		List<StyleRange> undoRanges = new ArrayList<>(ranges.length);
		for (int i = 0; i < ranges.length; i++) {
			undoRanges.add((StyleRange) ranges[i].clone());
		}

		int offset = region.getOffset();
		StyleRange current = undoRanges.size() > 0
				? (StyleRange) undoRanges.get(0)
				: null;
		int curStart = current != null ? current.start
				: region.getOffset() + region.getLength();
		int curEnd = current != null ? current.start + current.length : -1;
		int index = 0;

		// fill no-style regions
		while (curEnd < region.getOffset() + region.getLength()) {
			// add empty range
			if (curStart > offset) {
				StyleRange undoRange = new StyleRange(offset, curStart - offset,
						null, null);
				undoRanges.add(index, undoRange);
				index++;
			}

			// step
			index++;
			if (index < undoRanges.size()) {
				offset = curEnd;
				current = undoRanges.get(index);
				curStart = current.start;
				curEnd = current.start + current.length;
			} else if (index == undoRanges.size()) {
				// last one
				offset = curEnd;
				current = null;
				curStart = region.getOffset() + region.getLength();
				curEnd = -1;
			} else
				curEnd = region.getOffset() + region.getLength();
		}

		// create modified styles (with background)
		List shadedRanges = new ArrayList(undoRanges.size());
		for (Iterator it = undoRanges.iterator(); it.hasNext();) {
			StyleRange range = (StyleRange) ((StyleRange) it.next()).clone();
			shadedRanges.add(range);
			range.background = getHighlightColor(disp);
		}

		// set the ranges one by one
		for (Iterator iter = shadedRanges.iterator(); iter.hasNext();) {
			text.setStyleRange((StyleRange) iter.next());

		}

		return undoRanges.toArray(undoRanges.toArray(new StyleRange[0]));
	}

	private void resetViewerBackground(StyleRange[] oldRanges) {

		if (oldRanges == null)
			return;

		if (fInput == null)
			return;

		StyledText text = fInput.fViewer.getTextWidget();
		if (text == null || text.isDisposed())
			return;

		// set the ranges one by one
		for (int i = 0; i < oldRanges.length; i++) {
			text.setStyleRange(oldRanges[i]);
		}
	}

	private Color getHighlightColor(Display disp) {
		return disp.getSystemColor(SWT.COLOR_GRAY);
	}

	private Color getSelectionColor(Display disp) {
		return disp.getSystemColor(SWT.COLOR_GRAY);
	}

}
