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

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.function.Function;
import net.minecraft.world.level.levelgen.feature.blockplacers.BlockPlacerType;
import net.minecraft.resources.ResourceLocation;
import java.util.function.Supplier;
import net.minecraft.core.Registry;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProviderType;
import java.util.Map;
import java.util.stream.Stream;
import com.google.common.collect.ImmutableMap;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.types.DynamicOps;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Block;
import java.util.Set;
import net.minecraft.world.level.levelgen.feature.blockplacers.BlockPlacer;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;

public class RandomPatchConfiguration implements FeatureConfiguration {
    public final BlockStateProvider stateProvider;
    public final BlockPlacer blockPlacer;
    public final Set<Block> whitelist;
    public final Set<BlockState> blacklist;
    public final int tries;
    public final int xspread;
    public final int yspread;
    public final int zspread;
    public final boolean canReplace;
    public final boolean project;
    public final boolean needWater;
    
    private RandomPatchConfiguration(final BlockStateProvider chw, final BlockPlacer cfw, final Set<Block> set3, final Set<BlockState> set4, final int integer5, final int integer6, final int integer7, final int integer8, final boolean boolean9, final boolean boolean10, final boolean boolean11) {
        this.stateProvider = chw;
        this.blockPlacer = cfw;
        this.whitelist = set3;
        this.blacklist = set4;
        this.tries = integer5;
        this.xspread = integer6;
        this.yspread = integer7;
        this.zspread = integer8;
        this.canReplace = boolean9;
        this.project = boolean10;
        this.needWater = boolean11;
    }
    
    @Override
    public <T> Dynamic<T> serialize(final DynamicOps<T> dynamicOps) {
        final ImmutableMap.Builder<T, T> builder3 = ImmutableMap.<T, T>builder();
        builder3.put((T)dynamicOps.createString("state_provider"), this.stateProvider.<T>serialize(dynamicOps)).put((T)dynamicOps.createString("block_placer"), this.blockPlacer.<T>serialize(dynamicOps)).put((T)dynamicOps.createString("whitelist"), (T)dynamicOps.createList((Stream)this.whitelist.stream().map(bph -> BlockState.<T>serialize(dynamicOps, bph.defaultBlockState()).getValue()))).put((T)dynamicOps.createString("blacklist"), (T)dynamicOps.createList((Stream)this.blacklist.stream().map(byj -> BlockState.<T>serialize(dynamicOps, byj).getValue()))).put((T)dynamicOps.createString("tries"), (T)dynamicOps.createInt(this.tries)).put((T)dynamicOps.createString("xspread"), (T)dynamicOps.createInt(this.xspread)).put((T)dynamicOps.createString("yspread"), (T)dynamicOps.createInt(this.yspread)).put((T)dynamicOps.createString("zspread"), (T)dynamicOps.createInt(this.zspread)).put((T)dynamicOps.createString("can_replace"), (T)dynamicOps.createBoolean(this.canReplace)).put((T)dynamicOps.createString("project"), (T)dynamicOps.createBoolean(this.project)).put((T)dynamicOps.createString("need_water"), (T)dynamicOps.createBoolean(this.needWater));
        return (Dynamic<T>)new Dynamic((DynamicOps)dynamicOps, dynamicOps.createMap((Map)builder3.build()));
    }
    
    public static <T> RandomPatchConfiguration deserialize(final Dynamic<T> dynamic) {
        final BlockStateProviderType<?> chx2 = Registry.BLOCKSTATE_PROVIDER_TYPES.get(new ResourceLocation(dynamic.get("state_provider").get("type").asString().<Throwable>orElseThrow(RuntimeException::new)));
        final BlockPlacerType<?> cfx3 = Registry.BLOCK_PLACER_TYPES.get(new ResourceLocation(dynamic.get("block_placer").get("type").asString().<Throwable>orElseThrow(RuntimeException::new)));
        return new RandomPatchConfiguration((BlockStateProvider)chx2.deserialize(dynamic.get("state_provider").orElseEmptyMap()), (BlockPlacer)cfx3.deserialize(dynamic.get("block_placer").orElseEmptyMap()), (Set<Block>)dynamic.get("whitelist").asList((Function)BlockState::deserialize).stream().map(BlockState::getBlock).collect(Collectors.toSet()), Sets.newHashSet(dynamic.get("blacklist").asList((Function)BlockState::deserialize)), dynamic.get("tries").asInt(128), dynamic.get("xspread").asInt(7), dynamic.get("yspread").asInt(3), dynamic.get("zspread").asInt(7), dynamic.get("can_replace").asBoolean(false), dynamic.get("project").asBoolean(true), dynamic.get("need_water").asBoolean(false));
    }
    
    public static class GrassConfigurationBuilder {
        private final BlockStateProvider stateProvider;
        private final BlockPlacer blockPlacer;
        private Set<Block> whitelist;
        private Set<BlockState> blacklist;
        private int tries;
        private int xspread;
        private int yspread;
        private int zspread;
        private boolean canReplace;
        private boolean project;
        private boolean needWater;
        
        public GrassConfigurationBuilder(final BlockStateProvider chw, final BlockPlacer cfw) {
            this.whitelist = ImmutableSet.of();
            this.blacklist = ImmutableSet.of();
            this.tries = 64;
            this.xspread = 7;
            this.yspread = 3;
            this.zspread = 7;
            this.project = true;
            this.needWater = false;
            this.stateProvider = chw;
            this.blockPlacer = cfw;
        }
        
        public GrassConfigurationBuilder whitelist(final Set<Block> set) {
            this.whitelist = set;
            return this;
        }
        
        public GrassConfigurationBuilder blacklist(final Set<BlockState> set) {
            this.blacklist = set;
            return this;
        }
        
        public GrassConfigurationBuilder tries(final int integer) {
            this.tries = integer;
            return this;
        }
        
        public GrassConfigurationBuilder xspread(final int integer) {
            this.xspread = integer;
            return this;
        }
        
        public GrassConfigurationBuilder yspread(final int integer) {
            this.yspread = integer;
            return this;
        }
        
        public GrassConfigurationBuilder zspread(final int integer) {
            this.zspread = integer;
            return this;
        }
        
        public GrassConfigurationBuilder canReplace() {
            this.canReplace = true;
            return this;
        }
        
        public GrassConfigurationBuilder noProjection() {
            this.project = false;
            return this;
        }
        
        public GrassConfigurationBuilder needWater() {
            this.needWater = true;
            return this;
        }
        
        public RandomPatchConfiguration build() {
            return new RandomPatchConfiguration(this.stateProvider, this.blockPlacer, this.whitelist, this.blacklist, this.tries, this.xspread, this.yspread, this.zspread, this.canReplace, this.project, this.needWater, null);
        }
    }
}
