/*
 * 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.
 * 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 java.io.Closeable;
import java.io.InputStream;

import ej.annotation.Nullable;
import ej.microui.MicroUIException;

/**
 * A <code>ResourceImage</code> represents an image which may require dynamic allocation in order to be created.
 * <p>
 * A resource image should be closed in order to free the dynamic allocation used to store the image pixels.
 * <p>
 * This class provides statics method in order to load an image from a resource or from a given input stream.
 */
public class ResourceImage extends Image implements Closeable {

	/**
	 * Enumerates the different formats in which a resource image can store pixel colors.
	 *
	 * @see #loadImage(String, OutputFormat)
	 * @see #loadImage(InputStream, int, OutputFormat)
	 * @since 2.0
	 */
	public enum OutputFormat {

		/**
		 * Represents pixel colors on 32 bits: 8 bits for alpha, 8 bits for red, 8 bits for green and 8 bits for blue.
		 */
		ARGB8888,

		/**
		 * Represents pixel colors on 24 bits: 0 bit for alpha, 8 bits for red, 8 bits for green and 8 bits for blue.
		 */
		RGB888,

		/**
		 * Represents pixel colors on 16 bits: 0 bit for alpha, 5 bits for red, 6 bits for green and 5 bits for blue.
		 */
		RGB565,

		/**
		 * Represents pixel colors on 16 bits: 1 bit for alpha, 5 bits for red, 5 bits for green and 5 bits for blue.
		 */
		ARGB1555,

		/**
		 * Represents pixel colors on 16 bits: 4 bit for alpha, 4 bits for red, 4 bits for green and 4 bits for blue.
		 */
		ARGB4444,

		/**
		 * Represents pixel colors on 8 bits: 8 bit for alpha, 0 bits for red, 0 bits for green and 0 bits for blue.
		 */
		A8;

		/**
		 * Returns the SNI context data of this format.
		 * <p>
		 * The SNI context can be used to call a native method with SNI. This allows to identify the format in the
		 * native world.
		 * <p>
		 * The data format is implementation specific.
		 *
		 * @return the SNI context of this format.
		 */
		public byte getSNIContext() {
			throw new RuntimeException();
		}

	}

	/**
	 * Forbidden constructor: call one of the <code>loadImage</code> methods to get an instance of
	 * {@link ResourceImage}.
	 */
	/* default */ ResourceImage() {
	}

	/**
	 * Returns whether an image can be loaded from a resource.
	 * <p>
	 * This method may be used to know whether calling {@link ResourceImage#loadImage(String)} with the given path would
	 * be successful or not.
	 *
	 * @param path
	 *            the resource path.
	 * @return <code>true</code> if the image can be loaded, <code>false</code> otherwise.
	 * @throws MicroUIException
	 *             if the resource path doesn't start with "/".
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 * @throws SecurityException
	 *             if a security manager exists and does not allow the caller to load an image.
	 * @see #loadImage(String)
	 * @since 3.0
	 */
	public static boolean canLoadImage(String path) {
		throw new RuntimeException();
	}

	/**
	 * Loads an immutable image from a resource.
	 * <p>
	 * This method can load images which are in the internal image format defined by the MicroUI implementation, and
	 * images which are in standard image formats (such as PNG), depending on the capabilities of the MicroUI
	 * implementation (such as having a PNG decoder).
	 * <p>
	 * The MicroUI implementation is responsible for retrieving the correct image load/decoder in order to load the
	 * image.
	 * <p>
	 * The output format of the returned image is the best format for the input format. For example, the output format
	 * for PNG images is {@link OutputFormat#ARGB8888}. The output format for images in internal MicroUI image format is
	 * the output format specified in the <code>images.list</code> file.
	 * <p>
	 * Calling this method is equivalent to calling <code>loadImage(name, null)</code>.
	 *
	 * @param path
	 *            the resource path.
	 * @return the loaded image.
	 * @throws MicroUIException
	 *             if the image could not be loaded for any reason (see {@link MicroUIException#getErrorCode()}).
	 * @throws MicroUIException
	 *             if the resource path doesn't start with "/".
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 * @throws SecurityException
	 *             if a security manager exists and does not allow the caller to load an image.
	 * @since 2.0
	 */
	public static ResourceImage loadImage(String path) {
		throw new RuntimeException();
	}

	/**
	 * Loads an immutable image from a resource.
	 * <p>
	 * This method can load images which are in the internal image format defined by the MicroUI implementation, and
	 * images which are in standard image formats (such as PNG), depending on the capabilities of the MicroUI
	 * implementation (such as having a PNG decoder).
	 * <p>
	 * The MicroUI implementation is responsible for retrieving the correct image load/decoder in order to load the
	 * image.
	 * <p>
	 * The output format of the image is the output format given as parameter. This format may be different from the
	 * default output format (@see {@link #loadImage(String)}).
	 *
	 * @param path
	 *            the resource path.
	 * @param format
	 *            the desired output format, or <code>null</code> to use the default output format.
	 * @return the loaded image.
	 * @throws MicroUIException
	 *             if the image could not be loaded for any reason (see {@link MicroUIException#getErrorCode()}).
	 * @throws MicroUIException
	 *             if the resource path doesn't start with "/".
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 * @throws SecurityException
	 *             if a security manager exists and does not allow the caller to load an image.
	 * @since 2.0
	 */
	public static ResourceImage loadImage(String path, @Nullable OutputFormat format) {
		throw new RuntimeException();
	}

	/**
	 * Loads an immutable image from an {@link InputStream}.
	 * <p>
	 * Refer to {@link #loadImage(String)} for more information.
	 * <p>
	 * Calling this method is equivalent to calling <code>loadImage(stream, size, null)</code>.
	 *
	 * @param stream
	 *            the input stream providing the image data.
	 * @param size
	 *            the number of bytes to read from the input stream.
	 * @return the loaded image.
	 * @throws MicroUIException
	 *             if the image could not be loaded for any reason (see {@link MicroUIException#getErrorCode()}).
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 * @throws SecurityException
	 *             if a security manager exists and does not allow the caller to load an image.
	 * @since 2.0
	 */
	public static ResourceImage loadImage(InputStream stream, int size) {
		throw new RuntimeException();
	}

	/**
	 * Loads an immutable image from an {@link InputStream}.
	 * <p>
	 * Refer to {@link #loadImage(String, OutputFormat)} for more information.
	 *
	 * @param stream
	 *            the input stream providing the image data.
	 * @param size
	 *            the number of bytes to read from the input stream.
	 * @param format
	 *            the desired output format, or <code>null</code> to use the default output format.
	 * @return the loaded image.
	 * @throws MicroUIException
	 *             if the image could not be loaded for any reason (see {@link MicroUIException#getErrorCode()}).
	 * @throws MicroUIException
	 *             if MicroUI is not started.
	 * @throws SecurityException
	 *             if a security manager exists and does not allow the caller to load an image.
	 * @since 2.0
	 */
	public static ResourceImage loadImage(InputStream stream, int size, @Nullable OutputFormat format) {
		throw new RuntimeException();
	}

	/**
	 * Returns whether this image has been closed.
	 *
	 * @return <code>true</code> if the image has been closed, <code>false</code> otherwise.
	 */
	public boolean isClosed() {
		throw new RuntimeException();
	}

	/**
	 * Closes this image and its associated resources.
	 * <p>
	 * Calling this method on an image which has already been closed has no effect.
	 */
	@Override
	public void close() {
		throw new RuntimeException();
	}

}
