package net.minecraft.world.level.levelgen.structure.templatesystem;

import java.util.Collections;
import net.minecraft.core.Vec3i;
import net.minecraft.util.Mth;
import net.minecraft.Util;
import java.util.Collection;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Random;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import javax.annotation.Nullable;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.Mirror;

public class StructurePlaceSettings {
    private Mirror mirror;
    private Rotation rotation;
    private BlockPos rotationPivot;
    private boolean ignoreEntities;
    @Nullable
    private ChunkPos chunkPos;
    @Nullable
    private BoundingBox boundingBox;
    private boolean keepLiquids;
    @Nullable
    private Random random;
    @Nullable
    private int palette;
    private final List<StructureProcessor> processors;
    private boolean knownShape;
    
    public StructurePlaceSettings() {
        this.mirror = Mirror.NONE;
        this.rotation = Rotation.NONE;
        this.rotationPivot = BlockPos.ZERO;
        this.keepLiquids = true;
        this.processors = Lists.newArrayList();
    }
    
    public StructurePlaceSettings copy() {
        final StructurePlaceSettings cmp2 = new StructurePlaceSettings();
        cmp2.mirror = this.mirror;
        cmp2.rotation = this.rotation;
        cmp2.rotationPivot = this.rotationPivot;
        cmp2.ignoreEntities = this.ignoreEntities;
        cmp2.chunkPos = this.chunkPos;
        cmp2.boundingBox = this.boundingBox;
        cmp2.keepLiquids = this.keepLiquids;
        cmp2.random = this.random;
        cmp2.palette = this.palette;
        cmp2.processors.addAll(this.processors);
        cmp2.knownShape = this.knownShape;
        return cmp2;
    }
    
    public StructurePlaceSettings setMirror(final Mirror bsu) {
        this.mirror = bsu;
        return this;
    }
    
    public StructurePlaceSettings setRotation(final Rotation btu) {
        this.rotation = btu;
        return this;
    }
    
    public StructurePlaceSettings setRotationPivot(final BlockPos fk) {
        this.rotationPivot = fk;
        return this;
    }
    
    public StructurePlaceSettings setIgnoreEntities(final boolean boolean1) {
        this.ignoreEntities = boolean1;
        return this;
    }
    
    public StructurePlaceSettings setChunkPos(final ChunkPos bjh) {
        this.chunkPos = bjh;
        return this;
    }
    
    public StructurePlaceSettings setBoundingBox(final BoundingBox clb) {
        this.boundingBox = clb;
        return this;
    }
    
    public StructurePlaceSettings setRandom(@Nullable final Random random) {
        this.random = random;
        return this;
    }
    
    public StructurePlaceSettings setKnownShape(final boolean boolean1) {
        this.knownShape = boolean1;
        return this;
    }
    
    public StructurePlaceSettings clearProcessors() {
        this.processors.clear();
        return this;
    }
    
    public StructurePlaceSettings addProcessor(final StructureProcessor cmq) {
        this.processors.add(cmq);
        return this;
    }
    
    public StructurePlaceSettings popProcessor(final StructureProcessor cmq) {
        this.processors.remove(cmq);
        return this;
    }
    
    public Mirror getMirror() {
        return this.mirror;
    }
    
    public Rotation getRotation() {
        return this.rotation;
    }
    
    public BlockPos getRotationPivot() {
        return this.rotationPivot;
    }
    
    public Random getRandom(@Nullable final BlockPos fk) {
        if (this.random != null) {
            return this.random;
        }
        if (fk == null) {
            return new Random(Util.getMillis());
        }
        return new Random(Mth.getSeed(fk));
    }
    
    public boolean isIgnoreEntities() {
        return this.ignoreEntities;
    }
    
    @Nullable
    public BoundingBox getBoundingBox() {
        if (this.boundingBox == null && this.chunkPos != null) {
            this.updateBoundingBoxFromChunkPos();
        }
        return this.boundingBox;
    }
    
    public boolean getKnownShape() {
        return this.knownShape;
    }
    
    public List<StructureProcessor> getProcessors() {
        return this.processors;
    }
    
    void updateBoundingBoxFromChunkPos() {
        if (this.chunkPos != null) {
            this.boundingBox = this.calculateBoundingBox(this.chunkPos);
        }
    }
    
    public boolean shouldKeepLiquids() {
        return this.keepLiquids;
    }
    
    public List<StructureTemplate.StructureBlockInfo> getRandomPalette(final List<List<StructureTemplate.StructureBlockInfo>> list, @Nullable final BlockPos fk) {
        final int integer4 = list.size();
        return (integer4 > 0) ? list.get(this.getRandom(fk).nextInt(integer4)) : Collections.<StructureTemplate.StructureBlockInfo>emptyList();
    }
    
    @Nullable
    private BoundingBox calculateBoundingBox(@Nullable final ChunkPos bjh) {
        if (bjh == null) {
            return this.boundingBox;
        }
        final int integer3 = bjh.x * 16;
        final int integer4 = bjh.z * 16;
        return new BoundingBox(integer3, 0, integer4, integer3 + 16 - 1, 255, integer4 + 16 - 1);
    }
}
