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

		// not available yet
		// HORIZONTAL,
		// VERTICAL,
		;
	}

	private ShapePainter() {
		// static methods only
	}

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