package net.minecraft.world.level;

import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.chunk.EmptyLevelChunk;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.chunk.ChunkAccess;

public class PathNavigationRegion implements BlockGetter, CollisionGetter {
    protected final int centerX;
    protected final int centerZ;
    protected final ChunkAccess[][] chunks;
    protected boolean allEmpty;
    protected final Level level;
    
    public PathNavigationRegion(final Level bjw, final BlockPos fk2, final BlockPos fk3) {
        this.level = bjw;
        this.centerX = fk2.getX() >> 4;
        this.centerZ = fk2.getZ() >> 4;
        final int integer5 = fk3.getX() >> 4;
        final int integer6 = fk3.getZ() >> 4;
        this.chunks = new ChunkAccess[integer5 - this.centerX + 1][integer6 - this.centerZ + 1];
        final ChunkSource cad7 = bjw.getChunkSource();
        this.allEmpty = true;
        for (int integer7 = this.centerX; integer7 <= integer5; ++integer7) {
            for (int integer8 = this.centerZ; integer8 <= integer6; ++integer8) {
                this.chunks[integer7 - this.centerX][integer8 - this.centerZ] = cad7.getChunkNow(integer7, integer8);
            }
        }
        for (int integer7 = fk2.getX() >> 4; integer7 <= fk3.getX() >> 4; ++integer7) {
            for (int integer8 = fk2.getZ() >> 4; integer8 <= fk3.getZ() >> 4; ++integer8) {
                final ChunkAccess bzy10 = this.chunks[integer7 - this.centerX][integer8 - this.centerZ];
                if (bzy10 != null && !bzy10.isYSpaceEmpty(fk2.getY(), fk3.getY())) {
                    this.allEmpty = false;
                    return;
                }
            }
        }
    }
    
    private ChunkAccess getChunk(final BlockPos fk) {
        return this.getChunk(fk.getX() >> 4, fk.getZ() >> 4);
    }
    
    private ChunkAccess getChunk(final int integer1, final int integer2) {
        final int integer3 = integer1 - this.centerX;
        final int integer4 = integer2 - this.centerZ;
        if (integer3 < 0 || integer3 >= this.chunks.length || integer4 < 0 || integer4 >= this.chunks[integer3].length) {
            return new EmptyLevelChunk(this.level, new ChunkPos(integer1, integer2));
        }
        final ChunkAccess bzy6 = this.chunks[integer3][integer4];
        return (bzy6 != null) ? bzy6 : new EmptyLevelChunk(this.level, new ChunkPos(integer1, integer2));
    }
    
    @Override
    public WorldBorder getWorldBorder() {
        return this.level.getWorldBorder();
    }
    
    @Override
    public BlockGetter getChunkForCollisions(final int integer1, final int integer2) {
        return this.getChunk(integer1, integer2);
    }
    
    @Nullable
    @Override
    public BlockEntity getBlockEntity(final BlockPos fk) {
        final ChunkAccess bzy3 = this.getChunk(fk);
        return bzy3.getBlockEntity(fk);
    }
    
    @Override
    public BlockState getBlockState(final BlockPos fk) {
        if (Level.isOutsideBuildHeight(fk)) {
            return Blocks.AIR.defaultBlockState();
        }
        final ChunkAccess bzy3 = this.getChunk(fk);
        return bzy3.getBlockState(fk);
    }
    
    @Override
    public FluidState getFluidState(final BlockPos fk) {
        if (Level.isOutsideBuildHeight(fk)) {
            return Fluids.EMPTY.defaultFluidState();
        }
        final ChunkAccess bzy3 = this.getChunk(fk);
        return bzy3.getFluidState(fk);
    }
}
