package net.minecraft.client.renderer.chunk;

import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.lighting.LevelLightEngine;
import java.util.Iterator;
import javax.annotation.Nullable;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;

public class RenderChunkRegion implements BlockAndTintGetter {
    protected final int centerX;
    protected final int centerZ;
    protected final BlockPos start;
    protected final int xLength;
    protected final int yLength;
    protected final int zLength;
    protected final LevelChunk[][] chunks;
    protected final BlockState[] blockStates;
    protected final FluidState[] fluidStates;
    protected final Level level;
    
    @Nullable
    public static RenderChunkRegion createIfNotEmpty(final Level bjw, final BlockPos fk2, final BlockPos fk3, final int integer) {
        final int integer2 = fk2.getX() - integer >> 4;
        final int integer3 = fk2.getZ() - integer >> 4;
        final int integer4 = fk3.getX() + integer >> 4;
        final int integer5 = fk3.getZ() + integer >> 4;
        final LevelChunk[][] arr9 = new LevelChunk[integer4 - integer2 + 1][integer5 - integer3 + 1];
        for (int integer6 = integer2; integer6 <= integer4; ++integer6) {
            for (int integer7 = integer3; integer7 <= integer5; ++integer7) {
                arr9[integer6 - integer2][integer7 - integer3] = bjw.getChunk(integer6, integer7);
            }
        }
        boolean boolean10 = true;
        for (int integer7 = fk2.getX() >> 4; integer7 <= fk3.getX() >> 4; ++integer7) {
            for (int integer8 = fk2.getZ() >> 4; integer8 <= fk3.getZ() >> 4; ++integer8) {
                final LevelChunk cal13 = arr9[integer7 - integer2][integer8 - integer3];
                if (!cal13.isYSpaceEmpty(fk2.getY(), fk3.getY())) {
                    boolean10 = false;
                }
            }
        }
        if (boolean10) {
            return null;
        }
        int integer7 = 1;
        final BlockPos fk4 = fk2.offset(-1, -1, -1);
        final BlockPos fk5 = fk3.offset(1, 1, 1);
        return new RenderChunkRegion(bjw, integer2, integer3, arr9, fk4, fk5);
    }
    
    public RenderChunkRegion(final Level bjw, final int integer2, final int integer3, final LevelChunk[][] arr, final BlockPos fk5, final BlockPos fk6) {
        this.level = bjw;
        this.centerX = integer2;
        this.centerZ = integer3;
        this.chunks = arr;
        this.start = fk5;
        this.xLength = fk6.getX() - fk5.getX() + 1;
        this.yLength = fk6.getY() - fk5.getY() + 1;
        this.zLength = fk6.getZ() - fk5.getZ() + 1;
        this.blockStates = new BlockState[this.xLength * this.yLength * this.zLength];
        this.fluidStates = new FluidState[this.xLength * this.yLength * this.zLength];
        for (final BlockPos fk7 : BlockPos.betweenClosed(fk5, fk6)) {
            final int integer4 = (fk7.getX() >> 4) - integer2;
            final int integer5 = (fk7.getZ() >> 4) - integer3;
            final LevelChunk cal12 = arr[integer4][integer5];
            final int integer6 = this.index(fk7);
            this.blockStates[integer6] = cal12.getBlockState(fk7);
            this.fluidStates[integer6] = cal12.getFluidState(fk7);
        }
    }
    
    protected final int index(final BlockPos fk) {
        return this.index(fk.getX(), fk.getY(), fk.getZ());
    }
    
    protected int index(final int integer1, final int integer2, final int integer3) {
        final int integer4 = integer1 - this.start.getX();
        final int integer5 = integer2 - this.start.getY();
        final int integer6 = integer3 - this.start.getZ();
        return integer6 * this.xLength * this.yLength + integer5 * this.xLength + integer4;
    }
    
    @Override
    public BlockState getBlockState(final BlockPos fk) {
        return this.blockStates[this.index(fk)];
    }
    
    @Override
    public FluidState getFluidState(final BlockPos fk) {
        return this.fluidStates[this.index(fk)];
    }
    
    @Override
    public LevelLightEngine getLightEngine() {
        return this.level.getLightEngine();
    }
    
    @Nullable
    @Override
    public BlockEntity getBlockEntity(final BlockPos fk) {
        return this.getBlockEntity(fk, LevelChunk.EntityCreationType.IMMEDIATE);
    }
    
    @Nullable
    public BlockEntity getBlockEntity(final BlockPos fk, final LevelChunk.EntityCreationType a) {
        final int integer4 = (fk.getX() >> 4) - this.centerX;
        final int integer5 = (fk.getZ() >> 4) - this.centerZ;
        return this.chunks[integer4][integer5].getBlockEntity(fk, a);
    }
    
    @Override
    public int getBlockTint(final BlockPos fk, final ColorResolver colorResolver) {
        return this.level.getBlockTint(fk, colorResolver);
    }
}
