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