/*
 * Java
 *
 * Copyright 2008-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.
 * This document has been released and published by E-S-R consortium, a non-profit entity.
 * To learn more about E-S-R consortium, please visit http://www.e-s-r.net/.
 * The matter contained in this document is not subject to copyright; you are free to use it for any purpose, for more information see E-S-R consortium policies.
 */
package ej.microui.display;

import ej.microui.MicroUIException;

/**
 * A <code>Font</code> defines how characters are drawn on a {@link GraphicsContext}.
 * <p>
 * A font has a set of identifiers. An identifier is an integer which specifies whether the font is able to render
 * specific languages and alphabets. A value has been assigned to the built-in identifiers: see {@link FontIdentifiers}.
 * Custom identifiers may be defined in order to identify or find a specific font. For example, a font which contains
 * some special characters like arrows or emojis can be tagged by the font creator with a specific identifier.
 * <p>
 * A font has a style, which is a combination of the following style constants: <code>STYLE_PLAIN</code>,
 * <code>STYLE_BOLD</code> and <code>SYTLE_ITALIC</code>.
 * <p>
 * A font has a descriptor, which is a string describing the font.
 * <p>
 * Fonts can not be created by applications and are rather retrieved from the implementation environment. An application
 * can get the list of all the fonts, the default font or a font with a specific path.
 */
public abstract class Font {

	/**
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public static final int STYLE_PLAIN = 0x0;

	/**
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public static final int STYLE_BOLD = 0x1;

	/**
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public static final int STYLE_ITALIC = 0x2;

	/**
	 * Returns an array containing all the fonts of the system.
	 *
	 * @return an array containing all the fonts.
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 */
	public static Font[] getAllFonts() {
		throw new RuntimeException();
	}

	/**
	 * Returns the default font of the system.
	 *
	 * @return the default font.
	 * @throws MicroUIException
	 *             if no font is declared in the system.
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 */
	public static Font getDefaultFont() {
		throw new RuntimeException();
	}

	/**
	 * Returns the font matching a given path.
	 *
	 * @param path
	 *            the path of the desired font.
	 * @return the font matching the given path.
	 * @throws MicroUIException
	 *             if the resource path does not start with "/".
	 * @throws MicroUIException
	 *             if no font matches the given path.
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 */
	public static Font getFont(String path) {
		throw new RuntimeException();
	}

	/**
	 * Creates a font.
	 * <p>
	 * The format must be a custom font format, a value between {@link Format#CUSTOM_0} and {@link Format#CUSTOM_7}.
	 * <p>
	 * The given byte array is used to identify and to use a font in the native world.
	 *
	 * @param format
	 *            the custom font format
	 * @param fontData
	 *            the data of this font
	 * @throws IllegalArgumentException
	 *             if the format is not a custom format.
	 */
	protected Font(Format format, byte[] fontData) {
		throw new RuntimeException();
	}

	/**
	 * Returns the width of a character when it is drawn using this font.
	 * <p>
	 * The width is the horizontal space that would be occupied if the given character were drawn using this font. It
	 * also includes the horizontal space that would be added after the character to separate it appropriately from the
	 * following characters.
	 * <p>
	 * This method only supports characters in the range U+0000 to U+FFFF. It does not handle characters with code
	 * points greater than U+FFFF, which are represented as a pair of char values (referred to as "surrogate pair").
	 *
	 * @param character
	 *            the character to measure.
	 * @return the width of the given character.
	 */
	public int charWidth(char character) {
		throw new RuntimeException();
	}

	/**
	 * Returns the width of a string when it is drawn using this font.
	 * <p>
	 * The width is the horizontal space that would be occupied if the given string were drawn using this font. It also
	 * includes the horizontal space between the characters of the string to separate them appropriately.
	 *
	 * @param string
	 *            the string to measure.
	 * @return the width of the given string.
	 */
	public int stringWidth(String string) {
		throw new RuntimeException();
	}

	/**
	 * Returns the width of a part of a string when it is drawn using this font.
	 * <p>
	 * The width is the horizontal space that would be occupied if the given substring were drawn using this font. It
	 * also includes the horizontal space between the characters of the substring to separate them appropriately.
	 *
	 * @param string
	 *            the string containing the substring to measure.
	 * @param offset
	 *            the index of the first character in the substring to measure.
	 * @param length
	 *            the number of characters to measure.
	 * @return the width of the given substring.
	 * @throws StringIndexOutOfBoundsException
	 *             if the given offset and length are out of the string bounds.
	 */
	public int substringWidth(String string, int offset, int length) {
		throw new RuntimeException();
	}

	/**
	 * Returns the height of a line of text when it is drawn using this font.
	 * <p>
	 * The height includes the size of the font as well as sufficient spacing below the line of text to separate it
	 * appropriately from the following lines.
	 *
	 * @return height of a line of text with this font.
	 */
	public abstract int getHeight();

	/**
	 * Returns the vertical distance in pixels between the top of this font and its baseline.
	 *
	 * @return the baseline of this font.
	 */
	public abstract int getBaselinePosition();

	/**
	 * Computes the width of the given char array.
	 *
	 * @param chars
	 *            the char array
	 * @param offset
	 *            the starting offset
	 * @param length
	 *            the length
	 * @return the width of the given char array
	 * @see #charWidth(char)
	 * @see #stringWidth(String)
	 * @see #substringWidth(String, int, int)
	 */
	protected int charsWidth(char[] chars, int offset, int length) {
		throw new RuntimeException();
	}

	/**
	 * Draws a char array with this font at a position.
	 * <p>
	 * The translation of the graphics context is already applied to the given x and y.
	 *
	 * @param gc
	 *            the graphics context to draw on
	 * @param chars
	 *            the char array
	 * @param offset
	 *            the starting offset
	 * @param length
	 *            the length
	 * @param x
	 *            the x coordinate to draw at
	 * @param y
	 *            the y coordinate to draw at
	 * @see Painter#drawString(GraphicsContext, String, Font, int, int)
	 * @see Painter#drawSubstring(GraphicsContext, String, int, int, Font, int, int)
	 */
	protected void drawChars(GraphicsContext gc, char[] chars, int offset, int length, int x, int y) {
		throw new RuntimeException();
	}

	/**
	 * Allocates a byte array useful to speed-up the rendering of the renderable string.
	 * <p>
	 * The type and content of this array is specific to each subclass of Font. It can be retrieved by a call to
	 * {@link RenderableString#getSNIContext()}.
	 * <p>
	 * It should be passed as an argument to the implementation of
	 * {@link Painter#drawRenderableString(GraphicsContext, RenderableString, int, int)}.
	 * <p>
	 * Returns an empty array by default.
	 *
	 * @param chars
	 *            the char array of the renderable string
	 * @param offset
	 *            the starting offset in the char array
	 * @param length
	 *            the length of the renderable string
	 * @return the object associated to the renderable string
	 */
	protected byte[] allocateRenderableStringSNIContext(char[] chars, int offset, int length) {
		throw new RuntimeException();
	}

	/**
	 * Returns an array containing all the identifiers supported by this font.
	 * <p>
	 * An identifier can be either one of the identifier constants specified in this class or an specific identifier
	 * value defined by the MicroUI implementation.
	 *
	 * @return an array containing all the identifier supported by this font.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public int[] getIdentifiers() {
		throw new RuntimeException();
	}

	/**
	 * Returns whether this font supports the given identifier.
	 *
	 * @param identifier
	 *            the identifier to check.
	 * @return <code>true</code> if this font supports the given identifier, <code>false</code> otherwise.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public boolean isIdentifierSupported(int identifier) {
		throw new RuntimeException();
	}

	/**
	 * Returns the style of this font.
	 * <p>
	 * The returned value is a combination of the following style constants: <code>STYLE_PLAIN</code>,
	 * <code>STYLE_BOLD</code> and <code>SYTLE_ITALIC</code>.
	 *
	 * @return the style of this font.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public int getStyle() {
		throw new RuntimeException();
	}

	/**
	 * Returns the descriptor of this font.
	 * <p>
	 * This method returns an empty string if this font does not have a descriptor.
	 *
	 * @return the descriptor of this font.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public String getDescriptor() {
		throw new RuntimeException();
	}

	/**
	 * Returns whether this font is plain.
	 *
	 * @return <code>true</code> if this font is plain, <code>false</code> otherwise.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public boolean isPlain() {
		throw new RuntimeException();
	}

	/**
	 * Returns whether this font is bold.
	 *
	 * @return <code>true</code> if this font is bold, <code>false</code> otherwise.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public boolean isBold() {
		throw new RuntimeException();
	}

	/**
	 * Returns whether this font is italic.
	 *
	 * @return <code>true</code> if this font is italic, <code>false</code> otherwise.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public boolean isItalic() {
		throw new RuntimeException();
	}

	/**
	 * Returns whether this font is monospaced.
	 * <p>
	 * A monospaced font is a font in which every character has the same width.
	 *
	 * @return <code>true</code> if this font is monospaced, <code>false</code> otherwise.
	 * @deprecated only available in for fonts retrieved with {@link #getDefaultFont()}, {@link #getFont(String)} or
	 *             {@link #getAllFonts()}.
	 */
	@Deprecated
	public boolean isMonospaced() {
		throw new RuntimeException();
	}

	/**
	 * Returns the SNI context data of this font.
	 * <p>
	 * The SNI context can be used to call a native method with SNI. This allows to identify and to use a font in the
	 * native world.
	 * <p>
	 * The data format is implementation specific.
	 * <p>
	 * Implementors can throw a {@link MicroUIException} with {@link MicroUIException#RESOURCE_CLOSED} error code when
	 * the font has been closed. It allows to catch the error in Java instead of having an unspecified behavior in the
	 * native world while drawing a resource that no longer exist.
	 *
	 * @return the SNI context of this font.
	 */
	public byte[] getSNIContext() {
		throw new RuntimeException();
	}

}
