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.HellFireDecorator;
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 java.util.concurrent.atomic.AtomicBoolean;
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.levelgen.ChunkGeneratorSettings;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.core.Registry;
import com.mojang.datafixers.Dynamic;
import java.util.function.Function;
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> HELL_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 Function<Dynamic<?>, ? extends DC> configurationFactory;
    
    private static <T extends DecoratorConfiguration, G extends FeatureDecorator<T>> G register(final String string, final G cka) {
        return Registry.<G>register(Registry.DECORATOR, string, cka);
    }
    
    public FeatureDecorator(final Function<Dynamic<?>, ? extends DC> function) {
        this.configurationFactory = function;
    }
    
    public DC createSettings(final Dynamic<?> dynamic) {
        return (DC)this.configurationFactory.apply(dynamic);
    }
    
    public ConfiguredDecorator<DC> configured(final DC cgk) {
        return new ConfiguredDecorator<DC>(this, cgk);
    }
    
    protected <FC extends FeatureConfiguration, F extends Feature<FC>> boolean placeFeature(final LevelAccessor bjx, final ChunkGenerator<? extends ChunkGeneratorSettings> caa, final Random random, final BlockPos fk, final DC cgk, final ConfiguredFeature<FC, F> cdc) {
        final AtomicBoolean atomicBoolean8 = new AtomicBoolean(false);
        final boolean boolean7;
        final AtomicBoolean atomicBoolean9;
        this.getPositions(bjx, caa, random, cgk, fk).forEach(fk -> {
            boolean7 = cdc.place(bjx, caa, random, fk);
            atomicBoolean9.set(atomicBoolean9.get() || boolean7);
            return;
        });
        return atomicBoolean8.get();
    }
    
    public abstract Stream<BlockPos> getPositions(final LevelAccessor bjx, final ChunkGenerator<? extends ChunkGeneratorSettings> caa, final Random random, final DC cgk, final BlockPos fk);
    
    @Override
    public String toString() {
        return this.getClass().getSimpleName() + "@" + Integer.toHexString(this.hashCode());
    }
    
    static {
        NOPE = FeatureDecorator.<DecoratorConfiguration, NopePlacementDecorator>register("nope", new NopePlacementDecorator(NoneDecoratorConfiguration::deserialize));
        COUNT_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, CountHeightmapDecorator>register("count_heightmap", new CountHeightmapDecorator(FrequencyDecoratorConfiguration::deserialize));
        COUNT_TOP_SOLID = FeatureDecorator.<DecoratorConfiguration, CountTopSolidDecorator>register("count_top_solid", new CountTopSolidDecorator(FrequencyDecoratorConfiguration::deserialize));
        COUNT_HEIGHTMAP_32 = FeatureDecorator.<DecoratorConfiguration, CountHeightmap32Decorator>register("count_heightmap_32", new CountHeightmap32Decorator(FrequencyDecoratorConfiguration::deserialize));
        COUNT_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, CountHeighmapDoubleDecorator>register("count_heightmap_double", new CountHeighmapDoubleDecorator(FrequencyDecoratorConfiguration::deserialize));
        COUNT_HEIGHT_64 = FeatureDecorator.<DecoratorConfiguration, CountHeight64Decorator>register("count_height_64", new CountHeight64Decorator(FrequencyDecoratorConfiguration::deserialize));
        NOISE_HEIGHTMAP_32 = FeatureDecorator.<DecoratorConfiguration, NoiseHeightmap32Decorator>register("noise_heightmap_32", new NoiseHeightmap32Decorator(NoiseDependantDecoratorConfiguration::deserialize));
        NOISE_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, NoiseHeightmapDoubleDecorator>register("noise_heightmap_double", new NoiseHeightmapDoubleDecorator(NoiseDependantDecoratorConfiguration::deserialize));
        CHANCE_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, ChanceHeightmapDecorator>register("chance_heightmap", new ChanceHeightmapDecorator(ChanceDecoratorConfiguration::deserialize));
        CHANCE_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, ChanceHeightmapDoubleDecorator>register("chance_heightmap_double", new ChanceHeightmapDoubleDecorator(ChanceDecoratorConfiguration::deserialize));
        CHANCE_PASSTHROUGH = FeatureDecorator.<DecoratorConfiguration, ChancePassthroughDecorator>register("chance_passthrough", new ChancePassthroughDecorator(ChanceDecoratorConfiguration::deserialize));
        CHANCE_TOP_SOLID_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, ChanceTopSolidHeightmapDecorator>register("chance_top_solid_heightmap", new ChanceTopSolidHeightmapDecorator(ChanceDecoratorConfiguration::deserialize));
        COUNT_EXTRA_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, CountWithExtraChanceHeightmapDecorator>register("count_extra_heightmap", new CountWithExtraChanceHeightmapDecorator(FrequencyWithExtraChanceDecoratorConfiguration::deserialize));
        COUNT_RANGE = FeatureDecorator.<DecoratorConfiguration, CountRangeDecorator>register("count_range", new CountRangeDecorator(CountRangeDecoratorConfiguration::deserialize));
        COUNT_BIASED_RANGE = FeatureDecorator.<DecoratorConfiguration, CountBiasedRangeDecorator>register("count_biased_range", new CountBiasedRangeDecorator(CountRangeDecoratorConfiguration::deserialize));
        COUNT_VERY_BIASED_RANGE = FeatureDecorator.<DecoratorConfiguration, CountVeryBiasedRangeDecorator>register("count_very_biased_range", new CountVeryBiasedRangeDecorator(CountRangeDecoratorConfiguration::deserialize));
        RANDOM_COUNT_RANGE = FeatureDecorator.<DecoratorConfiguration, RandomCountRangeDecorator>register("random_count_range", new RandomCountRangeDecorator(CountRangeDecoratorConfiguration::deserialize));
        CHANCE_RANGE = FeatureDecorator.<DecoratorConfiguration, ChanceRangeDecorator>register("chance_range", new ChanceRangeDecorator(ChanceRangeDecoratorConfiguration::deserialize));
        COUNT_CHANCE_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, CountChanceHeightmapDecorator>register("count_chance_heightmap", new CountChanceHeightmapDecorator(FrequencyChanceDecoratorConfiguration::deserialize));
        COUNT_CHANCE_HEIGHTMAP_DOUBLE = FeatureDecorator.<DecoratorConfiguration, CountChanceHeightmapDoubleDecorator>register("count_chance_heightmap_double", new CountChanceHeightmapDoubleDecorator(FrequencyChanceDecoratorConfiguration::deserialize));
        COUNT_DEPTH_AVERAGE = FeatureDecorator.<DecoratorConfiguration, CountDepthAverageDecorator>register("count_depth_average", new CountDepthAverageDecorator(DepthAverageConfigation::deserialize));
        TOP_SOLID_HEIGHTMAP = FeatureDecorator.<DecoratorConfiguration, TopSolidHeightMapDecorator>register("top_solid_heightmap", new TopSolidHeightMapDecorator(NoneDecoratorConfiguration::deserialize));
        TOP_SOLID_HEIGHTMAP_RANGE = FeatureDecorator.<DecoratorConfiguration, TopSolidHeightMapRangeDecorator>register("top_solid_heightmap_range", new TopSolidHeightMapRangeDecorator(RangeDecoratorConfiguration::deserialize));
        TOP_SOLID_HEIGHTMAP_NOISE_BIASED = FeatureDecorator.<DecoratorConfiguration, TopSolidHeightMapNoiseBasedDecorator>register("top_solid_heightmap_noise_biased", new TopSolidHeightMapNoiseBasedDecorator(NoiseCountFactorDecoratorConfiguration::deserialize));
        CARVING_MASK = FeatureDecorator.<DecoratorConfiguration, CarvingMaskDecorator>register("carving_mask", new CarvingMaskDecorator(CarvingMaskDecoratorConfiguration::deserialize));
        FOREST_ROCK = FeatureDecorator.<DecoratorConfiguration, ForestRockPlacementDecorator>register("forest_rock", new ForestRockPlacementDecorator(FrequencyDecoratorConfiguration::deserialize));
        HELL_FIRE = FeatureDecorator.<DecoratorConfiguration, HellFireDecorator>register("hell_fire", new HellFireDecorator(FrequencyDecoratorConfiguration::deserialize));
        MAGMA = FeatureDecorator.<DecoratorConfiguration, MagmaDecorator>register("magma", new MagmaDecorator(FrequencyDecoratorConfiguration::deserialize));
        EMERALD_ORE = FeatureDecorator.<DecoratorConfiguration, EmeraldPlacementDecorator>register("emerald_ore", new EmeraldPlacementDecorator(NoneDecoratorConfiguration::deserialize));
        LAVA_LAKE = FeatureDecorator.<DecoratorConfiguration, LakeLavaPlacementDecorator>register("lava_lake", new LakeLavaPlacementDecorator(ChanceDecoratorConfiguration::deserialize));
        WATER_LAKE = FeatureDecorator.<DecoratorConfiguration, LakeWaterPlacementDecorator>register("water_lake", new LakeWaterPlacementDecorator(ChanceDecoratorConfiguration::deserialize));
        DUNGEONS = FeatureDecorator.<DecoratorConfiguration, MonsterRoomPlacementDecorator>register("dungeons", new MonsterRoomPlacementDecorator(ChanceDecoratorConfiguration::deserialize));
        DARK_OAK_TREE = FeatureDecorator.<DecoratorConfiguration, DarkOakTreePlacementDecorator>register("dark_oak_tree", new DarkOakTreePlacementDecorator(NoneDecoratorConfiguration::deserialize));
        ICEBERG = FeatureDecorator.<DecoratorConfiguration, IcebergPlacementDecorator>register("iceberg", new IcebergPlacementDecorator(ChanceDecoratorConfiguration::deserialize));
        LIGHT_GEM_CHANCE = FeatureDecorator.<DecoratorConfiguration, LightGemChanceDecorator>register("light_gem_chance", new LightGemChanceDecorator(FrequencyDecoratorConfiguration::deserialize));
        END_ISLAND = FeatureDecorator.<DecoratorConfiguration, EndIslandPlacementDecorator>register("end_island", new EndIslandPlacementDecorator(NoneDecoratorConfiguration::deserialize));
        CHORUS_PLANT = FeatureDecorator.<DecoratorConfiguration, ChorusPlantPlacementDecorator>register("chorus_plant", new ChorusPlantPlacementDecorator(NoneDecoratorConfiguration::deserialize));
        END_GATEWAY = FeatureDecorator.<DecoratorConfiguration, EndGatewayPlacementDecorator>register("end_gateway", new EndGatewayPlacementDecorator(NoneDecoratorConfiguration::deserialize));
    }
}
