/*******************************************************************************
 * Copyright (c) 2006, 2008 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.text.source;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
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.core.runtime.Assert;

import org.eclipse.jface.resource.JFaceResources;

import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.TextEvent;


/**
 * Abstract implementation of a {@link IVerticalRulerColumn} that
 * uses a {@link Canvas} to draw the ruler contents and which
 * handles scrolling and mouse selection.
 *
 * <h3>Painting</h3>
 * Subclasses can hook into the paint loop at three levels:
 * <ul>
 * <li>Override <strong>{@link #paint(GC, ILineRange)}</strong> to control the entire painting of
 * the ruler.</li>
 * <li>Override <strong>{@link #paintLine(GC, int, int, int, int)}</strong> to control the
 * painting of a line.</li>
 * <li>Leave the painting to the default implementation, but override <strong>{@link #computeBackground(int)}</strong>,
 * <strong>{@link #computeForeground(int)}</strong> and <strong>{@link #computeText(int)}</strong>
 * to specify the ruler appearance for a line.</li>
 * </ul>
 *
 * <h3>Invalidation</h3>
 * Subclasses may call {@link #redraw()} to mark the entire ruler as needing to be redrawn.
 * Alternatively, use {@link #redraw(ILineRange)} to only invalidate a certain line range, for
 * example due to changes to the display model.
 *
 * <h3>Configuration</h3>
 * Subclasses can set the following properties. Setting them may trigger redrawing.
 * <ul>
 * <li>The {@link #setFont(Font) font} used to draw text in {@link #paintLine(GC, int, int, int, int)}.</li>
 * <li>The horizontal {@link #setTextInset(int) text inset} for text drawn.</li>
 * <li>The {@link #setDefaultBackground(Color) default background color} of the ruler.</li>
 * <li>The {@link #setWidth(int) width} of the ruler.</li>
 * </ul>
 *
 * @since 3.3
 */
public abstract class AbstractRulerColumn implements IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension {
	private static final int DEFAULT_WIDTH= 12;
	private static final int DEFAULT_TEXT_INSET= 2;

	/**
	 * Handles all the mouse interaction in this line number ruler column.
	 */
	private final class MouseHandler implements MouseListener, MouseMoveListener {

		@Override
		public void mouseUp(MouseEvent event) {
		}

		@Override
		public void mouseDown(MouseEvent event) {
			fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
		}

		@Override
		public void mouseDoubleClick(MouseEvent event) {
			fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
		}

		@Override
		public void mouseMove(MouseEvent event) {
			fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
		}
	}

	/**
	 * Internal listener class that updates the ruler upon scrolling and text modifications.
	 */
	private final class InternalListener implements IViewportListener, ITextListener {

		@Override
		public void viewportChanged(int topPixel) {
			int delta= topPixel - fLastTopPixel;
			if (scrollVertical(delta))
				fCanvas.update(); // force update the invalidated regions
		}

		@Override
		public void textChanged(TextEvent event) {
			/*
			 * Redraw: - when the viewer is drawing, and any of the following - the widget was not
			 * full before the change - the widget is not full after the change - the document event
			 * was a visual modification (no document event attached) - for example when the
			 * projection changes.
			 */
			if (!event.getViewerRedrawState())
				return;

			if (fWasShowingEntireContents || event.getDocumentEvent() == null || JFaceTextUtil.isShowingEntireContents(fStyledText))
				redraw();
		}
	}

	/* Listeners */

	/** The viewport listener. */
	private final InternalListener fInternalListener= new InternalListener();
	/** The mouse handler. */
	private final MouseHandler fMouseHandler= new MouseHandler();

	/*
	 * Implementation and context of this ruler - created and set in createControl(), disposed of in
	 * columnRemoved().
	 */

	/** The parent ruler, possibly <code>null</code>. */
	private CompositeRuler fParentRuler;
	/** The canvas, the only widget used to draw this ruler, possibly <code>null</code>. */
	private Canvas fCanvas;
	/** The text viewer, possibly <code>null</code>. */
	private ITextViewer fTextViewer;
	/** The text viewer's widget, possibly <code>null</code>. */
	private StyledText fStyledText;

	/* State when the canvas was last painted. */

	/** The text widget's top pixel when the ruler was last painted. */
	private int fLastTopPixel= -1;
	/** Whether the text widget was showing the entire contents when the ruler was last painted. */
	private boolean fWasShowingEntireContents= false;

	/* Configuration */

	/** The width of this ruler. */
	private int fWidth= DEFAULT_WIDTH;
	/** The text inset. */
	private int fTextInset= DEFAULT_TEXT_INSET;
	/** The default background color, <code>null</code> to use the text viewer's background color. */
	private Color fBackground;
	/** The font, <code>null</code> to use the default font. */
	private Font fFont;
	/** The annotation model, possibly <code>null</code>. */
	private IAnnotationModel fModel;
	/** The annotation hover, possibly <code>null</code>. */
	private IAnnotationHover fHover;

	/**
	 * Creates a new ruler.
	 */
	protected AbstractRulerColumn() {
	}

	@Override
	public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
		Assert.isLegal(parentControl != null);
		Assert.isLegal(parentRuler != null);
		Assert.isLegal(fParentRuler == null); // only call when not yet initialized!

		fParentRuler= parentRuler;

		fTextViewer= getParentRuler().getTextViewer();
		fTextViewer.addViewportListener(fInternalListener);
		fTextViewer.addTextListener(fInternalListener);

		fStyledText= fTextViewer.getTextWidget();

		fCanvas= new Canvas(parentControl, getCanvasStyle());

		fCanvas.setBackground(getDefaultBackground());
		fCanvas.setFont(getFont());

		fCanvas.addPaintListener(AbstractRulerColumn.this::paintControl);

		fCanvas.addMouseListener(fMouseHandler);
		fCanvas.addMouseMoveListener(fMouseHandler);

		return fCanvas;
	}

	/**
	 * Returns the SWT style bits used when creating the ruler canvas.
	 * <p>
	 * The default implementation returns <code>SWT.NO_BACKGROUND</code>.</p>
	 * <p>
	 * Clients may reimplement this method to create a canvas with their
	 * desired style bits.</p>
	 *
	 * @return the SWT style bits, or <code>SWT.NONE</code> if none
	 */
	protected int getCanvasStyle() {
		return SWT.NO_BACKGROUND;
	}

	@Override
	public final Control getControl() {
		return fCanvas;
	}

	/**
	 * The new width in pixels. The <code>DEFAULT_WIDTH</code> constant
	 * specifies the default width.
	 *
	 * @param width the new width
	 */
	protected final void setWidth(int width) {
		Assert.isLegal(width >= 0);
		if (fWidth != width) {
			fWidth= width;
			CompositeRuler composite= getParentRuler();
			if (composite != null)
				composite.relayout();
		}
	}

	@Override
	public final int getWidth() {
		return fWidth;
	}

	/**
	 * Returns the parent ruler, <code>null</code> before
	 * {@link #createControl(CompositeRuler, Composite)} has been called.
	 *
	 * @return the parent ruler or <code>null</code>
	 */
	protected final CompositeRuler getParentRuler() {
		return fParentRuler;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @param font the font or <code>null</code> to use the default font
	 */
	@Override
	public final void setFont(Font font) {
		if (fFont != font) {
			fFont= font;
			redraw();
		}
	}

	/**
	 * Returns the current font. If a font has not been explicitly set, the widget's font is
	 * returned.
	 *
	 * @return the font used to render text on the ruler.
	 */
	protected final Font getFont() {
		if (fFont != null)
			return fFont;
		if (fStyledText != null && !fStyledText.isDisposed())
			return fStyledText.getFont();
		return JFaceResources.getTextFont();
	}

	/**
	 * Sets the text inset (padding) used to draw text in {@link #paintLine(GC, int, int, int, int)}.
	 *
	 * @param textInset the new text inset
	 */
	protected final void setTextInset(int textInset) {
		if (textInset != fTextInset) {
			fTextInset= textInset;
			redraw();
		}
	}

	/**
	 * Returns the text inset for text drawn by {@link #paintLine(GC, int, int, int, int)}. The
	 * <code>DEFAULT_TEXT_INSET</code> constant specifies the default inset in pixels.
	 *
	 * @return the text inset for text
	 */
	protected final int getTextInset() {
		return fTextInset;
	}

	@Override
	public void setModel(IAnnotationModel model) {
		if (fModel != model) {
			fModel= model;
			redraw();
		}
	}

	@Override
	public final IAnnotationModel getModel() {
		return fModel;
	}

	/**
	 * Sets the default background color for this column. The default background is used as default
	 * implementation of {@link #computeBackground(int)} and also to paint the area of the ruler
	 * that does not correspond to any lines (when the viewport is not entirely filled with lines).
	 *
	 * @param background the default background color, <code>null</code> to use the text widget's
	 *        background
	 */
	protected final void setDefaultBackground(Color background) {
		if (fBackground != background) {
			fBackground= background;
			if (fCanvas != null && !fCanvas.isDisposed())
				fCanvas.setBackground(getDefaultBackground());
			redraw();
		}
	}

	/**
	 * Returns the background color. May return <code>null</code> if the system is shutting down.
	 *
	 * @return the background color
	 */
	protected final Color getDefaultBackground() {
		if (fBackground != null)
			return fBackground;
		if (fStyledText != null && !fStyledText.isDisposed())
			return fStyledText.getBackground();
		Display display;
		if (fCanvas != null && !fCanvas.isDisposed())
			display= fCanvas.getDisplay();
		else
			display= Display.getCurrent();
		if (display != null)
			return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
		return null;
	}

	/**
	 * Sets the annotation hover.
	 *
	 * @param hover the annotation hover, <code>null</code> for no hover
	 */
	protected final void setHover(IAnnotationHover hover) {
		if (fHover != hover)
			fHover= hover;
	}

	@Override
	public IAnnotationHover getHover() {
		return fHover;
	}

	/**
	 * Disposes this ruler column.
	 * <p>
	 * Subclasses may extend this method.</p>
	 * <p>
	 * Clients who created this column are responsible to call this method
	 * once the column is no longer used.</p>
	 */
	public void dispose() {
		if (fTextViewer != null) {
			fTextViewer.removeViewportListener(fInternalListener);
			fTextViewer.removeTextListener(fInternalListener);
			fTextViewer= null;
		}

		if (fStyledText != null)
			fStyledText= null;

		if (fCanvas != null) {
			fCanvas.dispose();
			fCanvas= null;
		}
	}

	@Override
	public final void redraw() {
		if (fCanvas != null && !fCanvas.isDisposed())
			fCanvas.redraw();
	}

	/**
	 * Marks the region covered by <code>lines</code> as needing to be redrawn.
	 *
	 * @param lines the lines to be redrawn in document coordinates
	 */
	protected final void redraw(ILineRange lines) {
		if (fCanvas == null || fCanvas.isDisposed())
			return;
		int firstModelLine= lines.getStartLine();
		int lastModelLine= firstModelLine + lines.getNumberOfLines();
		int firstWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, firstModelLine);
		int lastWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, lastModelLine);

		int from= Math.max(0, fStyledText.getLinePixel(firstWidgetLine));
		// getLinePixel will return the last pixel of the last line if line == lineCount
		int to= Math.min(fCanvas.getSize().y, fStyledText.getLinePixel(lastWidgetLine + 1));
		fCanvas.redraw(0, from, fWidth, to - from, false);
	}

	/**
	 * Paints the ruler column.
	 *
	 * @param event the paint event
	 */
	private void paintControl(PaintEvent event) {
		if (fTextViewer == null)
			return;
		fWasShowingEntireContents= JFaceTextUtil.isShowingEntireContents(fStyledText);
		fLastTopPixel= fStyledText.getTopPixel();

		ILineRange lines= computeDirtyWidgetLines(event);
		GC gc= event.gc;
		paint(gc, lines);

		if ((fCanvas.getStyle() & SWT.NO_BACKGROUND) != 0) {
			// fill empty area below any lines
			int firstEmpty= Math.max(event.y, fStyledText.getLinePixel(fStyledText.getLineCount()));
			int lastEmpty= event.y + event.height;
			if (lastEmpty > firstEmpty) {
				gc.setBackground(getDefaultBackground());
				gc.fillRectangle(0, firstEmpty, getWidth(), lastEmpty - firstEmpty);
			}
		}
	}

	/**
	 * Computes the widget lines that need repainting given the clipping region of a paint event.
	 *
	 * @param event the paint event
	 * @return the lines in widget coordinates that need repainting
	 */
	private ILineRange computeDirtyWidgetLines(PaintEvent event) {
		int firstLine= fStyledText.getLineIndex(event.y);
		int lastLine= fStyledText.getLineIndex(event.y + event.height - 1);
		return new LineRange(firstLine, lastLine - firstLine + 1);
	}

	/**
	 * Paints the ruler. Note that <code>lines</code> reference widget line indices, and that
	 * <code>lines</code> may not cover the entire viewport, but only the lines that need to be
	 * painted. The lines may not be entirely visible.
	 * <p>
	 * Subclasses may replace or extend. The default implementation calls
	 * {@link #paintLine(GC, int, int, int, int)} for every visible line.
	 * </p>
	 *
	 * @param gc the graphics context to paint on
	 * @param lines the lines to paint in widget coordinates
	 */
	protected void paint(GC gc, ILineRange lines) {
		final int firstLine= lines.getStartLine();
		final int lastLine= firstLine + lines.getNumberOfLines();
		for (int line= firstLine; line < lastLine; line++) {
			int modelLine= JFaceTextUtil.widgetLine2ModelLine(fTextViewer, line);
			if (modelLine == -1)
				continue;
			int linePixel= fStyledText.getLinePixel(line);
			int lineHeight= fStyledText.getLineHeight(fStyledText.getOffsetAtLine(line));
			paintLine(gc, modelLine, line, linePixel, lineHeight);
		}
	}

	/**
	 * Paints the ruler representation of a single line.
	 * <p>
	 * Subclasses may replace or extend. The default implementation draws the text obtained by
	 * {@link #computeText(int)} in the {@link #computeForeground(int) foreground color} and fills
	 * the entire width using the {@link #computeBackground(int) background color}. The text is
	 * drawn {@link #getTextInset()} pixels to the right of the left border.
	 * </p>
	 *
	 * @param gc the graphics context to paint on
	 * @param modelLine the model line (based on document coordinates)
	 * @param widgetLine the line in the text widget corresponding to <code>modelLine</code>
	 * @param linePixel the first y-pixel of the widget line
	 * @param lineHeight the line height in pixels
	 */
	protected void paintLine(GC gc, int modelLine, int widgetLine, int linePixel, int lineHeight) {
		gc.setBackground(computeBackground(modelLine));
		gc.fillRectangle(0, linePixel, getWidth(), lineHeight);
		String text= computeText(modelLine);
		if (text != null) {
			gc.setForeground(computeForeground(modelLine));
			gc.drawString(text, getTextInset(), linePixel, true);
		}
	}

	/**
	 * Returns the text to be drawn for a certain line by {@link #paintLine(GC, int, int, int, int)},
	 * <code>null</code> for no text. The default implementation returns <code>null</code>.
	 * <p>
	 * Subclasses may replace or extend.
	 * </p>
	 *
	 * @param line the document line number
	 * @return the text to be drawn for the given line, <code>null</code> for no text
	 */
	protected String computeText(int line) {
		return null;
	}

	/**
	 * Returns the background color drawn for a certain line by
	 * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns
	 * {@link #getDefaultBackground()}.
	 * <p>
	 * Subclasses may replace or extend.
	 * </p>
	 *
	 * @param line the document line number
	 * @return the background color for drawn for the given line
	 */
	protected Color computeBackground(int line) {
		return getDefaultBackground();
	}

	/**
	 * Returns the foreground color drawn for a certain line by
	 * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns a
	 * {@link SWT#COLOR_DARK_GRAY} color.
	 * <p>
	 * Subclasses may replace or extend.
	 * </p>
	 *
	 * @param line the document line number
	 * @return the foreground color for drawn for the given line
	 */
	protected Color computeForeground(int line) {
		return fStyledText.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
	}

	@Override
	public final int getLineOfLastMouseButtonActivity() {
		return getParentRuler().getLineOfLastMouseButtonActivity();
	}

	@Override
	public final int toDocumentLineNumber(int y_coordinate) {
		return getParentRuler().toDocumentLineNumber(y_coordinate);
	}

	@Override
	public void addVerticalRulerListener(IVerticalRulerListener listener) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void removeVerticalRulerListener(IVerticalRulerListener listener) {
		throw new UnsupportedOperationException();
	}

	/**
	 * Scrolls the canvas vertically (adapted from
	 * {@linkplain StyledText StyledText.scrollVertical()}).
	 *
	 * @param pixels the number of pixels to scroll (negative to scroll upwards)
	 * @return <code>true</code> if the widget was scrolled, <code>false</code> if the widget
	 *         was not scrolled
	 */
	private boolean scrollVertical(int pixels) {
		if (pixels == 0 || fCanvas == null || fCanvas.isDisposed())
			return false;

		final int width= getWidth();
		final int clientAreaHeight= fStyledText.getClientArea().height;
		final int topMargin= 0;
		final int leftMargin= 0;
		final int bottomMargin= 0;

		if (pixels > 0) {
			// downwards scrolling - content moves upwards
			int sourceY= topMargin + pixels;
			int scrollHeight= clientAreaHeight - sourceY - bottomMargin;
			if (scrollHeight > 0)
				// scroll recycled area
				fCanvas.scroll(leftMargin, topMargin, leftMargin, sourceY, width, scrollHeight, true);
			if (sourceY > scrollHeight) {
				// redraw in-between area
				int redrawY= Math.max(0, topMargin + scrollHeight);
				int redrawHeight= Math.min(clientAreaHeight, pixels - scrollHeight);
				fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true);
			}
		} else {
			// upwards scrolling - content moves downwards
			int destinationY= topMargin - pixels;
			int scrollHeight= clientAreaHeight - destinationY - bottomMargin;
			if (scrollHeight > 0)
				// scroll recycled area
				fCanvas.scroll(leftMargin, destinationY, leftMargin, topMargin, width, scrollHeight, true);
			if (destinationY > scrollHeight) {
				// redraw in-between area
				int redrawY= Math.max(0, topMargin + scrollHeight);
				int redrawHeight= Math.min(clientAreaHeight, -pixels - scrollHeight);
				fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true);
			}
		}
		return true;
	}
}
