/**
 *  Copyright (c) 2017 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.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;

import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationPainter.IDrawingStrategy;

/**
 * {@link IDrawingStrategy} implementation to render {@link AbstractInlinedAnnotation}.
 *
 * @since 3.13
 */
class InlinedAnnotationDrawingStrategy implements IDrawingStrategy {

	@Override
	public void draw(Annotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length, Color color) {
		if (!(annotation instanceof AbstractInlinedAnnotation)) {
			return;
		}
		AbstractInlinedAnnotation inlinedAnnotation= (AbstractInlinedAnnotation) annotation;
		if (inlinedAnnotation.isInVisibleLines() && inlinedAnnotation.isFirstVisibleOffset(widgetOffset)) {
			draw((AbstractInlinedAnnotation) annotation, gc, textWidget, widgetOffset, length,
					color);
		}
	}

	/**
	 * Draw the inlined annotation.
	 *
	 * @param annotation the annotation to be drawn
	 * @param gc the graphics context, <code>null</code> when in clearing mode
	 * @param textWidget the text widget to draw on
	 * @param widgetOffset the offset of the line
	 * @param length the length of the line
	 * @param color the color of the line
	 */
	public static void draw(AbstractInlinedAnnotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length,
			Color color) {
		if (annotation instanceof LineHeaderAnnotation) {
			draw((LineHeaderAnnotation) annotation, gc, textWidget, widgetOffset, length, color);
		} else {
			draw((LineContentAnnotation) annotation, gc, textWidget, widgetOffset, length, color);
		}
	}

	/**
	 * Draw the line header annotation in the line spacing of the previous line.
	 *
	 * @param annotation the annotation to be drawn
	 * @param gc the graphics context, <code>null</code> when in clearing mode
	 * @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
	 */
	private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText textWidget, int offset, int length,
			Color color) {
		int line= textWidget.getLineAtOffset(offset);
		if (isDeleted(annotation)) {
			// When annotation is deleted, update metrics to null to remove extra spaces of the line header annotation.
			if (textWidget.getLineVerticalIndent(line) > 0)
				textWidget.setLineVerticalIndent(line, 0);
			return;
		}
		if (gc != null) {
			// Setting vertical indent first, before computing bounds
			int height= annotation.getHeight();
			if (height != 0) {
				if (height != textWidget.getLineVerticalIndent(line)) {
					if (annotation.oldLine != -1 && annotation.oldLine < textWidget.getLineCount()) {
						textWidget.setLineVerticalIndent(annotation.oldLine, 0);
					}
					textWidget.setLineVerticalIndent(line, height);
				}
				annotation.oldLine= line;
			} else if (textWidget.getLineVerticalIndent(line) > 0) {
				textWidget.setLineVerticalIndent(line, 0);
			}
			// Compute the location of the annotation
			Rectangle bounds= textWidget.getTextBounds(offset, offset);
			int x= bounds.x;
			int y= bounds.y;
			// Draw the line header annotation
			gc.setBackground(textWidget.getBackground());
			annotation.setLocation(x, y);
			annotation.draw(gc, textWidget, offset, length, color, x, y);
		} else if (textWidget.getLineVerticalIndent(line) > 0) {
			// Here vertical indent is done, the redraw of the full line width is done to avoid annotation clipping
			Rectangle bounds= textWidget.getTextBounds(offset, offset);
			Rectangle client= textWidget.getClientArea();
			textWidget.redraw(0, bounds.y, client.width, bounds.height, false);
		} else {
			textWidget.redrawRange(offset, length, true);
		}
	}

	/**
	 * Draw the line content annotation inside line in the empty area computed by
	 * {@link GlyphMetrics}.
	 *
	 * @param annotation the annotation to be drawn
	 * @param gc the graphics context, <code>null</code> when in clearing mode
	 * @param textWidget the text widget to draw on
	 * @param widgetOffset the offset of the line in the widget (not model)
	 * @param length the length of the line
	 * @param color the color of the line
	 */
	private static void draw(LineContentAnnotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length,
			Color color) {
		if (annotation.isEndOfLine(widgetOffset)) {
			drawAfterLine(annotation, gc, textWidget, widgetOffset, length, color);
		} else if (annotation.drawRightToPreviousChar(widgetOffset)) {
			drawAsRightOfPreviousCharacter(annotation, gc, textWidget, widgetOffset, length, color);
		} else {
			drawAsLeftOf1stCharacter(annotation, gc, textWidget, widgetOffset, length, color);
		}
	}

	private static void drawAfterLine(LineContentAnnotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length, Color color) {
		if (gc == null) {
			return;
		}
		if (textWidget.getCharCount() == 0) {
			annotation.draw(gc, textWidget, widgetOffset, length, color, 0, 0);
		} else {
			int line= textWidget.getLineAtOffset(widgetOffset);
			int lineEndOffset= widgetOffset < textWidget.getCharCount() ? widgetOffset : textWidget.getCharCount() - 1;
			Rectangle bounds= textWidget.getTextBounds(lineEndOffset, lineEndOffset);
			int lineEndX= bounds.x + bounds.width + gc.stringExtent(" ").x; //$NON-NLS-1$
			annotation.setLocation(lineEndX, textWidget.getLinePixel(line) + textWidget.getLineVerticalIndent(line));
			annotation.draw(gc, textWidget, widgetOffset, length, color, lineEndX, textWidget.getLinePixel(line) + textWidget.getLineVerticalIndent(line));
		}
	}

	protected static void drawAsLeftOf1stCharacter(LineContentAnnotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length, Color color) {
		StyleRange style= null;
		try {
			style= textWidget.getStyleRangeAtOffset(widgetOffset);
		} catch (Exception e) {
			return;
		}
		if (isDeleted(annotation)) {
			// When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation.
			if (style != null && style.metrics != null) {
				style.metrics= null;
				textWidget.setStyleRange(style);
			}
			return;
		}
		if (gc != null) {
			String hostCharacter= textWidget.getText(widgetOffset, widgetOffset);
			boolean isEndOfLine= ("\r".equals(hostCharacter) || "\n".equals(hostCharacter)); //$NON-NLS-1$ //$NON-NLS-2$

			// Compute the location of the annotation
			Rectangle bounds= textWidget.getTextBounds(widgetOffset, widgetOffset);
			int x= bounds.x + (isEndOfLine ? bounds.width * 2 : 0);
			int y= bounds.y;

			// When line text has line header annotation, there is a space on the top, adjust the y by using char height
			y+= bounds.height - textWidget.getLineHeight();

			// Draw the line content annotation
			annotation.setLocation(x, y);
			annotation.draw(gc, textWidget, widgetOffset, length, color, x, y);
			int width= annotation.getWidth();
			if (width != 0) {
				if (isEndOfLine) {
					if (!gc.getClipping().contains(x, y)) {
						// The draw of mining is not inside the gc clipping, redraw the area which contains the mining to draw.
						Rectangle client= textWidget.getClientArea();
						textWidget.redraw(x, y, client.width, bounds.height, false);
					}
				} else {
					// Get size of the character where GlyphMetrics width is added
					Point charBounds= gc.stringExtent(hostCharacter);
					int charWidth= charBounds.x;

					// FIXME: remove this code when we need not redraw the character (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=531769)
					// START TO REMOVE
					annotation.setRedrawnCharacterWidth(charWidth);
					// END TO REMOVE

					// Annotation takes place, add GlyphMetrics width to the style
					StyleRange newStyle= annotation.updateStyle(style);
					if (newStyle != null) {
						textWidget.setStyleRange(newStyle);
						return;
					}

					// FIXME: remove this code when we need not redraw the character (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=531769)
					// START TO REMOVE
					// The inline annotation replaces one character by taking a place width
					// GlyphMetrics
					// Here we need to redraw this first character because GlyphMetrics clip this
					// character.
					int redrawnHostCharX= x + bounds.width - charWidth;
					int redrawnHostCharY= y;
					gc.setForeground(textWidget.getForeground());
					gc.setBackground(textWidget.getBackground());
					gc.setFont(textWidget.getFont());
					if (style != null) {
						if (style.background != null) {
							gc.setBackground(style.background);
							gc.fillRectangle(redrawnHostCharX, redrawnHostCharY, charWidth + 1, bounds.height);
						}
						if (style.foreground != null) {
							gc.setForeground(style.foreground);
						}
						if (style.font != null) {
							gc.setFont(style.font);
						}
					}
					if (textWidget.getSelection().x <= widgetOffset && textWidget.getSelection().y > widgetOffset) {
						gc.setForeground(textWidget.getSelectionForeground());
						gc.setBackground(textWidget.getSelectionBackground());
					}
					gc.drawString(hostCharacter, redrawnHostCharX, redrawnHostCharY, true);
				}
				// END TO REMOVE
			} else if (style != null && style.metrics != null && style.metrics.width != 0) {
				// line content annotation had an , reset it
				style.metrics= null;
				textWidget.setStyleRange(style);
			}
		} else {
			textWidget.redrawRange(widgetOffset, length, true);
		}
	}

	protected static void drawAsRightOfPreviousCharacter(LineContentAnnotation annotation, GC gc, StyledText textWidget, int widgetOffset, int length, Color color) {
		StyleRange style= null;
		try {
			style= textWidget.getStyleRangeAtOffset(widgetOffset - 1);
		} catch (Exception e) {
			return;
		}
		if (isDeleted(annotation)) {
			// When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation.
			if (style != null && style.metrics != null) {
				style.metrics= null;
				textWidget.setStyleRange(style);
			}
			return;
		}
		if (gc != null) {
			char hostCharacter= textWidget.getText(widgetOffset - 1, widgetOffset - 1).charAt(0);
			// use gc.stringExtent instead of gc.geCharWidth because of bug 548866
			int redrawnCharacterWidth= hostCharacter != '\t' ? gc.stringExtent(Character.toString(hostCharacter)).x : textWidget.getTabs() * gc.stringExtent(" ").x; //$NON-NLS-1$
			Rectangle charBounds= textWidget.getTextBounds(widgetOffset - 1, widgetOffset - 1);
			Rectangle annotationBounds= new Rectangle(charBounds.x + redrawnCharacterWidth, charBounds.y, annotation.getWidth(), charBounds.height);

			// When line text has line header annotation, there is a space on the top, adjust the y by using char height
			int verticalDrawingOffset= charBounds.height - textWidget.getLineHeight();
			annotationBounds.y+= verticalDrawingOffset;

			// Draw the line content annotation
			annotation.setLocation(annotationBounds.x, annotationBounds.y);
			annotation.draw(gc, textWidget, widgetOffset, length, color, annotationBounds.x, annotationBounds.y);
			int width= annotation.getWidth();
			if (width != 0) {
				// FIXME: remove this code when we need not redraw the character (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=531769)
				// START TO REMOVE
				annotation.setRedrawnCharacterWidth(redrawnCharacterWidth);
				// END TO REMOVE

				// Annotation takes place, add GlyphMetrics width to the style
				StyleRange newStyle= annotation.updateStyle(style);
				if (newStyle != null) {
					textWidget.setStyleRange(newStyle);
					return;
				}

				// FIXME: remove this code when we need not redraw the character (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=531769)
				// START TO REMOVE
				// The inline annotation replaces one character by taking a place width
				// GlyphMetrics
				// Here we need to redraw this first character because GlyphMetrics clip this
				// character.
				gc.setForeground(textWidget.getForeground());
				gc.setBackground(textWidget.getBackground());
				gc.setFont(textWidget.getFont());
				if (style != null) {
					if (style.background != null) {
						gc.setBackground(style.background);
						gc.fillRectangle(charBounds.x, annotationBounds.y, redrawnCharacterWidth, charBounds.height);
					}
					if (style.foreground != null) {
						gc.setForeground(style.foreground);
					}
					if (style.font != null) {
						gc.setFont(style.font);
					}
				}
				int toRedrawCharOffset= widgetOffset - 1;
				if (textWidget.getSelection().x <= toRedrawCharOffset && textWidget.getSelection().y > toRedrawCharOffset) {
					gc.setForeground(textWidget.getSelectionForeground());
					gc.setBackground(textWidget.getSelectionBackground());
				}
				gc.drawString(Character.toString(hostCharacter), charBounds.x, charBounds.y + verticalDrawingOffset, true);
				// END TO REMOVE
			} else if (style != null && style.metrics != null && style.metrics.width != 0) {
				// line content annotation had an , reset it
				style.metrics= null;
				textWidget.setStyleRange(style);
			}
		} else {
			textWidget.redrawRange(widgetOffset, length, true);
		}
	}

	/**
	 * Returns <code>true</code> if inlined annotation is deleted and <code>false</code> otherwise.
	 *
	 * @param annotation the inlined annotation to check
	 * @return <code>true</code> if inlined annotation is deleted and <code>false</code> otherwise.
	 */
	private static boolean isDeleted(AbstractInlinedAnnotation annotation) {
		return annotation.isMarkedDeleted() || annotation.getPosition().isDeleted() || annotation.getPosition().getLength() == 0;
	}
}
