package net.Chipperfluff.chipi.world.gen;

import net.minecraft.block.BlockState;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;

public final class DungeonContext {

    public static final DungeonContext EMPTY = new DungeonContext();

    private Integer grid_x;
    private Integer grid_y;
    private BlockPos structure_origin; // logical center
    private ChipiStructure structure;
    private ServerWorld world;

    private DungeonContext() {}

    private DungeonContext(ServerWorld world, Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) {
        this.world = world;
        this.grid_x = grid_x;
        this.grid_y = grid_y;
        this.structure_origin = structure_origin;
        this.structure = structure;
    }

    public static DungeonContext of(ServerWorld world, Integer grid_x, Integer grid_y, BlockPos structure_origin, ChipiStructure structure) {
        return new DungeonContext(world, grid_x, grid_y, structure_origin, structure);
    }

    public ServerWorld getWorld() {
        return world;
    }

    public Integer getGridX() {
        return grid_x;
    }

    public Integer getGridY() {
        return grid_y;
    }

    public ChipiStructure getStructure() {
        return structure;
    }

    public BlockPos getStructureOrigin() {
        return structure_origin;
    }

    public void setBlock(BlockPos localPos, BlockState state) {
        BlockPos worldPos = structure.localToWorld(structure_origin, localPos);
        System.out.println("[CHIPI] setBlock grid=(" + grid_x + "," + grid_y + ") worldPos=" + worldPos);
        world.setBlockState(worldPos, state, 3);
    }

    public void fillBlocks(BlockPos from, BlockPos to, BlockState state) {
        BlockPos start = structure.localToWorld(structure_origin, from);
        BlockPos end = structure.localToWorld(structure_origin, to);
        System.out.println("[CHIPI] fillBlocks grid=(" + grid_x + "," + grid_y + ") from=" + start + " to=" + end);
        BlockPos.stream(start, end).forEach(pos -> world.setBlockState(pos, state, 3));
    }
}
