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.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.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 cmo, final BlockPos fk, final Rotation btu, final List<StructurePiece> list, final Random random, final ShipwreckConfiguration chf) {
        final ResourceLocation sm7 = chf.isBeached ? ShipwreckPieces.STRUCTURE_LOCATION_BEACHED[random.nextInt(ShipwreckPieces.STRUCTURE_LOCATION_BEACHED.length)] : ShipwreckPieces.STRUCTURE_LOCATION_OCEAN[random.nextInt(ShipwreckPieces.STRUCTURE_LOCATION_OCEAN.length)];
        list.add(new ShipwreckPiece(cmo, sm7, fk, btu, chf.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 cmo, final ResourceLocation sm, final BlockPos fk, final Rotation btu, final boolean boolean5) {
            super(StructurePieceType.SHIPWRECK_PIECE, 0);
            this.templatePosition = fk;
            this.rotation = btu;
            this.templateLocation = sm;
            this.isBeached = boolean5;
            this.loadTemplate(cmo);
        }
        
        public ShipwreckPiece(final StructureManager cmo, final CompoundTag jt) {
            super(StructurePieceType.SHIPWRECK_PIECE, jt);
            this.templateLocation = new ResourceLocation(jt.getString("Template"));
            this.isBeached = jt.getBoolean("isBeached");
            this.rotation = Rotation.valueOf(jt.getString("Rot"));
            this.loadTemplate(cmo);
        }
        
        @Override
        protected void addAdditionalSaveData(final CompoundTag jt) {
            super.addAdditionalSaveData(jt);
            jt.putString("Template", this.templateLocation.toString());
            jt.putBoolean("isBeached", this.isBeached);
            jt.putString("Rot", this.rotation.name());
        }
        
        private void loadTemplate(final StructureManager cmo) {
            final StructureTemplate cms3 = cmo.getOrCreate(this.templateLocation);
            final StructurePlaceSettings cmp4 = new StructurePlaceSettings().setRotation(this.rotation).setMirror(Mirror.NONE).setRotationPivot(ShipwreckPieces.PIVOT).addProcessor(BlockIgnoreProcessor.STRUCTURE_AND_AIR);
            this.setup(cms3, this.templatePosition, cmp4);
        }
        
        @Override
        protected void handleDataMarker(final String string, final BlockPos fk, final LevelAccessor bjx, final Random random, final BoundingBox clb) {
            if ("map_chest".equals(string)) {
                RandomizableContainerBlockEntity.setLootTable(bjx, random, fk.below(), BuiltInLootTables.SHIPWRECK_MAP);
            }
            else if ("treasure_chest".equals(string)) {
                RandomizableContainerBlockEntity.setLootTable(bjx, random, fk.below(), BuiltInLootTables.SHIPWRECK_TREASURE);
            }
            else if ("supply_chest".equals(string)) {
                RandomizableContainerBlockEntity.setLootTable(bjx, random, fk.below(), BuiltInLootTables.SHIPWRECK_SUPPLY);
            }
        }
        
        @Override
        public boolean postProcess(final LevelAccessor bjx, final ChunkGenerator<?> caa, final Random random, final BoundingBox clb, final ChunkPos bjh) {
            int integer7 = 256;
            int integer8 = 0;
            final BlockPos fk9 = this.template.getSize();
            final Heightmap.Types a10 = this.isBeached ? Heightmap.Types.WORLD_SURFACE_WG : Heightmap.Types.OCEAN_FLOOR_WG;
            final int integer9 = fk9.getX() * fk9.getZ();
            if (integer9 == 0) {
                integer8 = bjx.getHeight(a10, this.templatePosition.getX(), this.templatePosition.getZ());
            }
            else {
                final BlockPos fk10 = this.templatePosition.offset(fk9.getX() - 1, 0, fk9.getZ() - 1);
                for (final BlockPos fk11 : BlockPos.betweenClosed(this.templatePosition, fk10)) {
                    final int integer10 = bjx.getHeight(a10, fk11.getX(), fk11.getZ());
                    integer8 += integer10;
                    integer7 = Math.min(integer7, integer10);
                }
                integer8 /= integer9;
            }
            final int integer11 = this.isBeached ? (integer7 - fk9.getY() / 2 - random.nextInt(3)) : integer8;
            this.templatePosition = new BlockPos(this.templatePosition.getX(), integer11, this.templatePosition.getZ());
            return super.postProcess(bjx, caa, random, clb, bjh);
        }
    }
}
