package org.eclipse.jdt.internal.ui.preferences;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
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.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;

public final class PreferenceHighlight implements PaintListener {

	private static final int HIGHLIGHT_FOCUS= SWT.COLOR_WIDGET_DARK_SHADOW;

	private static final int HIGHLIGHT_MOUSE= SWT.COLOR_WIDGET_NORMAL_SHADOW;

	private final Composite fParent;

	private final Control fLabelControl;

	private final Control fMainControl;

	private boolean fHover;

	private boolean fFocus;

	private PreferenceHighlight(Composite parent, Control labelControl, Control mainControl) {
		fParent= parent;
		fLabelControl= labelControl;
		fMainControl= mainControl;
	}

	@Override
	public void paintControl(PaintEvent e) {
		if ((!fHover && !fFocus) || !fMainControl.isEnabled() || ((GridData) fLabelControl.getLayoutData()).exclude)
			return;

		final int GAP= 7;
		final int ARROW= 3;
		Rectangle l= fLabelControl.getBounds();
		Point c= fMainControl.getLocation();

		e.gc.setForeground(e.display.getSystemColor(fFocus ? HIGHLIGHT_FOCUS : HIGHLIGHT_MOUSE));
		int x2= c.x - GAP;
		int y= l.y + l.height / 2 + 1;

		e.gc.drawLine(l.x + l.width + GAP, y, x2, y);
		e.gc.drawLine(x2 - ARROW, y - ARROW, x2, y);
		e.gc.drawLine(x2 - ARROW, y + ARROW, x2, y);
	}

	/**
	 * Adds the highlight feature to a pair of controls, that is an arrow painted between the label
	 * and the main control for easier selection and to show when the control has focus. Both
	 * controls must have the same parent.
	 * 
	 * @param labelControl the control acting as label
	 * @param mainControl the main control
	 * @param autoFocus if true, focus highlight will be switched automatically based on main
	 *            controls focus state
	 * @return highlight handler
	 */
	public static PreferenceHighlight addHighlight(Control labelControl, Control mainControl, boolean autoFocus) {
		final Composite parent= labelControl.getParent();
		PreferenceHighlight highlight= new PreferenceHighlight(parent, labelControl, mainControl);
		parent.addPaintListener(highlight);

		if (autoFocus) {
			mainControl.addFocusListener(new FocusListener() {
				@Override
				public void focusLost(FocusEvent e) {
					highlight.setFocus(false);
				}

				@Override
				public void focusGained(FocusEvent e) {
					highlight.setFocus(true);
				}
			});
		}

		MouseTrackAdapter labelComboListener= new MouseTrackAdapter() {
			@Override
			public void mouseEnter(MouseEvent e) {
				highlight.setHover(true);
			}

			@Override
			public void mouseExit(MouseEvent e) {
				highlight.setHover(false);
			}
		};
		mainControl.addMouseTrackListener(labelComboListener);
		labelControl.addMouseTrackListener(labelComboListener);

		parent.addMouseMoveListener(e -> {
			highlight.setHover(highlight.isAroundLabel(e));
		});
		parent.addMouseTrackListener(MouseTrackListener.mouseExitAdapter(e -> {
			highlight.setHover(false);
		}));
		parent.addMouseListener(MouseListener.mouseDownAdapter(e -> {
			if (highlight.isAroundLabel(e))
				mainControl.setFocus();
		}));

		if (labelControl instanceof Label) {
			labelControl.addMouseListener(MouseListener.mouseDownAdapter(e -> mainControl.setFocus()));
		}

		return highlight;
	}

	public void setFocus(boolean focus) {
		if (fFocus != focus) {
			fFocus= focus;
			fParent.redraw();
		}
	}

	public void setHover(boolean hover) {
		if (fHover != hover) {
			fHover= hover;
			fParent.redraw();
		}
	}

	private boolean isAroundLabel(MouseEvent e) {
		int lx= fLabelControl.getLocation().x;
		Rectangle c= fMainControl.getBounds();
		int x= e.x;
		int y= e.y;
		return lx - 5 < x && x < c.x && c.y - 2 < y && y < c.y + c.height + 2;
	}
}
