package dev.photosync.platform.impl;

import dev.photosync.mcapi.screen.ScreenModel;
import lombok.Getter;
import lombok.experimental.Accessors;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;

/**
 * The one vanilla {@link Screen} this mod owns; every PhotoSync screen is a
 * {@link ScreenModel} wearing it.
 *
 * <p>Nothing is delegated to {@code super} except key handling, which is where
 * Escape lives. In particular vanilla's {@code renderBackground} is not called:
 * the model draws its own scrim and panel, and vanilla's would paint over the
 * world underneath at the wrong moment.
 */
public final class ModelScreen extends Screen {

    @Getter
    @Accessors(fluent = true)
    private final ScreenModel model;

    ModelScreen(ScreenModel model) {
        super(Component.literal(model.title()));
        this.model = model;
    }

    @Override
    protected void init() {
        model.layout(width, height);
    }

    @Override
    public void tick() {
        model.tick();
    }

    @Override
    public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
        model.render(new RenderAdapter(graphics, width, height, partialTick), mouseX, mouseY);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        return model.mouseClicked(mouseX, mouseY, button) || super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public boolean mouseReleased(double mouseX, double mouseY, int button) {
        return model.mouseReleased(mouseX, mouseY, button) || super.mouseReleased(mouseX, mouseY, button);
    }

    @Override
    public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
        return model.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
                || super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
    }

    /**
     * 1.20.2 split scrolling into two axes. The bridge only has one, because a
     * horizontal wheel is not something any PhotoSync screen reacts to, so the
     * vertical delta is the one that gets through.
     */
    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
        return model.mouseScrolled(mouseX, mouseY, scrollY)
                || super.mouseScrolled(mouseX, mouseY, scrollX, scrollY);
    }

    @Override
    public boolean keyPressed(int key, int scanCode, int modifiers) {
        return model.keyPressed(key, scanCode, modifiers) || super.keyPressed(key, scanCode, modifiers);
    }

    @Override
    public boolean charTyped(char character, int modifiers) {
        return model.charTyped(character, modifiers) || super.charTyped(character, modifiers);
    }

    @Override
    public boolean isPauseScreen() {
        return model.pausesGame();
    }

    @Override
    public boolean shouldCloseOnEsc() {
        return model.closeOnEscape();
    }

    @Override
    public void removed() {
        model.closed();
    }
}
