/*
 * 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
    }

    /**
     * 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();
    }
}
