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

import net.minecraft.world.level.levelgen.placement.nether.LightGemChanceDecorator;
import net.minecraft.world.level.levelgen.placement.nether.MagmaDecorator;
import net.minecraft.world.level.levelgen.placement.nether.FireDecorator;
import net.minecraft.world.level.levelgen.placement.nether.ChanceRangeDecorator;
import net.minecraft.world.level.levelgen.placement.nether.RandomCountRangeDecorator;
import net.minecraft.world.level.levelgen.placement.nether.CountRangeDecorator;
import java.util.stream.Stream;
import net.minecraft.world.level.LevelAccessor;
import org.apache.commons.lang3.mutable.MutableBoolean;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.core.BlockPos;
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.Registry;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.levelgen.feature.configurations.ChanceRangeDecoratorConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.CountRangeDecoratorConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.NoiseDependantDecoratorConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.NoneDecoratorConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.DecoratorConfiguration;

public abstract class FeatureDecorator<DC extends DecoratorConfiguration> {
    public static final FeatureDecorator<NoneDecoratorConfiguration> NOPE;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> COUNT_HEIGHTMAP;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> COUNT_TOP_SOLID;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> COUNT_HEIGHTMAP_32;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> COUNT_HEIGHTMAP_DOUBLE;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> COUNT_HEIGHT_64;
    public static final FeatureDecorator<NoiseDependantDecoratorConfiguration> NOISE_HEIGHTMAP_32;
    public static final FeatureDecorator<NoiseDependantDecoratorConfiguration> NOISE_HEIGHTMAP_DOUBLE;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> CHANCE_HEIGHTMAP;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> CHANCE_HEIGHTMAP_DOUBLE;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> CHANCE_PASSTHROUGH;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> CHANCE_TOP_SOLID_HEIGHTMAP;
    public static final FeatureDecorator<FrequencyWithExtraChanceDecoratorConfiguration> COUNT_EXTRA_HEIGHTMAP;
    public static final FeatureDecorator<CountRangeDecoratorConfiguration> COUNT_RANGE;
    public static final FeatureDecorator<CountRangeDecoratorConfiguration> COUNT_BIASED_RANGE;
    public static final FeatureDecorator<CountRangeDecoratorConfiguration> COUNT_VERY_BIASED_RANGE;
    public static final FeatureDecorator<CountRangeDecoratorConfiguration> RANDOM_COUNT_RANGE;
    public static final FeatureDecorator<ChanceRangeDecoratorConfiguration> CHANCE_RANGE;
    public static final FeatureDecorator<FrequencyChanceDecoratorConfiguration> COUNT_CHANCE_HEIGHTMAP;
    public static final FeatureDecorator<FrequencyChanceDecoratorConfiguration> COUNT_CHANCE_HEIGHTMAP_DOUBLE;
    public static final FeatureDecorator<DepthAverageConfigation> COUNT_DEPTH_AVERAGE;
    public static final FeatureDecorator<NoneDecoratorConfiguration> TOP_SOLID_HEIGHTMAP;
    public static final FeatureDecorator<RangeDecoratorConfiguration> TOP_SOLID_HEIGHTMAP_RANGE;
    public static final FeatureDecorator<NoiseCountFactorDecoratorConfiguration> TOP_SOLID_HEIGHTMAP_NOISE_BIASED;
    public static final FeatureDecorator<CarvingMaskDecoratorConfiguration> CARVING_MASK;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> FOREST_ROCK;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> FIRE;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> MAGMA;
    public static final FeatureDecorator<NoneDecoratorConfiguration> EMERALD_ORE;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> LAVA_LAKE;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> WATER_LAKE;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> DUNGEONS;
    public static final FeatureDecorator<NoneDecoratorConfiguration> DARK_OAK_TREE;
    public static final FeatureDecorator<ChanceDecoratorConfiguration> ICEBERG;
    public static final FeatureDecorator<FrequencyDecoratorConfiguration> LIGHT_GEM_CHANCE;
    public static final FeatureDecorator<NoneDecoratorConfiguration> END_ISLAND;
    public static final FeatureDecorator<NoneDecoratorConfiguration> CHORUS_PLANT;
    public static final FeatureDecorator<NoneDecoratorConfiguration> END_GATEWAY;
    private final Codec<ConfiguredDecorator<DC>> configuredCodec;
    
    private static <T extends DecoratorConfiguration, G extends FeatureDecorator<T>> G register(final String string, final G csc) {
        return Registry.<G>register(Registry.DECORATOR, string, csc);
    }
    
    public FeatureDecorator(final Codec<DC> codec) {
        this.configuredCodec = (Codec<ConfiguredDecorator<DC>>)codec.fieldOf("config").xmap(cnn -> new ConfiguredDecorator((FeatureDecorator<DecoratorConfiguration>)this, cnn), crl -> crl.config).codec();
    }
    
    public ConfiguredDecorator<DC> configured(final DC cnn) {
        return new ConfiguredDecorator<DC>(this, cnn);
    }
    
    public Codec<ConfiguredDecorator<DC>> configuredCodec() {
        return this.configuredCodec;
    }
    
    protected <FC extends FeatureConfiguration, F extends Feature<FC>> boolean placeFeature(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BlockPos fu, final DC cnn, final ConfiguredFeature<FC, F> ckb) {
        final MutableBoolean mutableBoolean9 = new MutableBoolean();
        final MutableBoolean mutableBoolean10;
        this.getPositions(bqu, cha, random, cnn, fu).forEach(fu -> {
            if (ckb.place(bqu, bqq, cha, random, fu)) {
                mutableBoolean10.setTrue();
            }
            return;
        });
        return mutableBoolean9.isTrue();
    }
    
    public abstract Stream<BlockPos> getPositions(final LevelAccessor bqc, final ChunkGenerator cha, final Random random, final DC cnn, final BlockPos fu);
    
    @Override
    public String toString() {
        return this.getClass().getSimpleName() + "@" + Integer.toHexString(this.hashCode());
    }
    
    static {
        NOPE = FeatureDecorator.<DecoratorConfiguration, NopePlacementDecorator>register("nope", new NopePlacementDecorator(NoneDecoratorConfiguration.CODEC));
        COUNT_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, CountHeightmapDecorator>register("count_heightmap", new CountHeightmapDecorator(FrequencyDecoratorConfiguration.CODEC));
        COUNT_TOP_SOLID = FeatureDecorator.<DecoratorConfiguration, CountTopSolidDecorator>register("count_top_solid", new CountTopSolidDecorator(FrequencyDecoratorConfiguration.CODEC));
        COUNT_HEIGHTMAP_32 = FeatureDecorator.<DecoratorConfiguration, CountHeightmap32Decorator>register("count_heightmap_32", new CountHeightmap32Decorator(FrequencyDecoratorConfiguration.CODEC));
        COUNT_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, CountHeighmapDoubleDecorator>register("count_heightmap_double", new CountHeighmapDoubleDecorator(FrequencyDecoratorConfiguration.CODEC));
        COUNT_HEIGHT_64 = FeatureDecorator.<DecoratorConfiguration, CountHeight64Decorator>register("count_height_64", new CountHeight64Decorator(FrequencyDecoratorConfiguration.CODEC));
        NOISE_HEIGHTMAP_32 = FeatureDecorator.<DecoratorConfiguration, NoiseHeightmap32Decorator>register("noise_heightmap_32", new NoiseHeightmap32Decorator(NoiseDependantDecoratorConfiguration.CODEC));
        NOISE_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, NoiseHeightmapDoubleDecorator>register("noise_heightmap_double", new NoiseHeightmapDoubleDecorator(NoiseDependantDecoratorConfiguration.CODEC));
        CHANCE_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, ChanceHeightmapDecorator>register("chance_heightmap", new ChanceHeightmapDecorator(ChanceDecoratorConfiguration.CODEC));
        CHANCE_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, ChanceHeightmapDoubleDecorator>register("chance_heightmap_double", new ChanceHeightmapDoubleDecorator(ChanceDecoratorConfiguration.CODEC));
        CHANCE_PASSTHROUGH = FeatureDecorator.<DecoratorConfiguration, ChancePassthroughDecorator>register("chance_passthrough", new ChancePassthroughDecorator(ChanceDecoratorConfiguration.CODEC));
        CHANCE_TOP_SOLID_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, ChanceTopSolidHeightmapDecorator>register("chance_top_solid_heightmap", new ChanceTopSolidHeightmapDecorator(ChanceDecoratorConfiguration.CODEC));
        COUNT_EXTRA_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, CountWithExtraChanceHeightmapDecorator>register("count_extra_heightmap", new CountWithExtraChanceHeightmapDecorator(FrequencyWithExtraChanceDecoratorConfiguration.CODEC));
        COUNT_RANGE = FeatureDecorator.<DecoratorConfiguration, CountRangeDecorator>register("count_range", new CountRangeDecorator(CountRangeDecoratorConfiguration.CODEC));
        COUNT_BIASED_RANGE = FeatureDecorator.<DecoratorConfiguration, CountBiasedRangeDecorator>register("count_biased_range", new CountBiasedRangeDecorator(CountRangeDecoratorConfiguration.CODEC));
        COUNT_VERY_BIASED_RANGE = FeatureDecorator.<DecoratorConfiguration, CountVeryBiasedRangeDecorator>register("count_very_biased_range", new CountVeryBiasedRangeDecorator(CountRangeDecoratorConfiguration.CODEC));
        RANDOM_COUNT_RANGE = FeatureDecorator.<DecoratorConfiguration, RandomCountRangeDecorator>register("random_count_range", new RandomCountRangeDecorator(CountRangeDecoratorConfiguration.CODEC));
        CHANCE_RANGE = FeatureDecorator.<DecoratorConfiguration, ChanceRangeDecorator>register("chance_range", new ChanceRangeDecorator(ChanceRangeDecoratorConfiguration.CODEC));
        COUNT_CHANCE_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, CountChanceHeightmapDecorator>register("count_chance_heightmap", new CountChanceHeightmapDecorator(FrequencyChanceDecoratorConfiguration.CODEC));
        COUNT_CHANCE_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, CountChanceHeightmapDoubleDecorator>register("count_chance_heightmap_double", new CountChanceHeightmapDoubleDecorator(FrequencyChanceDecoratorConfiguration.CODEC));
        COUNT_DEPTH_AVERAGE = FeatureDecorator.<DecoratorConfiguration, CountDepthAverageDecorator>register("count_depth_average", new CountDepthAverageDecorator(DepthAverageConfigation.CODEC));
        TOP_SOLID_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, TopSolidHeightMapDecorator>register("top_solid_heightmap", new TopSolidHeightMapDecorator(NoneDecoratorConfiguration.CODEC));
        TOP_SOLID_HEIGHTMAP_RANGE = FeatureDecorator.<DecoratorConfiguration, TopSolidHeightMapRangeDecorator>register("top_solid_heightmap_range", new TopSolidHeightMapRangeDecorator(RangeDecoratorConfiguration.CODEC));
        TOP_SOLID_HEIGHTMAP_NOISE_BIASED = FeatureDecorator.<DecoratorConfiguration, TopSolidHeightMapNoiseBasedDecorator>register("top_solid_heightmap_noise_biased", new TopSolidHeightMapNoiseBasedDecorator(NoiseCountFactorDecoratorConfiguration.CODEC));
        CARVING_MASK = FeatureDecorator.<DecoratorConfiguration, CarvingMaskDecorator>register("carving_mask", new CarvingMaskDecorator(CarvingMaskDecoratorConfiguration.CODEC));
        FOREST_ROCK = FeatureDecorator.<DecoratorConfiguration, ForestRockPlacementDecorator>register("forest_rock", new ForestRockPlacementDecorator(FrequencyDecoratorConfiguration.CODEC));
        FIRE = FeatureDecorator.<DecoratorConfiguration, FireDecorator>register("fire", new FireDecorator(FrequencyDecoratorConfiguration.CODEC));
        MAGMA = FeatureDecorator.<DecoratorConfiguration, MagmaDecorator>register("magma", new MagmaDecorator(FrequencyDecoratorConfiguration.CODEC));
        EMERALD_ORE = FeatureDecorator.<DecoratorConfiguration, EmeraldPlacementDecorator>register("emerald_ore", new EmeraldPlacementDecorator(NoneDecoratorConfiguration.CODEC));
        LAVA_LAKE = FeatureDecorator.<DecoratorConfiguration, LakeLavaPlacementDecorator>register("lava_lake", new LakeLavaPlacementDecorator(ChanceDecoratorConfiguration.CODEC));
        WATER_LAKE = FeatureDecorator.<DecoratorConfiguration, LakeWaterPlacementDecorator>register("water_lake", new LakeWaterPlacementDecorator(ChanceDecoratorConfiguration.CODEC));
        DUNGEONS = FeatureDecorator.<DecoratorConfiguration, MonsterRoomPlacementDecorator>register("dungeons", new MonsterRoomPlacementDecorator(ChanceDecoratorConfiguration.CODEC));
        DARK_OAK_TREE = FeatureDecorator.<DecoratorConfiguration, DarkOakTreePlacementDecorator>register("dark_oak_tree", new DarkOakTreePlacementDecorator(NoneDecoratorConfiguration.CODEC));
        ICEBERG = FeatureDecorator.<DecoratorConfiguration, IcebergPlacementDecorator>register("iceberg", new IcebergPlacementDecorator(ChanceDecoratorConfiguration.CODEC));
        LIGHT_GEM_CHANCE = FeatureDecorator.<DecoratorConfiguration, LightGemChanceDecorator>register("light_gem_chance", new LightGemChanceDecorator(FrequencyDecoratorConfiguration.CODEC));
        END_ISLAND = FeatureDecorator.<DecoratorConfiguration, EndIslandPlacementDecorator>register("end_island", new EndIslandPlacementDecorator(NoneDecoratorConfiguration.CODEC));
        CHORUS_PLANT = FeatureDecorator.<DecoratorConfiguration, ChorusPlantPlacementDecorator>register("chorus_plant", new ChorusPlantPlacementDecorator(NoneDecoratorConfiguration.CODEC));
        END_GATEWAY = FeatureDecorator.<DecoratorConfiguration, EndGatewayPlacementDecorator>register("end_gateway", new EndGatewayPlacementDecorator(NoneDecoratorConfiguration.CODEC));
    }
}
