package dev.photosync.mcapi;

import dev.photosync.core.capture.CameraPose;

import java.nio.file.Path;
import java.util.Optional;

/** The ambient client state PhotoSync has to consult, and the render thread. */
public interface GameContext {

    /** True once a world is loaded and being rendered. */
    boolean inWorld();

    /** True while any screen is up, vanilla's or ours. Automatic capture checks this. */
    boolean screenOpen();

    /**
     * Where the camera is and which way it faces, or empty when there is nothing
     * to be looking through -- the title screen, or a world that is still
     * loading.
     *
     * <p>Sampled every tick by the automatic-capture timer, which uses it to tell
     * an idle player apart from one who is actually somewhere new. Nothing else
     * needs it, and nothing should read a Minecraft position through it: it is
     * deliberately a snapshot of five numbers rather than a handle on an entity.
     */
    Optional<CameraPose> cameraPose();

    /**
     * The game-instance config directory (the {@code config/photosync} folder
     * inside the game directory), where PhotoSync historically keeps its
     * settings and upload queue. The settings file can be moved to
     * {@link #userDataDirectory()} from the settings screen; the upload queue
     * always stays here.
     */
    Path configDirectory();

    /**
     * The OS-user-level directory offered as the alternative home for the
     * settings file: {@code ~/.config/photosyncmod} on Linux and macOS,
     * {@code %APPDATA%\photosyncmod} on Windows. Only used once the player
     * chooses it; {@link #configDirectory()} stays the default.
     */
    Path userDataDirectory();

    /**
     * Runs a task on the render thread, or immediately if already on it.
     *
     * <p>Anything that touches a texture, a screen or the framebuffer has to go
     * through here, because everything that produces such work in this mod --
     * uploads, thumbnail fetches, the capture timer -- runs on a worker.
     */
    void submit(Runnable task);

    /**
     * Opens a file or folder in the desktop's file manager.
     *
     * <p>The queue screen offers this for a screenshot the player is looking at,
     * because the alternative to a working "show in folder" is explaining where
     * {@code .minecraft} lives.
     */
    void reveal(Path path);

    /** The running Minecraft version, for logs and the settings screen's footer. */
    String minecraftVersion();

    /**
     * The window title, which modpacks replace with their own name. Recorded
     * from {@code Window.setTitle} rather than reconstructed, because only the
     * window knows what some other mod put there.
     */
    String clientName();

    /**
     * The multiplayer server's address, or empty in single player and on the
     * title screen. Both the value and its absence are meaningful to the upload
     * description.
     */
    Optional<String> serverAddress();

    /**
     * Shuts the game down, having already opened {@code QuitGuard}'s gate.
     *
     * <p>This is how the quit dialog finishes what the player started once the
     * uploads are done or they have chosen not to wait.
     */
    void quit();
}
