package net.minecraft.world.level.dimension;

import net.minecraft.world.phys.Vec3;
import net.minecraft.util.Mth;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.tags.BlockTags;
import javax.annotation.Nullable;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.state.BlockState;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.minecraft.world.level.biome.CheckerboardColumnBiomeSource;
import net.minecraft.world.level.biome.OverworldBiomeSource;
import net.minecraft.world.level.biome.FixedBiomeSource;
import net.minecraft.world.level.levelgen.OverworldLevelSource;
import net.minecraft.world.level.levelgen.TheEndLevelSource;
import net.minecraft.world.level.levelgen.NetherLevelSource;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.DebugGeneratorSettings;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.OverworldGeneratorSettings;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.levelgen.TheEndGeneratorSettings;
import net.minecraft.world.level.levelgen.NetherGeneratorSettings;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.biome.OverworldBiomeSourceSettings;
import net.minecraft.world.level.biome.CheckerboardBiomeSourceSettings;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.Registry;
import com.mojang.datafixers.types.JsonOps;
import com.google.gson.JsonElement;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.FixedBiomeSourceSettings;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import com.mojang.datafixers.types.DynamicOps;
import com.mojang.datafixers.Dynamic;
import net.minecraft.nbt.NbtOps;
import net.minecraft.world.level.LevelType;
import net.minecraft.world.level.biome.BiomeSourceType;
import net.minecraft.world.level.chunk.ChunkGeneratorType;
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.Level;

public class NormalDimension extends Dimension {
    public NormalDimension(final Level bjw, final DimensionType cbi) {
        super(bjw, cbi, 0.0f);
    }
    
    @Override
    public DimensionType getType() {
        return DimensionType.OVERWORLD;
    }
    
    @Override
    public ChunkGenerator<? extends ChunkGeneratorSettings> createRandomLevelGenerator() {
        final LevelType bkd2 = this.level.getLevelData().getGeneratorType();
        final ChunkGeneratorType<FlatLevelGeneratorSettings, FlatLevelSource> cac3 = ChunkGeneratorType.FLAT;
        final ChunkGeneratorType<DebugGeneratorSettings, DebugLevelSource> cac4 = ChunkGeneratorType.DEBUG;
        final ChunkGeneratorType<NetherGeneratorSettings, NetherLevelSource> cac5 = ChunkGeneratorType.CAVES;
        final ChunkGeneratorType<TheEndGeneratorSettings, TheEndLevelSource> cac6 = ChunkGeneratorType.FLOATING_ISLANDS;
        final ChunkGeneratorType<OverworldGeneratorSettings, OverworldLevelSource> cac7 = ChunkGeneratorType.SURFACE;
        final BiomeSourceType<FixedBiomeSourceSettings, FixedBiomeSource> bky8 = BiomeSourceType.FIXED;
        final BiomeSourceType<OverworldBiomeSourceSettings, OverworldBiomeSource> bky9 = BiomeSourceType.VANILLA_LAYERED;
        final BiomeSourceType<CheckerboardBiomeSourceSettings, CheckerboardColumnBiomeSource> bky10 = BiomeSourceType.CHECKERBOARD;
        if (bkd2 == LevelType.FLAT) {
            final FlatLevelGeneratorSettings ciy11 = FlatLevelGeneratorSettings.fromObject(new Dynamic((DynamicOps)NbtOps.INSTANCE, this.level.getLevelData().getGeneratorOptions()));
            final FixedBiomeSourceSettings blv12 = bky8.createSettings(this.level.getLevelData()).setBiome(ciy11.getBiome());
            return cac3.create(this.level, bky8.create(blv12), ciy11);
        }
        if (bkd2 == LevelType.DEBUG_ALL_BLOCK_STATES) {
            final FixedBiomeSourceSettings blv13 = bky8.createSettings(this.level.getLevelData()).setBiome(Biomes.PLAINS);
            return cac4.create(this.level, bky8.create(blv13), cac4.createSettings());
        }
        if (bkd2 == LevelType.BUFFET) {
            BiomeSource bkw11 = null;
            final JsonElement jsonElement12 = (JsonElement)Dynamic.convert((DynamicOps)NbtOps.INSTANCE, (DynamicOps)JsonOps.INSTANCE, this.level.getLevelData().getGeneratorOptions());
            final JsonObject jsonObject13 = jsonElement12.getAsJsonObject();
            final JsonObject jsonObject14 = jsonObject13.getAsJsonObject("biome_source");
            if (jsonObject14 != null && jsonObject14.has("type") && jsonObject14.has("options")) {
                final BiomeSourceType<?, ?> bky11 = Registry.BIOME_SOURCE_TYPE.get(new ResourceLocation(jsonObject14.getAsJsonPrimitive("type").getAsString()));
                final JsonObject jsonObject15 = jsonObject14.getAsJsonObject("options");
                Biome[] arr17 = { Biomes.OCEAN };
                if (jsonObject15.has("biomes")) {
                    final JsonArray jsonArray18 = jsonObject15.getAsJsonArray("biomes");
                    arr17 = ((jsonArray18.size() > 0) ? new Biome[jsonArray18.size()] : new Biome[] { Biomes.OCEAN });
                    for (int integer19 = 0; integer19 < jsonArray18.size(); ++integer19) {
                        arr17[integer19] = Registry.BIOME.getOptional(new ResourceLocation(jsonArray18.get(integer19).getAsString())).orElse(Biomes.OCEAN);
                    }
                }
                if (BiomeSourceType.FIXED == bky11) {
                    final FixedBiomeSourceSettings blv14 = bky8.createSettings(this.level.getLevelData()).setBiome(arr17[0]);
                    bkw11 = bky8.create(blv14);
                }
                if (BiomeSourceType.CHECKERBOARD == bky11) {
                    final int integer20 = jsonObject15.has("size") ? jsonObject15.getAsJsonPrimitive("size").getAsInt() : 2;
                    final CheckerboardBiomeSourceSettings bld19 = bky10.createSettings(this.level.getLevelData()).setAllowedBiomes(arr17).setSize(integer20);
                    bkw11 = bky10.create(bld19);
                }
                if (BiomeSourceType.VANILLA_LAYERED == bky11) {
                    final OverworldBiomeSourceSettings bmz18 = bky9.createSettings(this.level.getLevelData());
                    bkw11 = bky9.create(bmz18);
                }
            }
            if (bkw11 == null) {
                bkw11 = bky8.create(bky8.createSettings(this.level.getLevelData()).setBiome(Biomes.OCEAN));
            }
            BlockState byj15 = Blocks.STONE.defaultBlockState();
            BlockState byj16 = Blocks.WATER.defaultBlockState();
            final JsonObject jsonObject16 = jsonObject13.getAsJsonObject("chunk_generator");
            if (jsonObject16 != null && jsonObject16.has("options")) {
                final JsonObject jsonObject17 = jsonObject16.getAsJsonObject("options");
                if (jsonObject17.has("default_block")) {
                    final String string19 = jsonObject17.getAsJsonPrimitive("default_block").getAsString();
                    byj15 = Registry.BLOCK.get(new ResourceLocation(string19)).defaultBlockState();
                }
                if (jsonObject17.has("default_fluid")) {
                    final String string19 = jsonObject17.getAsJsonPrimitive("default_fluid").getAsString();
                    byj16 = Registry.BLOCK.get(new ResourceLocation(string19)).defaultBlockState();
                }
            }
            if (jsonObject16 != null && jsonObject16.has("type")) {
                final ChunkGeneratorType<?, ?> cac8 = Registry.CHUNK_GENERATOR_TYPE.get(new ResourceLocation(jsonObject16.getAsJsonPrimitive("type").getAsString()));
                if (ChunkGeneratorType.CAVES == cac8) {
                    final NetherGeneratorSettings cbw19 = cac5.createSettings();
                    cbw19.setDefaultBlock(byj15);
                    cbw19.setDefaultFluid(byj16);
                    return cac5.create(this.level, bkw11, cbw19);
                }
                if (ChunkGeneratorType.FLOATING_ISLANDS == cac8) {
                    final TheEndGeneratorSettings ccd19 = cac6.createSettings();
                    ccd19.setSpawnPosition(new BlockPos(0, 64, 0));
                    ccd19.setDefaultBlock(byj15);
                    ccd19.setDefaultFluid(byj16);
                    return cac6.create(this.level, bkw11, ccd19);
                }
            }
            final OverworldGeneratorSettings cbz18 = cac7.createSettings();
            cbz18.setDefaultBlock(byj15);
            cbz18.setDefaultFluid(byj16);
            return cac7.create(this.level, bkw11, cbz18);
        }
        final OverworldGeneratorSettings cbz19 = cac7.createSettings();
        final OverworldBiomeSourceSettings bmz19 = bky9.createSettings(this.level.getLevelData()).setGeneratorSettings(cbz19);
        return cac7.create(this.level, bky9.create(bmz19), cbz19);
    }
    
    @Nullable
    @Override
    public BlockPos getSpawnPosInChunk(final ChunkPos bjh, final boolean boolean2) {
        for (int integer4 = bjh.getMinBlockX(); integer4 <= bjh.getMaxBlockX(); ++integer4) {
            for (int integer5 = bjh.getMinBlockZ(); integer5 <= bjh.getMaxBlockZ(); ++integer5) {
                final BlockPos fk6 = this.getValidSpawnPosition(integer4, integer5, boolean2);
                if (fk6 != null) {
                    return fk6;
                }
            }
        }
        return null;
    }
    
    @Nullable
    @Override
    public BlockPos getValidSpawnPosition(final int integer1, final int integer2, final boolean boolean3) {
        final BlockPos.MutableBlockPos a5 = new BlockPos.MutableBlockPos(integer1, 0, integer2);
        final Biome bkt6 = this.level.getBiome(a5);
        final BlockState byj7 = bkt6.getSurfaceBuilderConfig().getTopMaterial();
        if (boolean3 && !byj7.getBlock().is(BlockTags.VALID_SPAWN)) {
            return null;
        }
        final LevelChunk cal8 = this.level.getChunk(integer1 >> 4, integer2 >> 4);
        final int integer3 = cal8.getHeight(Heightmap.Types.MOTION_BLOCKING, integer1 & 0xF, integer2 & 0xF);
        if (integer3 < 0) {
            return null;
        }
        if (cal8.getHeight(Heightmap.Types.WORLD_SURFACE, integer1 & 0xF, integer2 & 0xF) > cal8.getHeight(Heightmap.Types.OCEAN_FLOOR, integer1 & 0xF, integer2 & 0xF)) {
            return null;
        }
        for (int integer4 = integer3 + 1; integer4 >= 0; --integer4) {
            a5.set(integer1, integer4, integer2);
            final BlockState byj8 = this.level.getBlockState(a5);
            if (!byj8.getFluidState().isEmpty()) {
                break;
            }
            if (byj8.equals(byj7)) {
                return a5.above().immutable();
            }
        }
        return null;
    }
    
    @Override
    public float getTimeOfDay(final long long1, final float float2) {
        final double double5 = Mth.frac(long1 / 24000.0 - 0.25);
        final double double6 = 0.5 - Math.cos(double5 * 3.141592653589793) / 2.0;
        return (float)(double5 * 2.0 + double6) / 3.0f;
    }
    
    @Override
    public boolean isNaturalDimension() {
        return true;
    }
    
    @Override
    public Vec3 getFogColor(final float float1, final float float2) {
        float float3 = Mth.cos(float1 * 6.2831855f) * 2.0f + 0.5f;
        float3 = Mth.clamp(float3, 0.0f, 1.0f);
        float float4 = 0.7529412f;
        float float5 = 0.84705883f;
        float float6 = 1.0f;
        float4 *= float3 * 0.94f + 0.06f;
        float5 *= float3 * 0.94f + 0.06f;
        float6 *= float3 * 0.91f + 0.09f;
        return new Vec3(float4, float5, float6);
    }
    
    @Override
    public boolean mayRespawn() {
        return true;
    }
    
    @Override
    public boolean isFoggyAt(final int integer1, final int integer2) {
        return false;
    }
}
