/**
 *  Copyright (c) 2017, 2018 Angelo ZERR.
 *
 *  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:
 *  Angelo Zerr <angelo.zerr@gmail.com> - [CodeMining] Provide inline annotations support - Bug 527675
 */
package org.eclipse.jface.text.source.inlined;

import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.GlyphMetrics;

import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.source.ISourceViewer;

/**
 * Inlined annotation which is drawn in the line content and which takes some place with a given
 * width.
 *
 * @since 3.13
 */
public class LineContentAnnotation extends AbstractInlinedAnnotation {

	/**
	 * The annotation width
	 */
	private int width;

	private int redrawnCharacterWidth;

	/**
	 * Line content annotation constructor.
	 *
	 * @param position the position where the annotation must be drawn.
	 * @param viewer   the {@link ISourceViewer} where the annotation must be drawn.
	 */
	public LineContentAnnotation(Position position, ISourceViewer viewer) {
		super(position, viewer);
	}

	/**
	 * Returns the annotation width. By default it computes the well width for the text annotation.
	 *
	 * @return the annotation width.
	 */
	public final int getWidth() {
		return width;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * After drawn, compute the text width and update it.
	 * </p>
	 */
	@Override
	public final void draw(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
		width= drawAndComputeWidth(gc, textWidget, offset, length, color, x, y);
	}

	/**
	 * Draw the inlined annotation. By default it draws the text of the annotation with gray color.
	 * User can override this method to draw anything.
	 *
	 * @param gc         the graphics context
	 * @param textWidget the text widget to draw on
	 * @param offset     the offset of the line
	 * @param length     the length of the line
	 * @param color      the color of the line
	 * @param x          the x position of the annotation
	 * @param y          the y position of the annotation
	 * @return the text width.
	 */
	protected int drawAndComputeWidth(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
		// Draw the text annotation and returns the width
		super.draw(gc, textWidget, offset, length, color, x, y);
		return (int) (gc.stringExtent(getText()).x + 2 * gc.getFontMetrics().getAverageCharacterWidth());
	}

	int getRedrawnCharacterWidth() {
		return redrawnCharacterWidth;
	}

	void setRedrawnCharacterWidth(int redrawnCharacterWidth) {
		this.redrawnCharacterWidth= redrawnCharacterWidth;
	}

	@Override
	boolean contains(int x, int y) {
		return (x >= this.fX && x <= this.fX + width && y >= this.fY && y <= this.fY + getTextWidget().getLineHeight());
	}

	/**
	 * Returns the style to apply with GlyphMetrics width only if needed.
	 *
	 * As it's using Widget position, the results can be passed directly to
	 * {@link StyledText#setStyleRange(StyleRange)} and family. However, in case of a Viewer
	 * providing project/folder with {@link ITextViewerExtension5}, the range must be transformed to
	 * model position before passing it to a {@link TextPresentation}.
	 *
	 * @param style the current style and null otherwise.
	 * @return the style to apply with GlyphMetrics width only if needed. It uses widget position,
	 *         not model position.
	 */
	StyleRange updateStyle(StyleRange style) {
		Position widgetPosition= computeWidgetPosition();
		boolean usePreviousChar= drawRightToPreviousChar(widgetPosition.getOffset());
		if (width == 0 || getRedrawnCharacterWidth() == 0) {
			return null;
		}
		int fullWidth= width + getRedrawnCharacterWidth();
		if (style == null) {
			style= new StyleRange();
			style.start= widgetPosition.getOffset();
			if (usePreviousChar) {
				style.start--;
			}
			style.length= 1;
		}
		GlyphMetrics metrics= style.metrics;
		if (!isMarkedDeleted()) {
			if (metrics == null) {
				metrics= new GlyphMetrics(0, 0, fullWidth);
			} else {
				if (metrics.width == fullWidth) {
					return null;
				}
				/**
				 * We must create a new GlyphMetrics instance because comparison with similarTo used
				 * later in StyledText#setStyleRange will compare the same (modified) and won't
				 * realize an update happened.
				 */
				metrics= new GlyphMetrics(0, 0, fullWidth);
			}
		} else {
			metrics= null;
		}
		style.metrics= metrics;
		return style;
	}

	boolean drawRightToPreviousChar(int widgetOffset) {
		return getTextWidget().getLineAtOffset(widgetOffset) == getTextWidget().getLineAtOffset(widgetOffset - 1);
	}

}
