/*
 * Copyright 2015-2023 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.widget.basic;

import ej.annotation.Nullable;
import ej.microui.display.GraphicsContext;
import ej.microui.display.ResourceImage;
import ej.mwt.Widget;
import ej.mwt.style.Style;
import ej.mwt.util.Size;
import ej.widget.render.ImagePainter;

/**
 * A widget that displays a resource image.
 * <p>
 * The widget holds a path to the image. The actual image is allocated only when the widget is attached. It is also
 * closed when the widget is detached.
 */
public class ImageWidget extends Widget {

	private String imagePath;

	@Nullable
	private ResourceImage image;

	/**
	 * Creates an image widget with the resource path of the image to display.
	 *
	 * @param imagePath
	 *            the resource path of the image to display.
	 * @throws IllegalArgumentException
	 *             if the image cannot be loaded.
	 * @see ResourceImage#canLoadImage(String)
	 */
	public ImageWidget(String imagePath) {
		checkImage(imagePath);
		this.imagePath = imagePath;
	}

	/**
	 * Creates an image widget with the resource path of the image to display and its enabled state.
	 *
	 * @param imagePath
	 *            the resource path of the image to display.
	 * @param enabled
	 *            <code>true</code> if this image widget is to be enabled, <code>false</code> otherwise.
	 * @throws IllegalArgumentException
	 *             if the image cannot be loaded.
	 * @see ResourceImage#canLoadImage(String)
	 */
	protected ImageWidget(String imagePath, boolean enabled) {
		super(enabled);
		checkImage(imagePath);
		this.imagePath = imagePath;
	}

	@Override
	protected void onAttached() {
		super.onAttached();

		loadImage();
	}

	@Override
	protected void onDetached() {
		super.onDetached();

		closeImage();
	}

	private void loadImage() {
		this.image = ResourceImage.loadImage(this.imagePath);
	}

	private void closeImage() {
		ResourceImage image = this.image;
		if (image != null) {
			image.close();
			this.image = null;
		}
	}

	/**
	 * Sets the image path.
	 *
	 * @param imagePath
	 *            the resource path of the image to display.
	 * @throws IllegalArgumentException
	 *             if the image cannot be loaded.
	 * @see ResourceImage#canLoadImage(String)
	 */
	public void setImagePath(String imagePath) {
		checkImage(imagePath);
		this.imagePath = imagePath;
		if (isAttached()) {
			closeImage();
			loadImage();
		}
	}

	@Override
	protected void renderContent(GraphicsContext g, int contentWidth, int contentHeight) {
		ResourceImage image = this.image;
		if (image != null) {
			Style style = getStyle();
			g.setColor(style.getColor());
			ImagePainter.drawImageInArea(g, image, 0, 0, contentWidth, contentHeight, style.getHorizontalAlignment(),
					style.getVerticalAlignment());
		}
	}

	@Override
	protected void computeContentOptimalSize(Size size) {
		ResourceImage image = this.image;
		if (image != null) {
			ImagePainter.computeOptimalSize(image, size);
		} else {
			size.setSize(0, 0);
		}
	}

	private static void checkImage(String imagePath) {
		if (!ResourceImage.canLoadImage(imagePath)) {
			throw new IllegalArgumentException();
		}
	}
}
