/*
 * Java
 *
 * Copyright 2021-2022 MicroEJ Corp. All rights reserved.
 * This library is provided in source code for use, modification and test, subject to license terms.
 * Any modification of the source code will break MicroEJ Corp. warranties on the whole library.
 */
package ej.microvg;

import ej.microui.display.GraphicsContext;

/**
 * Provides static methods to draw paths, texts and images.
 */
public class VectorGraphicsPainter {

	/**
	 * Enum for the ways a path may be filled.
	 */
	public enum FillType {
		/**
		 * Specifies that "inside" is computed by a non-zero sum of signed edge crossings.
		 */
		WINDING,
		/**
		 * Specifies that "inside" is computed by an odd number of edge crossings.
		 */
		EVEN_ODD,
	}

	/**
	 * Enum for specifying the direction in which a rotation can occur.
	 */
	public enum Direction {
		/**
		 * Specifies that the direction is the same as a clock's hands.
		 */
		CLOCKWISE,
		/**
		 * Specifies that the direction is the opposite as a clock's hands.
		 */
		COUNTER_CLOCKWISE,
	}

	private VectorGraphicsPainter() {
	}

	/**
	 * Draws a path filled with the color of the graphics context and winding fill type and source over blending.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * Matrix matrix = new Matrix();
	 * matrix.setTranslate(x, y);
	 * fillPath(g, path, matrix, FillType.WINDING, GraphicsContext.OPAQUE, BlendMode.SRC_OVER);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param path
	 *            the path to draw
	 * @param x
	 *            the x coordinate of the path
	 * @param y
	 *            the y coordinate of the path
	 */
	public static void fillPath(GraphicsContext g, Path path, float x, float y) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a path filled with the color of the graphics context and winding fill type and source over blending.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * fillPath(g, path, matrix, FillType.WINDING, GraphicsContext.OPAQUE, BlendMode.SRC_OVER);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param path
	 *            the path to draw
	 * @param matrix
	 *            the matrix to apply
	 */
	public static void fillPath(GraphicsContext g, Path path, Matrix matrix) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a path filled with the color of the graphics context.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param path
	 *            the path to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param fillType
	 *            the fill type
	 * @param alpha
	 *            the global opacity rendering value, between 0 (transparent) and 255 (opaque)
	 * @param blendMode
	 *            the blend mode
	 * @see GraphicsContext#getAlpha(int)
	 */
	public static void fillPath(GraphicsContext g, Path path, Matrix matrix, FillType fillType, int alpha,
			BlendMode blendMode) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a path filled with a linear gradient and winding fill type and source over blending.
	 * <p>
	 * The color of the graphics context is not used by this drawing.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * fillGradientPath(g, path, matrix, gradient, FillType.WINDING, GraphicsContext.OPAQUE, BlendMode.SRC_OVER);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param path
	 *            the path to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param gradient
	 *            the gradient to fill with
	 */
	public static void fillGradientPath(GraphicsContext g, Path path, Matrix matrix, LinearGradient gradient) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a path filled with a linear gradient.
	 * <p>
	 * The color of the graphics context is not used by this drawing.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param path
	 *            the path to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param gradient
	 *            the gradient to fill with
	 * @param fillType
	 *            the fill type
	 * @param alpha
	 *            the global opacity rendering value, between 0 (transparent) and 255 (opaque)
	 * @param blendMode
	 *            the blend mode
	 * @see GraphicsContext#getAlpha(int)
	 */
	public static void fillGradientPath(GraphicsContext g, Path path, Matrix matrix, LinearGradient gradient,
			FillType fillType, int alpha, BlendMode blendMode) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a vector image.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * Matrix matrix = new Matrix();
	 * matrix.setTranslate(x, y);
	 * drawImage(g, image, matrix, GraphicsContext.OPAQUE);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param x
	 *            the x coordinate of the image
	 * @param y
	 *            the y coordinate of the image
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 */
	public static void drawImage(GraphicsContext g, VectorImage image, float x, float y) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a vector image.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * drawImage(g, image, matrix, GraphicsContext.OPAQUE);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param matrix
	 *            the matrix to apply
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 */
	public static void drawImage(GraphicsContext g, VectorImage image, Matrix matrix) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a vector image.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param alpha
	 *            the global opacity rendering value, between 0 (transparent) and 255 (opaque)
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see GraphicsContext#getAlpha(int)
	 */
	public static void drawImage(GraphicsContext g, VectorImage image, Matrix matrix, int alpha) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws an animated vector image at a specific time.
	 * <p>
	 * The given elapsed time is cropped between 0 and the image duration.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * Matrix matrix = new Matrix();
	 * matrix.setTranslate(x, y);
	 * drawAnimatedImage(g, image, matrix, elapsedTime, GraphicsContext.OPAQUE);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param x
	 *            the x coordinate of the image
	 * @param y
	 *            the y coordinate of the image
	 * @param elapsedTime
	 *            the elapsed time since the beginning of the animation, in milliseconds
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 */
	public static void drawAnimatedImage(GraphicsContext g, VectorImage image, float x, float y, long elapsedTime) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws an animated vector image at a specific time.
	 * <p>
	 * The given elapsed time is cropped between 0 and the image duration.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * drawAnimatedImage(g, image, matrix, elapsedTime, GraphicsContext.OPAQUE);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param elapsedTime
	 *            the elapsed time since the beginning of the animation, in milliseconds
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 */
	public static void drawAnimatedImage(GraphicsContext g, VectorImage image, Matrix matrix, long elapsedTime) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws an animated vector image at a specific time.
	 * <p>
	 * The given elapsed time is cropped between 0 and the image duration.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param elapsedTime
	 *            the elapsed time since the beginning of the animation, in milliseconds
	 * @param alpha
	 *            the global opacity rendering value, between 0 (transparent) and 255 (opaque)
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see GraphicsContext#getAlpha(int)
	 */
	public static void drawAnimatedImage(GraphicsContext g, VectorImage image, Matrix matrix, long elapsedTime,
			int alpha) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a vector image with a color filter.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param colorMatrix
	 *            the color matrix used to transform colors
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @throws ArrayIndexOutOfBoundsException
	 *             if the given color matrix is shorter than 20 entries
	 * @see VectorImage#filterImage(float[])
	 */
	public static void drawFilteredImage(GraphicsContext g, VectorImage image, Matrix matrix, float[] colorMatrix) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws an animated vector image at a specific time with a color filter.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param image
	 *            the image to draw
	 * @param matrix
	 *            the matrix to apply
	 * @param elapsedTime
	 *            the elapsed time since the beginning of the animation, in milliseconds
	 * @param colorMatrix
	 *            the color matrix used to transform colors
	 * @throws VectorGraphicsException
	 *             if the image could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @throws ArrayIndexOutOfBoundsException
	 *             if the given color matrix is shorter than 20 entries
	 * @see VectorImage#filterImage(float[])
	 */
	public static void drawFilteredAnimatedImage(GraphicsContext g, VectorImage image, Matrix matrix, long elapsedTime,
			float[] colorMatrix) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a text.
	 * <p>
	 * This method uses the color of the graphics context as font color.
	 * <p>
	 * The anchor point is the top left corner of the text render box (related to font height; different from the text
	 * bounding box, which is related to font size; see class comment {@link VectorFont}). The position of this anchor
	 * point within the graphics context is defined by the {@code (x,y)} coordinates.
	 * <p>
	 * For example, to draw a text where {@code yBaseline} defines the y coordinate of the text baseline, use
	 * {@code yBaseline - font.getBaselinePosition()} as argument of this method (see
	 * {@link VectorFont#getBaselinePosition(float)}).
	 * <p>
	 * The font size must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * Matrix matrix = new Matrix();
	 * matrix.setTranslate(x, y);
	 * drawString(g, string font, size, matrix, GraphicsContext.OPAQUE, BlendMode.SRC_OVER, 0);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param string
	 *            the text to draw
	 * @param font
	 *            the font to use
	 * @param size
	 *            the font size, in pixels
	 * @param x
	 *            the x coordinate of the string
	 * @param y
	 *            the y coordinate of the string
	 * @throws VectorGraphicsException
	 *             if the text could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 */
	public static void drawString(GraphicsContext g, String string, VectorFont font, float size, float x, float y) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a text.
	 * <p>
	 * This method uses the color of the graphics context as font color.
	 * <p>
	 * The anchor point is the top left corner of the text render box (related to font height; different from the text
	 * bounding box, which is related to font size; see class comment {@link VectorFont}). The matrix defines the
	 * transformations to apply to the text (translation, scale, rotation). For example, passing the identity matrix to
	 * this method will draw an horizontal text whose top-left corner is aligned with the origin of the graphics
	 * context.
	 * <p>
	 * The font size must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * This method allows to specify the global opacity value to apply during the rendering. The alpha must be a value
	 * between {@value GraphicsContext#TRANSPARENT} and {@value GraphicsContext#OPAQUE}. If the specified alpha is
	 * outside this range, nothing is drawn.
	 * <p>
	 * The blend mode specifies the algorithm to use when blending the pixels of the source and destination.
	 * <p>
	 * The letter spacing argument specifies the extra space to add between the characters. A positive value will move
	 * the characters apart, a negative value will move them together. The default value is 0.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param string
	 *            the text to draw
	 * @param font
	 *            the font to use
	 * @param size
	 *            the font size, in pixels
	 * @param matrix
	 *            the transformation matrix to apply
	 * @param alpha
	 *            the global opacity rendering value
	 * @param blendMode
	 *            the blend mode to use
	 * @param letterSpacing
	 *            the extra letter spacing to use, in pixels
	 * @throws VectorGraphicsException
	 *             if the text could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see GraphicsContext#getAlpha(int)
	 * @see BlendMode
	 */
	public static void drawString(GraphicsContext g, String string, VectorFont font, float size, Matrix matrix,
			int alpha, BlendMode blendMode, float letterSpacing) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a text along a circle. The circle represents the text baseline.
	 * <p>
	 * This method uses the color of the graphics context as font color.
	 * <p>
	 * The anchor point is the center of the circle. The matrix defines the transformations to apply to the text
	 * (translation, scale, rotation). For example, passing the identity matrix to this method will align the center of
	 * the circle with the origin of the graphics context.
	 * <p>
	 * The position where the text starts along the circle is the 3 o'clock position (positive X axis). This starting
	 * position can be modified by specifying a rotation into the transformation matrix.
	 * <p>
	 * The text winds along the circle in the specified direction (clockwise or counter-clockwise). The radius of the
	 * circle must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * The font size must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * Equivalent to:
	 *
	 * <pre>
	 * drawStringOnCircle(g, string font, size, matrix, radius, direction, GraphicsContext.OPAQUE, BlendMode.SRC_OVER, 0);
	 * </pre>
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param string
	 *            the string to draw
	 * @param font
	 *            the font to use
	 * @param size
	 *            the font size, in pixels
	 * @param matrix
	 *            the matrix to apply
	 * @param radius
	 *            the radius of the circle, in pixels
	 * @param direction
	 *            the winding direction of the text along the circle.
	 * @throws VectorGraphicsException
	 *             if the text could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see Direction
	 */
	public static void drawStringOnCircle(GraphicsContext g, String string, VectorFont font, float size, Matrix matrix,
			float radius, Direction direction) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a text along a circle. The circle represents the text baseline.
	 * <p>
	 * This method uses the color of the graphics context as font color.
	 * <p>
	 * The anchor point is the center of the circle. The matrix defines the transformations to apply to the text
	 * (translation, scale, rotation). For example, passing the identity matrix to this method will align the center of
	 * the circle with the origin of the graphics context.
	 * <p>
	 * The position where the text starts along the circle is the 3 o'clock position (positive X axis). This starting
	 * position can be modified by specifying a rotation into the transformation matrix.
	 * <p>
	 * The text winds along the circle in the specified direction (clockwise or counter-clockwise). The radius of the
	 * circle must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * The font size must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * This method allows to specify the global opacity value to apply during the rendering. The alpha must be a value
	 * between {@value GraphicsContext#TRANSPARENT} and {@value GraphicsContext#OPAQUE}. If the specified alpha is
	 * outside this range, nothing is drawn.
	 * <p>
	 * The blend mode specifies the algorithm to use when blending the pixels of the source and destination.
	 * <p>
	 * The letter spacing argument specifies the extra space to add between the characters. A positive value will move
	 * the characters apart, a negative value will move them together. The default value is 0.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param string
	 *            the string to draw
	 * @param font
	 *            the font to use
	 * @param size
	 *            the font size, in pixels
	 * @param matrix
	 *            the matrix to apply
	 * @param radius
	 *            the radius of the circle, in pixels
	 * @param direction
	 *            the winding direction of the text along the circle
	 * @param alpha
	 *            the global opacity rendering value
	 * @param blendMode
	 *            the blend mode
	 * @param letterSpacing
	 *            the extra letter spacing to use, in pixels
	 * @throws VectorGraphicsException
	 *             if the text could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see GraphicsContext#getAlpha(int)
	 * @see BlendMode
	 * @see Direction
	 */
	public static void drawStringOnCircle(GraphicsContext g, String string, VectorFont font, float size, Matrix matrix,
			float radius, Direction direction, int alpha, BlendMode blendMode, float letterSpacing) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a text with a gradient.
	 * <p>
	 * This method uses the given gradient for the font coloring. The color of the graphics context is not used by this
	 * drawing.
	 * <p>
	 * The anchor point is the top left corner of the text render box (related to font height; different from the text
	 * bounding box, which is related to font size; see class comment {@link VectorFont}). The matrix defines the
	 * transformations to apply to the text (translation, scale, rotation). For example, passing the identity matrix to
	 * this method will draw an horizontal text whose top-left corner is aligned with the origin of the graphics
	 * context.
	 * <p>
	 * The font size must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * This method allows to specify the global opacity value to apply during the rendering. The alpha must be a value
	 * between {@value GraphicsContext#TRANSPARENT} and {@value GraphicsContext#OPAQUE}. If the specified alpha is
	 * outside this range, nothing is drawn.
	 * <p>
	 * The blend mode specifies the algorithm to use when blending the pixels of the source and destination.
	 * <p>
	 * The letter spacing argument specifies the extra space to add between the characters. A positive value will move
	 * the characters apart, a negative value will move them together. The default value is 0.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param string
	 *            the text to draw
	 * @param font
	 *            the font to use
	 * @param size
	 *            the font size, in pixels
	 * @param matrix
	 *            the transformation matrix to apply
	 * @param gradient
	 *            the gradient to color the text with
	 * @param alpha
	 *            the global opacity rendering value
	 * @param blendMode
	 *            the blend mode
	 * @param letterSpacing
	 *            the extra letter spacing to use, in pixels
	 * @throws VectorGraphicsException
	 *             if the text could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see GraphicsContext#getAlpha(int)
	 * @see BlendMode
	 */
	public static void drawGradientString(GraphicsContext g, String string, VectorFont font, float size, Matrix matrix,
			LinearGradient gradient, int alpha, BlendMode blendMode, float letterSpacing) {
		throw new VectorGraphicsException();
	}

	/**
	 * Draws a text with a gradient along a circle. The circle represents the text baseline.
	 * <p>
	 * This method uses the given gradient for the font coloring. The color of the graphics context is not used by this
	 * drawing.
	 * <p>
	 * The anchor point is the center of the circle. The matrix defines the transformations to apply to the text
	 * (translation, scale, rotation). For example, passing the identity matrix to this method will align the center of
	 * the circle with the origin of the graphics context.
	 * <p>
	 * The position where the text starts along the circle is the 3 o'clock position (positive X axis). This starting
	 * position can be modified by specifying a rotation into the transformation matrix.
	 * <p>
	 * The text winds along the circle in the specified direction (clockwise or counter-clockwise). The radius of the
	 * circle must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * The font size must be positive. If it is less than or equal to 0, nothing is drawn.
	 * <p>
	 * This method allows to specify the global opacity value to apply during the rendering. The alpha must be a value
	 * between {@value GraphicsContext#TRANSPARENT} and {@value GraphicsContext#OPAQUE}. If the specified alpha is
	 * outside this range, nothing is drawn.
	 * <p>
	 * The blend mode specifies the algorithm to use when blending the pixels of the source and destination.
	 * <p>
	 * The letter spacing argument specifies the extra space to add between the characters. A positive value will move
	 * the characters apart, a negative value will move them together. The default value is 0.
	 *
	 * @param g
	 *            the graphics context to draw on
	 * @param string
	 *            the string to draw
	 * @param font
	 *            the font to use
	 * @param size
	 *            the font size, in pixels
	 * @param matrix
	 *            the matrix to apply
	 * @param gradient
	 *            the gradient to color the string with
	 * @param alpha
	 *            the global opacity rendering value
	 * @param blendMode
	 *            the blend mode
	 * @param letterSpacing
	 *            the extra letter spacing to use, in pixels
	 * @param radius
	 *            the radius of the circle, in pixels
	 * @param direction
	 *            the winding direction of the text along the circle
	 * @throws VectorGraphicsException
	 *             if the text could not be drawn for any reason (see {@link VectorGraphicsException#getErrorCode()})
	 * @see GraphicsContext#getAlpha(int)
	 * @see BlendMode
	 * @see Direction
	 */
	public static void drawGradientStringOnCircle(GraphicsContext g, String string, VectorFont font, float size,
			Matrix matrix, LinearGradient gradient, float radius, Direction direction, int alpha, BlendMode blendMode,
			float letterSpacing) {
		throw new VectorGraphicsException();
	}

}
