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

import java.util.Iterator;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor;
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.levelgen.feature.StructurePieceType;
import net.minecraft.Util;
import net.minecraft.world.level.levelgen.feature.configurations.ShipwreckConfiguration;
import java.util.Random;
import java.util.List;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.BlockPos;

public class ShipwreckPieces {
    private static final BlockPos PIVOT;
    private static final ResourceLocation[] STRUCTURE_LOCATION_BEACHED;
    private static final ResourceLocation[] STRUCTURE_LOCATION_OCEAN;
    
    public static void addPieces(final StructureManager cva, final BlockPos fu, final Rotation cap, final List<StructurePiece> list, final Random random, final ShipwreckConfiguration com) {
        final ResourceLocation uh7 = Util.<ResourceLocation>getRandom(com.isBeached ? ShipwreckPieces.STRUCTURE_LOCATION_BEACHED : ShipwreckPieces.STRUCTURE_LOCATION_OCEAN, random);
        list.add(new ShipwreckPiece(cva, uh7, fu, cap, com.isBeached));
    }
    
    static {
        PIVOT = new BlockPos(4, 0, 15);
        STRUCTURE_LOCATION_BEACHED = new ResourceLocation[] { new ResourceLocation("shipwreck/with_mast"), new ResourceLocation("shipwreck/sideways_full"), new ResourceLocation("shipwreck/sideways_fronthalf"), new ResourceLocation("shipwreck/sideways_backhalf"), new ResourceLocation("shipwreck/rightsideup_full"), new ResourceLocation("shipwreck/rightsideup_fronthalf"), new ResourceLocation("shipwreck/rightsideup_backhalf"), new ResourceLocation("shipwreck/with_mast_degraded"), new ResourceLocation("shipwreck/rightsideup_full_degraded"), new ResourceLocation("shipwreck/rightsideup_fronthalf_degraded"), new ResourceLocation("shipwreck/rightsideup_backhalf_degraded") };
        STRUCTURE_LOCATION_OCEAN = new ResourceLocation[] { new ResourceLocation("shipwreck/with_mast"), new ResourceLocation("shipwreck/upsidedown_full"), new ResourceLocation("shipwreck/upsidedown_fronthalf"), new ResourceLocation("shipwreck/upsidedown_backhalf"), new ResourceLocation("shipwreck/sideways_full"), new ResourceLocation("shipwreck/sideways_fronthalf"), new ResourceLocation("shipwreck/sideways_backhalf"), new ResourceLocation("shipwreck/rightsideup_full"), new ResourceLocation("shipwreck/rightsideup_fronthalf"), new ResourceLocation("shipwreck/rightsideup_backhalf"), new ResourceLocation("shipwreck/with_mast_degraded"), new ResourceLocation("shipwreck/upsidedown_full_degraded"), new ResourceLocation("shipwreck/upsidedown_fronthalf_degraded"), new ResourceLocation("shipwreck/upsidedown_backhalf_degraded"), new ResourceLocation("shipwreck/sideways_full_degraded"), new ResourceLocation("shipwreck/sideways_fronthalf_degraded"), new ResourceLocation("shipwreck/sideways_backhalf_degraded"), new ResourceLocation("shipwreck/rightsideup_full_degraded"), new ResourceLocation("shipwreck/rightsideup_fronthalf_degraded"), new ResourceLocation("shipwreck/rightsideup_backhalf_degraded") };
    }
    
    public static class ShipwreckPiece extends TemplateStructurePiece {
        private final Rotation rotation;
        private final ResourceLocation templateLocation;
        private final boolean isBeached;
        
        public ShipwreckPiece(final StructureManager cva, final ResourceLocation uh, final BlockPos fu, final Rotation cap, final boolean boolean5) {
            super(StructurePieceType.SHIPWRECK_PIECE, 0);
            this.templatePosition = fu;
            this.rotation = cap;
            this.templateLocation = uh;
            this.isBeached = boolean5;
            this.loadTemplate(cva);
        }
        
        public ShipwreckPiece(final StructureManager cva, final CompoundTag le) {
            super(StructurePieceType.SHIPWRECK_PIECE, le);
            this.templateLocation = new ResourceLocation(le.getString("Template"));
            this.isBeached = le.getBoolean("isBeached");
            this.rotation = Rotation.valueOf(le.getString("Rot"));
            this.loadTemplate(cva);
        }
        
        @Override
        protected void addAdditionalSaveData(final CompoundTag le) {
            super.addAdditionalSaveData(le);
            le.putString("Template", this.templateLocation.toString());
            le.putBoolean("isBeached", this.isBeached);
            le.putString("Rot", this.rotation.name());
        }
        
        private void loadTemplate(final StructureManager cva) {
            final StructureTemplate cve3 = cva.getOrCreate(this.templateLocation);
            final StructurePlaceSettings cvb4 = new StructurePlaceSettings().setRotation(this.rotation).setMirror(Mirror.NONE).setRotationPivot(ShipwreckPieces.PIVOT).addProcessor(BlockIgnoreProcessor.STRUCTURE_AND_AIR);
            this.setup(cve3, this.templatePosition, cvb4);
        }
        
        @Override
        protected void handleDataMarker(final String string, final BlockPos fu, final LevelAccessor bqc, final Random random, final BoundingBox ctd) {
            if ("map_chest".equals(string)) {
                RandomizableContainerBlockEntity.setLootTable(bqc, random, fu.below(), BuiltInLootTables.SHIPWRECK_MAP);
            }
            else if ("treasure_chest".equals(string)) {
                RandomizableContainerBlockEntity.setLootTable(bqc, random, fu.below(), BuiltInLootTables.SHIPWRECK_TREASURE);
            }
            else if ("supply_chest".equals(string)) {
                RandomizableContainerBlockEntity.setLootTable(bqc, random, fu.below(), BuiltInLootTables.SHIPWRECK_SUPPLY);
            }
        }
        
        @Override
        public boolean postProcess(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BoundingBox ctd, final ChunkPos bph, final BlockPos fu) {
            int integer9 = 256;
            int integer10 = 0;
            final BlockPos fu2 = this.template.getSize();
            final Heightmap.Types a12 = this.isBeached ? Heightmap.Types.WORLD_SURFACE_WG : Heightmap.Types.OCEAN_FLOOR_WG;
            final int integer11 = fu2.getX() * fu2.getZ();
            if (integer11 == 0) {
                integer10 = bqu.getHeight(a12, this.templatePosition.getX(), this.templatePosition.getZ());
            }
            else {
                final BlockPos fu3 = this.templatePosition.offset(fu2.getX() - 1, 0, fu2.getZ() - 1);
                for (final BlockPos fu4 : BlockPos.betweenClosed(this.templatePosition, fu3)) {
                    final int integer12 = bqu.getHeight(a12, fu4.getX(), fu4.getZ());
                    integer10 += integer12;
                    integer9 = Math.min(integer9, integer12);
                }
                integer10 /= integer11;
            }
            final int integer13 = this.isBeached ? (integer9 - fu2.getY() / 2 - random.nextInt(3)) : integer10;
            this.templatePosition = new BlockPos(this.templatePosition.getX(), integer13, this.templatePosition.getZ());
            return super.postProcess(bqu, bqq, cha, random, ctd, bph, fu);
        }
    }
}
