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

import java.util.function.BiFunction;
import com.mojang.datafixers.kinds.Applicative;
import com.mojang.datafixers.kinds.App;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.function.Function;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import java.util.Iterator;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
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.List;
import com.mojang.serialization.Codec;

public class ListPoolElement extends StructurePoolElement {
    public static final Codec<ListPoolElement> CODEC;
    private final List<StructurePoolElement> elements;
    
    @Deprecated
    public ListPoolElement(final List<StructurePoolElement> list) {
        this(list, StructureTemplatePool.Projection.RIGID);
    }
    
    public ListPoolElement(final List<StructurePoolElement> list, final StructureTemplatePool.Projection a) {
        super(a);
        if (list.isEmpty()) {
            throw new IllegalArgumentException("Elements are empty");
        }
        this.elements = list;
        this.setProjectionOnEachElement(a);
    }
    
    @Override
    public List<StructureTemplate.StructureBlockInfo> getShuffledJigsawBlocks(final StructureManager cva, final BlockPos fu, final Rotation cap, final Random random) {
        return this.elements.get(0).getShuffledJigsawBlocks(cva, fu, cap, random);
    }
    
    @Override
    public BoundingBox getBoundingBox(final StructureManager cva, final BlockPos fu, final Rotation cap) {
        final BoundingBox ctd5 = BoundingBox.getUnknownBox();
        for (final StructurePoolElement cqd7 : this.elements) {
            final BoundingBox ctd6 = cqd7.getBoundingBox(cva, fu, cap);
            ctd5.expand(ctd6);
        }
        return ctd5;
    }
    
    @Override
    public 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) {
        for (final StructurePoolElement cqd13 : this.elements) {
            if (!cqd13.place(cva, bqu, bqq, cha, fu5, fu6, cap, ctd, random, boolean10)) {
                return false;
            }
        }
        return true;
    }
    
    @Override
    public StructurePoolElementType<?> getType() {
        return StructurePoolElementType.LIST;
    }
    
    @Override
    public StructurePoolElement setProjection(final StructureTemplatePool.Projection a) {
        super.setProjection(a);
        this.setProjectionOnEachElement(a);
        return this;
    }
    
    @Override
    public String toString() {
        return "List[" + this.elements.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]";
    }
    
    private void setProjectionOnEachElement(final StructureTemplatePool.Projection a) {
        this.elements.forEach(cqd -> cqd.setProjection(a));
    }
    
    static {
        CODEC = RecordCodecBuilder.create(instance -> ((RecordCodecBuilder.Instance)instance).group((App)StructurePoolElement.CODEC.listOf().fieldOf("elements").forGetter(cqb -> cqb.elements), (App)StructurePoolElement.<StructurePoolElement>projectionCodec()).apply(instance, (BiFunction)ListPoolElement::new));
    }
}
