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

import org.apache.logging.log4j.LogManager;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
import java.util.Iterator;
import java.util.List;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.commands.arguments.blocks.BlockStateParser;
import com.mojang.brigadier.StringReader;
import net.minecraft.world.level.block.state.properties.StructureMode;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.ChunkPos;
import java.util.Random;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.levelgen.feature.StructurePieceType;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import org.apache.logging.log4j.Logger;

public abstract class TemplateStructurePiece extends StructurePiece {
    private static final Logger LOGGER;
    protected StructureTemplate template;
    protected StructurePlaceSettings placeSettings;
    protected BlockPos templatePosition;
    
    public TemplateStructurePiece(final StructurePieceType cmm, final int integer) {
        super(cmm, integer);
    }
    
    public TemplateStructurePiece(final StructurePieceType cmm, final CompoundTag le) {
        super(cmm, le);
        this.templatePosition = new BlockPos(le.getInt("TPX"), le.getInt("TPY"), le.getInt("TPZ"));
    }
    
    protected void setup(final StructureTemplate cve, final BlockPos fu, final StructurePlaceSettings cvb) {
        this.template = cve;
        this.setOrientation(Direction.NORTH);
        this.templatePosition = fu;
        this.placeSettings = cvb;
        this.boundingBox = cve.getBoundingBox(cvb, fu);
    }
    
    @Override
    protected void addAdditionalSaveData(final CompoundTag le) {
        le.putInt("TPX", this.templatePosition.getX());
        le.putInt("TPY", this.templatePosition.getY());
        le.putInt("TPZ", this.templatePosition.getZ());
    }
    
    @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) {
        this.placeSettings.setBoundingBox(ctd);
        this.boundingBox = this.template.getBoundingBox(this.placeSettings, this.templatePosition);
        if (this.template.placeInWorld(bqu, this.templatePosition, fu, this.placeSettings, random, 2)) {
            final List<StructureTemplate.StructureBlockInfo> list9 = this.template.filterBlocks(this.templatePosition, this.placeSettings, Blocks.STRUCTURE_BLOCK);
            for (final StructureTemplate.StructureBlockInfo c11 : list9) {
                if (c11.nbt == null) {
                    continue;
                }
                final StructureMode cgq12 = StructureMode.valueOf(c11.nbt.getString("mode"));
                if (cgq12 != StructureMode.DATA) {
                    continue;
                }
                this.handleDataMarker(c11.nbt.getString("metadata"), c11.pos, bqu, random, ctd);
            }
            final List<StructureTemplate.StructureBlockInfo> list10 = this.template.filterBlocks(this.templatePosition, this.placeSettings, Blocks.JIGSAW);
            for (final StructureTemplate.StructureBlockInfo c12 : list10) {
                if (c12.nbt == null) {
                    continue;
                }
                final String string13 = c12.nbt.getString("final_state");
                final BlockStateParser ef14 = new BlockStateParser(new StringReader(string13), false);
                BlockState cfj15 = Blocks.AIR.defaultBlockState();
                try {
                    ef14.parse(true);
                    final BlockState cfj16 = ef14.getState();
                    if (cfj16 != null) {
                        cfj15 = cfj16;
                    }
                    else {
                        TemplateStructurePiece.LOGGER.error("Error while parsing blockstate {} in jigsaw block @ {}", string13, c12.pos);
                    }
                }
                catch (CommandSyntaxException commandSyntaxException16) {
                    TemplateStructurePiece.LOGGER.error("Error while parsing blockstate {} in jigsaw block @ {}", string13, c12.pos);
                }
                bqu.setBlock(c12.pos, cfj15, 3);
            }
        }
        return true;
    }
    
    protected abstract void handleDataMarker(final String string, final BlockPos fu, final LevelAccessor bqc, final Random random, final BoundingBox ctd);
    
    @Override
    public void move(final int integer1, final int integer2, final int integer3) {
        super.move(integer1, integer2, integer3);
        this.templatePosition = this.templatePosition.offset(integer1, integer2, integer3);
    }
    
    @Override
    public Rotation getRotation() {
        return this.placeSettings.getRotation();
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
