/*
 * Java
 *
 * Copyright 2018-2020 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.drawing;

import ej.microui.display.GraphicsContext;

/**
 * The <code>ShapePainter</code> class offers a set of static methods to render thick shapes (with or without
 * anti-aliasing) and polygons.
 */
public class ShapePainter {

    /**
     * Defines the cap representation when drawing a line or a circle arc.
     */
    public enum Cap {

        /**
         * No specific cap is drawn.
         */
        NONE,
        /**
         * Cap is represented by a semi circle (default configuration).
         */
        ROUNDED,
        /**
         * Cap is perpendicular to the line.
         */
        PERPENDICULAR
    }

    /**
     * Draws a faded point at <code>(x,y)</code> using the {@link GraphicsContext}'s current color.
     * <p>
     * The shape's bounding box is
     * <code>(x - thickness / 2 - fade, y - thickness / 2 - fade) to (x + thickness / 2 + fade, y + thickness / 2 + fade)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the point
     * @param y
     *            the y coordinate of the point
     * @param thickness
     *            the thickness to apply.
     * @param fade
     *            the fade to apply.
     * @throws IllegalArgumentException
     *             when given thickness is negative
     */
    public static void drawThickFadedPoint(GraphicsContext gc, int x, int y, int thickness, int fade) {
        throw new RuntimeException();
    }

    /**
     * Draws a line from <code>(x1,y1)</code> to <code>(x2,y2)</code> using the {@link GraphicsContext}'s current color.
     * <p>
     * The rendering is aliased but the rendering time is often faster than
     * {@link #drawThickFadedLine(GraphicsContext, int, int, int, int, int, int, Cap, Cap)}.
     * <p>
     * Equivalent to calling {@link #drawThickFadedLine(GraphicsContext, int, int, int, int, int, int, Cap, Cap)} with a
     * fade equals to 0 and {@link Cap#NONE} for caps.
     * <p>
     * The shape's bounding box is
     * <code>(min(startX, endX) - thickness / 2, min(startY, endY) - thickness / 2) to (max(startX, endX) + thickness / 2, max(startY, endY) + thickness / 2)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param startX
     *            the x coordinate of the start of the line.
     * @param startY
     *            the y coordinate of the start of the line.
     * @param endX
     *            the x coordinate of the end of the line.
     * @param endY
     *            the y coordinate of the end of the line.
     * @param thickness
     *            the thickness to apply.
     * @throws IllegalArgumentException
     *             when given thickness is negative
     */
    public static void drawThickLine(GraphicsContext gc, int startX, int startY, int endX, int endY, int thickness) {
        throw new RuntimeException();
    }

    /**
     * Draws a faded line from <code>(x1,y1)</code> to <code>(x2,y2)</code> using the {@link GraphicsContext}'s current
     * color and caps.
     * <p>
     * The shape's bounding box is
     * <code>(min(startX, endX) - thickness / 2 - fade, min(startY, endY) - thickness / 2 - fade) to (max(startX, endX) + thickness / 2 + fade, max(startY, endY) + thickness / 2 + fade)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param startX
     *            the x coordinate of the start of the line
     * @param startY
     *            the y coordinate of the start of the line
     * @param endX
     *            the x coordinate of the end of the line
     * @param endY
     *            the y coordinate of the end of the line
     * @param thickness
     *            the thickness to apply.
     * @param fade
     *            the fade to apply.
     * @param startCap
     *            the cap to draw on (x1,y1).
     * @param endCap
     *            the cap to draw on (x2,y2).
     * @throws IllegalArgumentException
     *             when given thickness or fade is negative
     */
    public static void drawThickFadedLine(GraphicsContext gc, int startX, int startY, int endX, int endY, int thickness, int fade, Cap startCap, Cap endCap) {
        throw new RuntimeException();
    }

    /**
     * Draws the outline of a circular arc covering the specified square, using the {@link GraphicsContext} 's current
     * color.<br>
     * <br>
     * The arc is drawn from <code>startAngle</code> up to <code>arcAngle</code> degrees. The center of the arc is
     * defined as the center of the square whose origin is at <code>(x,y)</code> (upper-left corner) and whose dimension
     * is given by <code>diameter</code>.<br>
     * <br>
     * Angles are interpreted such that 0 degrees is at the 3 o'clock position. A positive value indicates a
     * counter-clockwise rotation while a negative value indicates a clockwise rotation.<br>
     * <br>
     * If <code>diameter</code> is negative, nothing is drawn.
     * <p>
     * The rendering is aliased but the rendering time is often faster than
     * {@link #drawThickFadedCircleArc(GraphicsContext, int, int, int, float, float, int, int, Cap, Cap)}.
     * <p>
     * Equivalent to calling
     * {@link #drawThickFadedCircleArc(GraphicsContext, int, int, int, float, float, int, int, Cap, Cap)} with a fade
     * equals to 0 and {@link Cap#NONE} for caps.
     * <p>
     * The shape's bounding box is (when arcAngle is 360°):
     * <code>(x - thickness / 2, y - thickness / 2) to (x + diameter + thickness / 2, y + diameter + thickness / 2)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the upper-left corner of the square where the arc is drawn.
     * @param y
     *            the y coordinate of the upper-left corner of the square where the arc is drawn.
     * @param diameter
     *            the diameter of the arc to draw.
     * @param startAngle
     *            the beginning angle of the arc to draw.
     * @param arcAngle
     *            the angular extent of the arc from <code>startAngle</code>.
     * @param thickness
     *            the thickness to apply.
     * @throws IllegalArgumentException
     *             when given thickness is negative
     */
    public static void drawThickCircleArc(GraphicsContext gc, int x, int y, int diameter, float startAngle, float arcAngle, int thickness) {
        throw new RuntimeException();
    }

    /**
     * Draws the faded outline of a circular arc covering the specified square, using the current color and caps. <br>
     * <br>
     * The arc is drawn from <code>startAngle</code> up to <code>arcAngle</code> degrees. The center of the arc is
     * defined as the center of the square whose origin is at <code>(x,y)</code> (upper-left corner) and whose dimension
     * is given by <code>diameter</code>.<br>
     * <br>
     * Angles are interpreted such that 0 degrees is at the 3 o'clock position. A positive value indicates a
     * counter-clockwise rotation while a negative value indicates a clockwise rotation.<br>
     * <br>
     * If <code>diameter</code> is negative or zero, nothing is drawn.<br>
     * <br>
     * The angles are given relative to the square. For instance an angle of 45 degrees is always defined by the line
     * from the center of the square to the upper right corner of the square. Thus for a non squared square angles are
     * skewed along either height or width.
     * <p>
     * The shape's bounding box is (when arcAngle is 360°):
     * <code>(x - thickness / 2 - fade, y - thickness / 2 - fade) to (x + diameter + thickness / 2 + fade, y + diameter + thickness / 2 + fade)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the upper-left corner of the square where the arc is drawn
     * @param y
     *            the y coordinate of the upper-left corner of the square where the arc is drawn
     * @param diameter
     *            the diameter of the arc to draw
     * @param startAngle
     *            the beginning angle of the arc to draw
     * @param arcAngle
     *            the angular extent of the arc from <code>startAngle</code>
     * @param thickness
     *            the thickness to apply.
     * @param fade
     *            the fade to apply.
     * @param startCap
     *            the cap to draw at startAngle.
     * @param endCap
     *            the cap to draw at startAngle + arcAngle.
     * @throws IllegalArgumentException
     *             when given thickness or fade is negative
     */
    public static void drawThickFadedCircleArc(GraphicsContext gc, int x, int y, int diameter, float startAngle, float arcAngle, int thickness, int fade, Cap startCap, Cap endCap) {
        throw new RuntimeException();
    }

    /**
     * Draws the outline of a circle covering the square specified by its diameter, using the {@link GraphicsContext} 's
     * current color.<br>
     * <br>
     * The center of the circle is defined as the center of the square whose origin is at <code>(x,y)</code> (upper-left
     * corner) and whose dimension is given by <code>diameter</code>.<br>
     * <br>
     * If <code>diameter</code> is negative, nothing is drawn.<br>
     * <p>
     * The rendering is aliased but the rendering time is often faster than
     * {@link #drawThickFadedCircle(GraphicsContext, int, int, int, int, int)}.
     * <p>
     * Equivalent to calling {@link #drawThickFadedCircle(GraphicsContext, int, int, int, int, int)} with a fade equals
     * to 0.
     * <p>
     * The shape's bounding box is
     * <code>(x - thickness / 2, y - thickness / 2) to (x + diameter + thickness / 2, y + diameter + thickness / 2)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the upper-left corner of the square where the circle is drawn.
     * @param y
     *            the y coordinate of the upper-left corner of the square where the circle is drawn.
     * @param diameter
     *            the diameter of the circle to draw.
     * @param thickness
     *            the thickness to apply.
     * @throws IllegalArgumentException
     *             when given thickness is negative
     */
    public static void drawThickCircle(GraphicsContext gc, int x, int y, int diameter, int thickness) {
        throw new RuntimeException();
    }

    /**
     * Draws the faded outline of a circle covering the square specified by its diameter, using the
     * {@link GraphicsContext} 's current color.<br>
     * <br>
     * The center of the circle is defined as the center of the square whose origin is at <code>(x,y)</code> (upper-left
     * corner) and whose dimension is given by <code>diameter</code>.<br>
     * <br>
     * If <code>diameter</code> is negative or zero, nothing is drawn.<br>
     * <p>
     * The shape's bounding box is
     * <code>(x - thickness / 2 - fade, y - thickness / 2 - fade) to (x + diameter + thickness / 2 + fade, y + diameter + thickness / 2 + fade)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the upper-left corner of the square where the circle is drawn
     * @param y
     *            the y coordinate of the upper-left corner of the square where the circle is drawn
     * @param diameter
     *            the diameter of the circle to draw
     * @param thickness
     *            the thickness to apply.
     * @param fade
     *            the fade to apply.
     * @throws IllegalArgumentException
     *             when given thickness or fade is negative
     */
    public static void drawThickFadedCircle(GraphicsContext gc, int x, int y, int diameter, int thickness, int fade) {
        throw new RuntimeException();
    }

    /**
     * Draws the outline of a ellipse covering the specified rectangle, using the {@link GraphicsContext}'s current
     * color.<br>
     * <br>
     * The center of the ellipse is defined as the center of the rectangle whose origin is at <code>(x,y)</code>
     * (upper-left corner) and whose dimension is given by <code>width</code> and <code>height</code>.<br>
     * <br>
     * If either <code>width</code> or <code>height</code> is negative or zero, nothing is drawn.<br>
     * <p>
     * The rendering is aliased but the rendering time is often faster than
     * {@link #drawThickFadedEllipse(GraphicsContext, int, int, int, int, int, int)}.
     * <p>
     * Equivalent to calling {@link #drawThickFadedEllipse(GraphicsContext, int, int, int, int, int, int)} with a fade
     * equals to 0.
     * <p>
     * The shape's bounding box is
     * <code>(x - thickness / 2, y - thickness / 2) to (x + width + thickness / 2, y + height + thickness / 2)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the upper-left corner of the rectangle where the ellipse is drawn
     * @param y
     *            the y coordinate of the upper-left corner of the rectangle where the ellipse is drawn
     * @param width
     *            the width of the ellipse to draw
     * @param height
     *            the height of the ellipse to draw
     * @param thickness
     *            the thickness to apply.
     * @throws IllegalArgumentException
     *             when given thickness is negative
     */
    public static void drawThickEllipse(GraphicsContext gc, int x, int y, int width, int height, int thickness) {
        throw new RuntimeException();
    }

    /**
     * Draws the outline of a ellipse covering the specified rectangle, using the {@link GraphicsContext}'s current
     * color.<br>
     * <br>
     * The center of the ellipse is defined as the center of the rectangle whose origin is at <code>(x,y)</code>
     * (upper-left corner) and whose dimension is given by <code>width</code> and <code>height</code>.<br>
     * <br>
     * If either <code>width</code> or <code>height</code> is negative or zero, nothing is drawn.<br>
     * <p>
     * The shape's bounding box is
     * <code>(x - thickness / 2 - fade, y - thickness / 2 - fade) to (x + width + thickness / 2 + fade, y + height + thickness / 2 + fade)</code>.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param x
     *            the x coordinate of the upper-left corner of the rectangle where the ellipse is drawn
     * @param y
     *            the y coordinate of the upper-left corner of the rectangle where the ellipse is drawn
     * @param width
     *            the width of the ellipse to draw
     * @param height
     *            the height of the ellipse to draw
     * @param thickness
     *            the thickness to apply.
     * @param fade
     *            the fade to apply.
     * @throws IllegalArgumentException
     *             when given thickness or fade is negative
     */
    public static void drawThickFadedEllipse(GraphicsContext gc, int x, int y, int width, int height, int thickness, int fade) {
        throw new RuntimeException();
    }

    /**
     * Draws the closed polygon which is defined by the array of integer coordinates, using the current color. Lines are
     * drawn between each consecutive pair, and between the first pair and last pair in the array. The effect is
     * identical to<br>
     * <code>draw(xys,0,xys.length);</code>
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param xys
     *            the array of coordinates : x1,y1,......xn,yn.
     * @throws IllegalArgumentException
     *             if the given array length is odd.
     */
    public static void drawPolygon(GraphicsContext gc, int[] xys) {
        throw new RuntimeException();
    }

    /**
     * Draws the closed polygon which is defined by the array of integer coordinates, using the current color. Lines are
     * drawn between each consecutive pair, and between the first pair and last pair in the array.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param xys
     *            the array of coordinates : x1,y1,......xn,yn.
     * @param offset
     *            the <code>x1</code> index in <code>xys</code>.
     * @param length
     *            the number of coordinates, must be even.
     * @throws IllegalArgumentException
     *             if the given array length is odd.
     * @throws ArrayIndexOutOfBoundsException
     *             the wanted data is outside the array bounds.
     */
    public static void drawPolygon(GraphicsContext gc, int[] xys, int offset, int length) {
        throw new RuntimeException();
    }

    /**
     * Fills the closed polygon which is defined by the array of integer coordinates, using the current color. Lines are
     * drawn between each consecutive pair, and between the first pair and last pair in the array. The lines connecting
     * each pair of points are included in the filled polygon. The effect is identical to<br>
     * <code>fill(xys,0,xys.length);</code>
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param xys
     *            the array of coordinates : x1,y1,......xn,yn.
     * @throws IllegalArgumentException
     *             if the given array length is odd.
     */
    public static void fillPolygon(GraphicsContext gc, int[] xys) {
        throw new RuntimeException();
    }

    /**
     * Fills the closed polygon which is defined by the array of integer coordinates, using the current color. Lines are
     * drawn between each consecutive pair, and between the first pair and last pair in the array. The lines connecting
     * each pair of points are included in the filled polygon.
     *
     * @param gc
     *            the graphics context where render the drawing.
     * @param xys
     *            the array of coordinates : x1,y1,......xn,yn.
     * @param offset
     *            the <code>x1</code> index in <code>xys</code>.
     * @param length
     *            the number of coordinates, must be even.
     * @throws ArrayIndexOutOfBoundsException
     *             if <code>offset</code> and <code>length</code> do not specify a valid range within <code>xys</code>.
     * @throws IllegalArgumentException
     *             if the <code>xys</code> length is odd.
     */
    public static void fillPolygon(GraphicsContext gc, int[] xys, int offset, int length) {
        throw new RuntimeException();
    }
}
