////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////

package pp.dialog;

import com.simsilica.lemur.Container;

/**
 * Represents a dialog within a dialog manager system.
 * Extends the Container class from the Lemur GUI library.
 */
public class Dialog extends Container {
    /**
     * The depth of the dialog within the dialog stack.
     * Dialogs with lower depth values are considered to be "on top" of dialogs with higher values.
     */
    protected final int depth;

    /**
     * The manager responsible for handling this dialog.
     */
    protected final DialogManager manager;

    /**
     * Constructs a new Dialog with a depth automatically assigned by the DialogManager.
     *
     * @param manager The DialogManager that manages this dialog.
     */
    public Dialog(DialogManager manager) {
        this(manager, manager.nextDepth());
    }

    /**
     * Constructs a new Dialog with the specified depth.
     *
     * @param manager The DialogManager that manages this dialog.
     * @param depth   The depth of this dialog within the dialog stack.
     * @throws IllegalArgumentException if the specified depth is invalid (i.e., it is not greater than the depth of the top dialog in the manager's stack).
     */
    public Dialog(DialogManager manager, int depth) {
        this.manager = manager;
        this.depth = depth;
        // Ensure the dialog depth is greater than the depth of the current top dialog in the stack
        if (!manager.getDialogStack().isEmpty() && manager.getDialogStack().getLast().depth >= depth)
            throw new IllegalArgumentException("Invalid dialog depth " + depth);
    }

    /**
     * Checks if this dialog is the topmost dialog in the dialog stack.
     *
     * @return true if this dialog is the topmost dialog, false otherwise.
     */
    public boolean isTopDialog() {
        return manager.isTop(this);
    }

    /**
     * Runs the specified runnable if this dialog is the topmost dialog in the dialog stack.
     *
     * @param runnable the runnable.
     * @see Dialog#isTopDialog()
     */
    public void ifTopDialog(Runnable runnable) {
        if (isTopDialog()) runnable.run();
    }

    /**
     * Opens this dialog, centers it, and notifies the DialogManager to manage it.
     */
    public void open() {
        manager.centering(this, depth);
        manager.open(this);
    }

    /**
     * Closes this dialog and notifies the DialogManager to stop managing it.
     */
    public void close() {
        manager.close(this);
    }

    /**
     * This method is called whenever the {@linkplain pp.dialog.DialogManager} would
     * like to update this dialog.
     */
    public void update() { /* empty */ }

    /**
     * This method is called by {@linkplain DialogManager#update(float)} for periodically
     * updating this dialog. The default implementation does nothing.
     */
    public void update(float delta) { /* empty */ }

    /**
     * This method calls the escape action if this dialog is the top dialog.
     */
    public void escape() { /* empty */ }
}
