package net.minecraft.world.level.chunk;

import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.Level;
import net.minecraft.core.Registry;
import java.util.function.Supplier;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.DebugGeneratorSettings;
import net.minecraft.world.level.levelgen.TheEndLevelSource;
import net.minecraft.world.level.levelgen.TheEndGeneratorSettings;
import net.minecraft.world.level.levelgen.NetherLevelSource;
import net.minecraft.world.level.levelgen.NetherGeneratorSettings;
import net.minecraft.world.level.levelgen.OverworldLevelSource;
import net.minecraft.world.level.levelgen.OverworldGeneratorSettings;
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;

public class ChunkGeneratorType<C extends ChunkGeneratorSettings, T extends ChunkGenerator<C>> implements ChunkGeneratorFactory<C, T> {
    public static final ChunkGeneratorType<OverworldGeneratorSettings, OverworldLevelSource> SURFACE;
    public static final ChunkGeneratorType<NetherGeneratorSettings, NetherLevelSource> CAVES;
    public static final ChunkGeneratorType<TheEndGeneratorSettings, TheEndLevelSource> FLOATING_ISLANDS;
    public static final ChunkGeneratorType<DebugGeneratorSettings, DebugLevelSource> DEBUG;
    public static final ChunkGeneratorType<FlatLevelGeneratorSettings, FlatLevelSource> FLAT;
    private final ChunkGeneratorFactory<C, T> factory;
    private final boolean isPublic;
    private final Supplier<C> settingsFactory;
    
    private static <C extends ChunkGeneratorSettings, T extends ChunkGenerator<C>> ChunkGeneratorType<C, T> register(final String string, final ChunkGeneratorFactory<C, T> cab, final Supplier<C> supplier, final boolean boolean4) {
        return Registry.<ChunkGeneratorType<C, T>>register(Registry.CHUNK_GENERATOR_TYPE, string, new ChunkGeneratorType<C, T>(cab, boolean4, supplier));
    }
    
    public ChunkGeneratorType(final ChunkGeneratorFactory<C, T> cab, final boolean boolean2, final Supplier<C> supplier) {
        this.factory = cab;
        this.isPublic = boolean2;
        this.settingsFactory = supplier;
    }
    
    @Override
    public T create(final Level bjw, final BiomeSource bkw, final C cbq) {
        return this.factory.create(bjw, bkw, cbq);
    }
    
    public C createSettings() {
        return this.settingsFactory.get();
    }
    
    public boolean isPublic() {
        return this.isPublic;
    }
    
    static {
        SURFACE = ChunkGeneratorType.<OverworldGeneratorSettings, OverworldLevelSource>register("surface", OverworldLevelSource::new, OverworldGeneratorSettings::new, true);
        CAVES = ChunkGeneratorType.<NetherGeneratorSettings, NetherLevelSource>register("caves", NetherLevelSource::new, NetherGeneratorSettings::new, true);
        FLOATING_ISLANDS = ChunkGeneratorType.<TheEndGeneratorSettings, TheEndLevelSource>register("floating_islands", TheEndLevelSource::new, TheEndGeneratorSettings::new, true);
        DEBUG = ChunkGeneratorType.<DebugGeneratorSettings, DebugLevelSource>register("debug", DebugLevelSource::new, DebugGeneratorSettings::new, false);
        FLAT = ChunkGeneratorType.<FlatLevelGeneratorSettings, FlatLevelSource>register("flat", FlatLevelSource::new, FlatLevelGeneratorSettings::new, false);
    }
}
