/*
 * Java
 *
 * Copyright 2020-2024 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 java.io.Closeable;

import ej.microui.display.Font;
import ej.microui.display.Painter;

/**
 * Represents a vector font.
 * <p>
 * <strong>Font metrics:</strong>
 * <ul>
 * <li><strong>Font size</strong>: the size of the text bounding box. Most of the glyphs will fit into that box, but
 * some may stick out of this box (like glyphs with accent, for example "Ä").</li>
 * <li><strong>Max ascent</strong>: the distance above the baseline for the highest glyph across the font.</li>
 * <li><strong>Baseline</strong>: the text baseline, a line on which the characters are placed.</li>
 * <li><strong>Max descent</strong>: the distance below the baseline for the lowest glyph across the font.</li>
 * </ul>
 * <p>
 * <strong>Important note:</strong> The font size should not be confused with the actual font height:
 * <ul>
 * <li>The font size specifies the height of the text bounding box, but some glyphs of the font may extend beyond the
 * box.</li>
 * <li>The actual font height is the distance between the line of maximum ascent and the line of maximum descent. All
 * the glyphs of the font will be fully enclosed between these two lines. The actual font height can be retrieved with
 * the method {@link #getHeight(float)}.</li>
 * </ul>
 *
 * <p>
 * <img src="doc-files/font_metrics.png" alt="Font metrics.">
 */
public class VectorFont implements Closeable {

	private VectorFont() {
	}

	/**
	 * Loads a vector font from a path using a simple text layout. Equivalent to calling
	 * <code>loadFont(resourcePath, false)</code>.
	 *
	 * @param resourcePath
	 *            the path to get the font from
	 * @return a vector font
	 * @throws VectorGraphicsException
	 *             if the font could not be loaded (see {@link VectorGraphicsException#getErrorCode()} for the error
	 *             cause)
	 */
	public static VectorFont loadFont(String resourcePath) {
		throw new VectorGraphicsException();
	}

	/**
	 * Loads a vector font from a path using the specified text layout(simple or complex).
	 *
	 * @param resourcePath
	 *            the path to get the font from
	 * @param complexText
	 *            if true the font layouter considers complex text layout features like contextual glyph substitution or
	 *            positioning.
	 *            <p>
	 *            Arabic and Thai scripts are examples of scripts that need complex text layout features.
	 *            <ul>
	 *            <li>Simple text layout uses the glyph advance metrics and the font kerning table.</li>
	 *            <li>Complex text layout uses the font GPOS and GSUB tables.</li>
	 *            </ul>
	 *            <p>
	 *            The vector font file should contain the tables needed by the selected text layout.
	 *
	 * @return a vector font
	 * @throws VectorGraphicsException
	 *             if the font could not be loaded or if complexText is true and no complex layouter is available(see
	 *             {@link VectorGraphicsException#getErrorCode()} for the error cause)
	 *
	 */
	public static VectorFont loadFont(String resourcePath, boolean complexText) {
		throw new VectorGraphicsException();
	}

	// /**
	// * Loads a vector font from an {@link InputStream}.
	// *
	// * @param stream
	// * the input stream providing the font data
	// * @param size
	// * the number of bytes to read from the input stream
	// * @return a vector font
	// * @throws VectorGraphicsException
	// * if the font could not be loaded (see {@link VectorGraphicsException#getErrorCode()} for the error
	// * cause)
	// */
	// public static VectorFont loadFont(InputStream stream, int size) {
	// throw new VectorGraphicsException();
	// }

	// /**
	// * Returns whether a font can be loaded from a resource.
	// * <p>
	// * This method may be used to know whether calling {@link VectorFont#loadFont(String)} with the given path would
	// be
	// * successful or not.
	// *
	// * @param path
	// * the resource path
	// * @return {@code true} if the font can be loaded, {@code false} otherwise
	// * @throws VectorGraphicsException
	// * if the path is not a valid path
	// */
	// public static boolean canLoadFont(String path) {
	// throw new VectorGraphicsException();
	// }

	/**
	 * Returns whether this font has been closed or not.
	 *
	 * @return {@code true} if the font has been closed, {@code false} otherwise
	 */
	public boolean isClosed() {
		throw new VectorGraphicsException();
	}

	/**
	 * Closes this font and its associated resources.
	 * <p>
	 * Calling this method on a font which has already been closed has no effect.
	 * <p>
	 * Beware that this method is not thread safe. Any concurrent use of this font to draw a string during the closing
	 * may result in a undefined behavior.
	 */
	@Override
	public void close() {
		throw new VectorGraphicsException();
	}

	/**
	 * Returns the height of this font, at given font size.
	 * <p>
	 * The returned value is the distance between the line of maximum ascent and the line of maximum descent (see
	 * {@link VectorFont}).
	 * <p>
	 * This method can be used to size a text area. Since all the glyphs of a font are located between these two lines,
	 * any text will fit in an area of that height when drawn with {@link VectorGraphicsPainter} methods. If, instead,
	 * you prefer to adjust the size of your area to be the exact size of a specific text, refer to the method
	 * {@link #measureStringHeight(String, float)}.
	 * <p>
	 * The specified font size must be positive. If it is less than or equal to 0, the method will return 0.
	 *
	 * @param size
	 *            the font size, in pixels
	 * @return the height of this font at given font size, in pixels
	 * @throws VectorGraphicsException
	 *             if the measure could not be obtained for any reason (see
	 *             {@link VectorGraphicsException#getErrorCode()})
	 * @see #measureStringHeight(String, float)
	 * @see VectorGraphicsPainter#drawString(ej.microui.display.GraphicsContext, String, VectorFont, float, float,
	 *      float)
	 */
	public float getHeight(float size) {
		throw new VectorGraphicsException();
	}

	/**
	 * Returns the position of the baseline for this font, at given font size.
	 * <p>
	 * The returned value is the distance between the line of maximum ascent and the baseline (see {@link VectorFont}).
	 * <p>
	 * The specified font size must be positive. If it is less than or equal to 0, the method will return 0.
	 *
	 * @param size
	 *            the font size, in pixels
	 * @return the baseline position of this font at given font size, in pixels
	 * @throws VectorGraphicsException
	 *             if the measure could not be obtained for any reason (see
	 *             {@link VectorGraphicsException#getErrorCode()})
	 */
	public float getBaselinePosition(float size) {
		throw new VectorGraphicsException();
	}

	/**
	 * Returns the width of a string when it is drawn with this font and the given size.
	 * <p>
	 * The returned value is the width of the smallest rectangle that encloses all the glyphs.
	 * <p>
	 * This method can be used to size a text area. The given text will fit perfectly in an area of that width when
	 * drawn with {@link VectorGraphicsPainter} methods.
	 * <p>
	 * Note that the measure includes the gaps between the glyphs (also known as side bearings). For this reason, the
	 * measurement for a given string is not equal to the sum of the measurements for each glyph of that string.
	 * <p>
	 * The specified font size must be positive. If it is less than or equal to 0, the method will return 0.
	 * <p>
	 * Equivalent to calling {@link #measureStringWidth(String, float, float)} with a letter spacing of 0.
	 *
	 * <p>
	 * <img src="doc-files/text-bounds.png" alt="Text bounds.">
	 *
	 * @param string
	 *            the string to measure
	 * @param size
	 *            the font size, in pixels
	 * @return the width of the specified string, in pixels
	 * @throws VectorGraphicsException
	 *             if the measure could not be obtained for any reason (see
	 *             {@link VectorGraphicsException#getErrorCode()})
	 * @see #measureStringWidth(String, float, float)
	 * @see VectorGraphicsPainter#drawString(ej.microui.display.GraphicsContext, String, VectorFont, float, float,
	 *      float)
	 */
	public float measureStringWidth(String string, float size) {
		throw new VectorGraphicsException();
	}

	/**
	 * Returns the width of a string when it is drawn with this font and the given size.
	 * <p>
	 * The returned value is the width of the smallest rectangle that encloses all the glyphs, taking into account the
	 * given extra letter spacing.
	 * <p>
	 * This method can be used to size a text area. The given text will fit perfectly in an area of that width when
	 * drawn with {@link VectorGraphicsPainter} methods.
	 * <p>
	 * Note that the measure includes the gaps between the glyphs (side bearings and extra letter spacing). For this
	 * reason, the measurement for a given string is not equal to the sum of the measurements for each glyph of that
	 * string.
	 * <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.
	 * <p>
	 * The specified font size must be positive. If it is less than or equal to 0, the method will return 0.
	 *
	 * <p>
	 * <img src="doc-files/text-bounds.png" alt="Text bounds.">
	 *
	 * @param string
	 *            the string to measure
	 * @param size
	 *            the font size, in pixels
	 * @param letterSpacing
	 *            the extra letter spacing to use, in pixels
	 * @return the width of the specified string, in pixels
	 * @throws VectorGraphicsException
	 *             if the measure could not be obtained for any reason (see
	 *             {@link VectorGraphicsException#getErrorCode()})
	 * @see #measureStringWidth(String, float)
	 * @see VectorGraphicsPainter#drawString(ej.microui.display.GraphicsContext, String, VectorFont, float, Matrix, int,
	 *      BlendMode, float)
	 */
	public float measureStringWidth(String string, float size, float letterSpacing) {
		throw new VectorGraphicsException();
	}

	/**
	 * Returns the height of a string when it is drawn with this font and the given size.
	 * <p>
	 * The returned value is the height of the smallest rectangle that encloses all the glyphs.
	 * <p>
	 * This method can be used to size a text area. The given text will fit perfectly in an area of that height when
	 * drawn with {@link VectorGraphicsPainter} methods. If, instead, you prefer to adjust the size of your area to fit
	 * any kind of text, refer to the method {@link #getHeight(float)}.
	 * <p>
	 * The specified font size must be positive. If it is less than or equal to 0, the method will return 0.
	 *
	 * <p>
	 * <img src="doc-files/text-bounds.png" alt="Text bounds.">
	 *
	 * @param string
	 *            the string to measure
	 * @param size
	 *            the font size, in pixels
	 * @return the height of the specified string, in pixels
	 * @throws VectorGraphicsException
	 *             if the measure could not be obtained for any reason (see
	 *             {@link VectorGraphicsException#getErrorCode()})
	 * @see #getHeight(float)
	 * @see VectorGraphicsPainter#drawString(ej.microui.display.GraphicsContext, String, VectorFont, float, float,
	 *      float)
	 */
	public float measureStringHeight(String string, float size) {
		throw new VectorGraphicsException();
	}

	/**
	 * Retrieves a fixed-sized font from this vector font.
	 * <p>
	 * Beware that using the resulting {@link Font} to draw a string while the {@link VectorFont} is being closed may
	 * result in a undefined behavior.
	 *
	 * @param size
	 *            the desired size
	 * @return the fixed-sized font
	 * @see Painter#drawString(ej.microui.display.GraphicsContext, String, Font, int, int)
	 */
	public Font getFont(int size) {
		throw new VectorGraphicsException();
	}

}
