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

import org.apache.logging.log4j.LogManager;
import java.util.function.Function;
import net.minecraft.core.Registry;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
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.world.level.levelgen.feature.configurations.DecoratedFeatureConfiguration;
import net.minecraft.world.level.levelgen.placement.ConfiguredDecorator;
import org.apache.logging.log4j.Logger;
import com.mojang.serialization.Codec;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;

public class ConfiguredFeature<FC extends FeatureConfiguration, F extends Feature<FC>> {
    public static final ConfiguredFeature<?, ?> NOPE;
    public static final Codec<ConfiguredFeature<?, ?>> CODEC;
    public static final Logger LOGGER;
    public final F feature;
    public final FC config;
    
    public ConfiguredFeature(final F ckt, final FC cnr) {
        this.feature = ckt;
        this.config = cnr;
    }
    
    public ConfiguredFeature<?, ?> decorated(final ConfiguredDecorator<?> crl) {
        final Feature<DecoratedFeatureConfiguration> ckt3 = (this.feature instanceof AbstractFlowerFeature) ? Feature.DECORATED_FLOWER : Feature.DECORATED;
        return ckt3.configured(new DecoratedFeatureConfiguration(this, crl));
    }
    
    public WeightedConfiguredFeature<FC> weighted(final float float1) {
        return new WeightedConfiguredFeature<FC>(this, float1);
    }
    
    public boolean place(final WorldGenLevel bqu, final StructureFeatureManager bqq, final ChunkGenerator cha, final Random random, final BlockPos fu) {
        return this.feature.place(bqu, bqq, cha, random, fu, this.config);
    }
    
    static {
        NOPE = new ConfiguredFeature<Object, Object>(Feature.NO_OP, NoneFeatureConfiguration.NONE);
        CODEC = Registry.FEATURE.dispatch("name", ckb -> ckb.feature, (Function)Feature::configuredCodec).withDefault(ConfiguredFeature.NOPE);
        LOGGER = LogManager.getLogger();
    }
}
