package net.minecraft.world.level.levelgen.feature.structures;

import net.minecraft.core.Registry;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import java.util.List;
import java.util.Random;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import java.util.function.Function;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import javax.annotation.Nullable;
import com.mojang.serialization.Codec;

public abstract class StructurePoolElement {
    public static final Codec<StructurePoolElement> CODEC;
    @Nullable
    private volatile StructureTemplatePool.Projection projection;
    
    protected static <E extends StructurePoolElement> RecordCodecBuilder<E, StructureTemplatePool.Projection> projectionCodec() {
        return (RecordCodecBuilder<E, StructureTemplatePool.Projection>)StructureTemplatePool.Projection.CODEC.fieldOf("projection").forGetter((Function)StructurePoolElement::getProjection);
    }
    
    protected StructurePoolElement(final StructureTemplatePool.Projection a) {
        this.projection = a;
    }
    
    public abstract List<StructureTemplate.StructureBlockInfo> getShuffledJigsawBlocks(final StructureManager cva, final BlockPos fu, final Rotation cap, final Random random);
    
    public abstract BoundingBox getBoundingBox(final StructureManager cva, final BlockPos fu, final Rotation cap);
    
    public abstract boolean place(final StructureManager cva, final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final BlockPos fu5, final BlockPos fu6, final Rotation cap, final BoundingBox ctd, final Random random, final boolean boolean10);
    
    public abstract StructurePoolElementType<?> getType();
    
    public void handleDataMarker(final LevelAccessor bqc, final StructureTemplate.StructureBlockInfo c, final BlockPos fu, final Rotation cap, final Random random, final BoundingBox ctd) {
    }
    
    public StructurePoolElement setProjection(final StructureTemplatePool.Projection a) {
        this.projection = a;
        return this;
    }
    
    public StructureTemplatePool.Projection getProjection() {
        final StructureTemplatePool.Projection a2 = this.projection;
        if (a2 == null) {
            throw new IllegalStateException();
        }
        return a2;
    }
    
    public int getGroundLevelDelta() {
        return 1;
    }
    
    static {
        CODEC = Registry.STRUCTURE_POOL_ELEMENT.dispatch("element_type", (Function)StructurePoolElement::getType, (Function)StructurePoolElementType::codec);
    }
}
