/*
 * Java
 *
 * Copyright 2010-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.event.EventHandler;

/**
 * <code>Displayable</code> is an abstract class which defines the very objects that can be shown on the
 * <code>Display</code>.<br>
 * A <code>Displayable</code> may be shown or hidden, but at most one <code>Displayable</code> is shown on the
 * <code>Display</code>.<br>
 * <br>
 * Subclasses should define the <code>Displayable</code> contents and their possible interactions with the user.<br>
 * <br>
 * By default, a new <code>Displayable</code> object is not visible on the display.
 *
 * @see Display
 */
public abstract class Displayable implements EventHandler {

	/**
	 * Requests a rendering for the entire displayable. Calling this method may result in subsequent call to
	 * {@link #render(GraphicsContext)} on the displayable.
	 * <p>
	 * The call to {@link #render(GraphicsContext)} occurs asynchronously to this call. That is, this method will not
	 * block waiting for {@link #render(GraphicsContext)} to finish. After render action (after call to
	 * {@link #render(GraphicsContext)}), a call to {@link Display#flush()} is synchronously performed.
	 * <p>
	 * This call may have no effect under certain conditions:
	 * <ul>
	 * <li>if the displayable is not visible on the display (see {@link Display#isShown(Displayable)}): the request is
	 * refused.</li>
	 * <li>if the displayable is not visible on the display when the event is executed (a call to
	 * {@link Display#requestShow(Displayable)} has been performed with another displayable): the request is abandoned
	 * (this displayable is no longer the current displayable).</li>
	 * <li>if a request is already available in the events queue <b>and</b> if the request is called from the MicroUI
	 * pump: the request is useless because this request has been already added and cannot be executed until the end of
	 * current caller method. The request is not added into the queue.</li>
	 * </ul>
	 *
	 */
	public void requestRender() {
		throw new RuntimeException();
	}

	/**
	 * This method is called by system as soon as the displayable becomes visible. Application should override this
	 * method to control its own displayables. Default behavior does nothing.
	 *
	 * @see Display#requestShow(Displayable)
	 */
	protected void onShown() {
		throw new RuntimeException();
	}

	/**
	 * This method is called by system as soon as the displayable becomes hidden. Application should override this
	 * method to control its own displayables. Default behavior does nothing.
	 * 
	 * @see Display#requestHide(Displayable)
	 */
	protected void onHidden() {
		throw new RuntimeException();
	}

	/**
	 * Renders the displayable. This method is called by system as soon as the displayable has be rendered. Caller
	 * ensures the graphics context's clip and translate are reseted.
	 *
	 * @param gc
	 *            the graphics context of display.
	 */
	protected abstract void render(GraphicsContext gc);
}
