package dev.photosync.platform.impl;

import dev.photosync.mcapi.render.RenderBridge;
import dev.photosync.mcapi.render.TextureHandle;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;

/**
 * The eleven drawing primitives, on top of {@link GuiGraphics}.
 *
 * <p>One of these is built per frame and thrown away; it holds the frame's
 * {@code GuiGraphics}, which is not valid outside the render call that produced
 * it. Coordinates are GUI-space, matching vanilla's, so nothing here scales.
 */
public final class RenderAdapter implements RenderBridge {

    private final GuiGraphics graphics;
    private final Font font;
    private final int width;
    private final int height;
    private final float tickDelta;

    public RenderAdapter(GuiGraphics graphics, int width, int height, float tickDelta) {
        this.graphics = graphics;
        this.font = Minecraft.getInstance().font;
        this.width = width;
        this.height = height;
        this.tickDelta = tickDelta;
    }

    @Override
    public int width() {
        return width;
    }

    @Override
    public int height() {
        return height;
    }

    @Override
    public float tickDelta() {
        return tickDelta;
    }

    @Override
    public void fill(int x, int y, int width, int height, int argb) {
        graphics.fill(x, y, x + width, y + height, argb);
    }

    @Override
    public void gradient(int x, int y, int width, int height, int topArgb, int bottomArgb) {
        graphics.fillGradient(x, y, x + width, y + height, topArgb, bottomArgb);
    }

    @Override
    public void border(int x, int y, int width, int height, int argb) {
        graphics.fill(x, y, x + width, y + 1, argb);
        graphics.fill(x, y + height - 1, x + width, y + height, argb);
        graphics.fill(x, y + 1, x + 1, y + height - 1, argb);
        graphics.fill(x + width - 1, y + 1, x + width, y + height - 1, argb);
    }

    @Override
    public void text(String text, int x, int y, int argb, boolean shadow) {
        graphics.drawString(font, text, x, y, argb, shadow);
    }

    @Override
    public int textWidth(String text) {
        return font.width(text);
    }

    @Override
    public int lineHeight() {
        return font.lineHeight;
    }

    @Override
    public void image(TextureHandle texture, int x, int y, int width, int height) {
        image(texture, x, y, width, height, 0f, 0f, 1f, 1f);
    }

    /**
     * This release's {@code blit} takes UVs in texels, not the 0..1 the bridge
     * speaks, so the handle's own dimensions do the conversion. Later releases
     * grew a normalised overload; see docs/PORTING.md.
     */
    @Override
    public void image(TextureHandle texture, int x, int y, int width, int height,
                      float u0, float v0, float u1, float v1) {
        TextureAdapter.Handle handle = (TextureAdapter.Handle) texture;
        int textureWidth = handle.width();
        int textureHeight = handle.height();
        graphics.blit(
                handle.id(),
                x, y, width, height,
                u0 * textureWidth, v0 * textureHeight,
                Math.max(1, Math.round((u1 - u0) * textureWidth)),
                Math.max(1, Math.round((v1 - v0) * textureHeight)),
                textureWidth, textureHeight);
    }

    @Override
    public void pushClip(int x, int y, int width, int height) {
        graphics.enableScissor(x, y, x + width, y + height);
    }

    @Override
    public void popClip() {
        graphics.disableScissor();
    }
}
