package net.minecraft.client.gui.screens.worldselection;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import net.minecraft.world.level.biome.OverworldBiomeSource;
import net.minecraft.client.gui.screens.CreateFlatWorldScreen;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.client.gui.screens.CreateBuffetWorldScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.biome.FixedBiomeSource;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.chat.Component;
import java.util.Optional;
import java.util.Map;
import java.util.List;

public abstract class WorldPreset {
    public static final WorldPreset NORMAL;
    private static final WorldPreset FLAT;
    private static final WorldPreset LARGE_BIOMES;
    public static final WorldPreset AMPLIFIED;
    private static final WorldPreset SINGLE_BIOME_SURFACE;
    private static final WorldPreset SINGLE_BIOME_CAVES;
    private static final WorldPreset SINGLE_BIOME_FLOATING_ISLANDS;
    private static final WorldPreset DEBUG;
    protected static final List<WorldPreset> PRESETS;
    protected static final Map<Optional<WorldPreset>, PresetEditor> EDITORS;
    private final Component description;
    
    private WorldPreset(final String string) {
        this.description = new TranslatableComponent("generator." + string);
    }
    
    private static WorldGenSettings fromBuffetSettings(final WorldGenSettings cix, final WorldPreset due, final Biome bre) {
        final BiomeSource brh4 = new FixedBiomeSource(bre);
        NoiseGeneratorSettings ciq5;
        if (due == WorldPreset.SINGLE_BIOME_CAVES) {
            ciq5 = NoiseGeneratorSettings.Preset.CAVES.settings();
        }
        else if (due == WorldPreset.SINGLE_BIOME_FLOATING_ISLANDS) {
            ciq5 = NoiseGeneratorSettings.Preset.FLOATING_ISLANDS.settings();
        }
        else {
            ciq5 = NoiseGeneratorSettings.Preset.OVERWORLD.settings();
        }
        return new WorldGenSettings(cix.seed(), cix.generateFeatures(), cix.generateBonusChest(), WorldGenSettings.withOverworld(cix.dimensions(), new NoiseBasedChunkGenerator(brh4, cix.seed(), ciq5)));
    }
    
    private static Biome parseBuffetSettings(final WorldGenSettings cix) {
        return cix.overworld().getBiomeSource().possibleBiomes().stream().findFirst().orElse(Biomes.PLAINS);
    }
    
    public static Optional<WorldPreset> of(final WorldGenSettings cix) {
        final ChunkGenerator cha2 = cix.overworld();
        if (cha2 instanceof FlatLevelSource) {
            return Optional.<WorldPreset>of(WorldPreset.FLAT);
        }
        if (cha2 instanceof DebugLevelSource) {
            return Optional.<WorldPreset>of(WorldPreset.DEBUG);
        }
        return Optional.<WorldPreset>empty();
    }
    
    public Component description() {
        return this.description;
    }
    
    public WorldGenSettings create(final RegistryAccess.RegistryHolder a, final long long2, final boolean boolean3, final boolean boolean4) {
        return new WorldGenSettings(long2, boolean3, boolean4, WorldGenSettings.withOverworld(DimensionType.defaultDimensions(long2), this.generator(long2)));
    }
    
    protected abstract ChunkGenerator generator(final long long1);
    
    static {
        NORMAL = new WorldPreset("default") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new NoiseBasedChunkGenerator(new OverworldBiomeSource(long1, false, false), long1, NoiseGeneratorSettings.Preset.OVERWORLD.settings());
            }
        };
        FLAT = new WorldPreset("flat") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new FlatLevelSource(FlatLevelGeneratorSettings.getDefault());
            }
        };
        LARGE_BIOMES = new WorldPreset("large_biomes") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new NoiseBasedChunkGenerator(new OverworldBiomeSource(long1, false, true), long1, NoiseGeneratorSettings.Preset.OVERWORLD.settings());
            }
        };
        AMPLIFIED = new WorldPreset("amplified") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new NoiseBasedChunkGenerator(new OverworldBiomeSource(long1, false, false), long1, NoiseGeneratorSettings.Preset.AMPLIFIED.settings());
            }
        };
        SINGLE_BIOME_SURFACE = new WorldPreset("single_biome_surface") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new NoiseBasedChunkGenerator(new FixedBiomeSource(Biomes.PLAINS), long1, NoiseGeneratorSettings.Preset.OVERWORLD.settings());
            }
        };
        SINGLE_BIOME_CAVES = new WorldPreset("single_biome_caves") {
            @Override
            public WorldGenSettings create(final RegistryAccess.RegistryHolder a, final long long2, final boolean boolean3, final boolean boolean4) {
                return new WorldGenSettings(long2, boolean3, boolean4, WorldGenSettings.withOverworld(DimensionType.defaultDimensions(long2), DimensionType::defaultOverworldCaves, this.generator(long2)));
            }
            
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new NoiseBasedChunkGenerator(new FixedBiomeSource(Biomes.PLAINS), long1, NoiseGeneratorSettings.Preset.CAVES.settings());
            }
        };
        SINGLE_BIOME_FLOATING_ISLANDS = new WorldPreset("single_biome_floating_islands") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return new NoiseBasedChunkGenerator(new FixedBiomeSource(Biomes.PLAINS), long1, NoiseGeneratorSettings.Preset.FLOATING_ISLANDS.settings());
            }
        };
        DEBUG = new WorldPreset("debug_all_block_states") {
            @Override
            protected ChunkGenerator generator(final long long1) {
                return DebugLevelSource.INSTANCE;
            }
        };
        PRESETS = Lists.<WorldPreset>newArrayList(WorldPreset.NORMAL, WorldPreset.FLAT, WorldPreset.LARGE_BIOMES, WorldPreset.AMPLIFIED, WorldPreset.SINGLE_BIOME_SURFACE, WorldPreset.SINGLE_BIOME_CAVES, WorldPreset.SINGLE_BIOME_FLOATING_ISLANDS, WorldPreset.DEBUG);
        final ChunkGenerator cha3;
        final Screen screen;
        final WorldGenSettingsComponent worldGenSettingsComponent;
        final WorldGenSettings cix2;
        EDITORS = ImmutableMap.<Optional<WorldPreset>, Object>of(Optional.<WorldPreset>of(WorldPreset.FLAT), (dty, cix) -> {
            cha3 = cix.overworld();
            new CreateFlatWorldScreen(dty, cra -> {
                worldGenSettingsComponent = dty.worldGenSettingsComponent;
                new WorldGenSettings(cix.seed(), cix.generateFeatures(), cix.generateBonusChest(), WorldGenSettings.withOverworld(cix.dimensions(), new FlatLevelSource(cra)));
                worldGenSettingsComponent.updateSettings(cix2);
                return;
            }, (cha3 instanceof FlatLevelSource) ? ((FlatLevelSource)cha3).settings() : FlatLevelGeneratorSettings.getDefault());
            return screen;
        }, Optional.<WorldPreset>of(WorldPreset.SINGLE_BIOME_SURFACE), (dty, cix) -> new CreateBuffetWorldScreen(dty, bre -> dty.worldGenSettingsComponent.updateSettings(fromBuffetSettings(cix, WorldPreset.SINGLE_BIOME_SURFACE, bre)), parseBuffetSettings(cix)), Optional.<WorldPreset>of(WorldPreset.SINGLE_BIOME_CAVES), (dty, cix) -> new CreateBuffetWorldScreen(dty, bre -> dty.worldGenSettingsComponent.updateSettings(fromBuffetSettings(cix, WorldPreset.SINGLE_BIOME_CAVES, bre)), parseBuffetSettings(cix)), Optional.<WorldPreset>of(WorldPreset.SINGLE_BIOME_FLOATING_ISLANDS), (dty, cix) -> new CreateBuffetWorldScreen(dty, bre -> dty.worldGenSettingsComponent.updateSettings(fromBuffetSettings(cix, WorldPreset.SINGLE_BIOME_FLOATING_ISLANDS, bre)), parseBuffetSettings(cix)));
    }
    
    public interface PresetEditor {
        Screen createEditScreen(final CreateWorldScreen dty, final WorldGenSettings cix);
    }
}
