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

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

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