// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.worldgen.loader.util;

import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
import com.hypixel.hytale.server.core.asset.type.fluid.Fluid;
import com.hypixel.hytale.procedurallib.json.NoisePropertyJsonLoader;
import javax.annotation.Nullable;
import com.hypixel.hytale.procedurallib.json.DoubleRangeJsonLoader;
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
import com.hypixel.hytale.server.worldgen.util.BlockFluidEntry;
import com.hypixel.hytale.procedurallib.supplier.IDoubleRange;
import com.hypixel.hytale.server.worldgen.util.ConstantNoiseProperty;
import com.hypixel.hytale.procedurallib.supplier.DoubleRange;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import java.nio.file.Path;
import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.json.SeedString;
import com.hypixel.hytale.server.worldgen.util.NoiseBlockArray;
import com.hypixel.hytale.server.worldgen.SeedStringResource;
import com.hypixel.hytale.procedurallib.json.JsonLoader;

public class NoiseBlockArrayJsonLoader extends JsonLoader<SeedStringResource, NoiseBlockArray>
{
    public NoiseBlockArrayJsonLoader(@Nonnull final SeedString<SeedStringResource> seed, final Path dataFolder, final JsonElement json) {
        super(seed.append(".NoiseBlockArray"), dataFolder, json);
    }
    
    @Nonnull
    @Override
    public NoiseBlockArray load() {
        if (this.json.isJsonPrimitive()) {
            return new NoiseBlockArray(new NoiseBlockArray.Entry[] { new EntryJsonLoader((SeedString<SeedStringResource>)this.seed, this.dataFolder, this.json).load() });
        }
        if (this.json.isJsonObject() && !this.has("Entries")) {
            return new NoiseBlockArray(new NoiseBlockArray.Entry[] { this.loadEntry(this.json, 0) });
        }
        JsonElement entriesElement;
        if (this.json.isJsonArray()) {
            entriesElement = this.json;
        }
        else {
            entriesElement = this.get("Entries");
        }
        if (entriesElement == null || entriesElement.isJsonNull()) {
            throw new IllegalArgumentException("Could not find entries in block array. Keyword: Entries");
        }
        final JsonArray entriesArray = entriesElement.getAsJsonArray();
        final NoiseBlockArray.Entry[] entries = new NoiseBlockArray.Entry[entriesArray.size()];
        for (int i = 0; i < entriesArray.size(); ++i) {
            try {
                entries[i] = this.loadEntry(entriesArray.get(i), i);
            }
            catch (final Throwable e) {
                throw new Error(String.format("Failed to load block array entry #%s", i), e);
            }
        }
        return new NoiseBlockArray(entries);
    }
    
    @Nonnull
    protected NoiseBlockArray.Entry loadEntry(final JsonElement element, final int i) {
        return new EntryJsonLoader((SeedString<SeedStringResource>)this.seed.append("-" + i), this.dataFolder, element).load();
    }
    
    protected static class EntryJsonLoader extends JsonLoader<SeedStringResource, NoiseBlockArray.Entry>
    {
        public EntryJsonLoader(@Nonnull final SeedString<SeedStringResource> seed, final Path dataFolder, final JsonElement json) {
            super(seed.append(".Entry"), dataFolder, json);
        }
        
        @Nonnull
        @Override
        public NoiseBlockArray.Entry load() {
            if (this.json.isJsonPrimitive()) {
                String blockName = this.json.getAsString();
                int repetitions = 1;
                if (blockName.contains(":")) {
                    final String[] parts = blockName.split(":");
                    blockName = parts[0];
                    repetitions = Integer.parseInt(parts[1]);
                }
                final BlockFluidEntry blockEntry = this.resolveBlockId(blockName);
                return new NoiseBlockArray.Entry(blockName, blockEntry, new DoubleRange.Constant(repetitions), ConstantNoiseProperty.DEFAULT_ZERO);
            }
            if (this.json.isJsonObject()) {
                final String blockName = this.get("Type").getAsString();
                final BlockFluidEntry blockEntry2 = this.resolveBlockId(blockName);
                final IDoubleRange repetitions2 = this.loadRepetitions();
                final NoiseProperty noise = this.loadNoise();
                return new NoiseBlockArray.Entry(blockName, blockEntry2, repetitions2, noise);
            }
            throw new IllegalArgumentException("Unsupported Json Entry: " + String.valueOf(this.json));
        }
        
        @Nullable
        protected IDoubleRange loadRepetitions() {
            return new DoubleRangeJsonLoader(this.seed, this.dataFolder, this.get("Repeat"), 1.0).load();
        }
        
        @Nullable
        protected NoiseProperty loadNoise() {
            NoiseProperty noise = ConstantNoiseProperty.DEFAULT_ZERO;
            if (this.has("RepeatNoise")) {
                noise = new NoisePropertyJsonLoader(this.seed, this.dataFolder, this.get("RepeatNoise")).load();
            }
            return noise;
        }
        
        @Nonnull
        protected BlockFluidEntry resolveBlockId(@Nonnull final String name) {
            try {
                if (name.startsWith("fluid#")) {
                    final String key = name.substring("fluid#".length());
                    final int index = Fluid.getAssetMap().getIndex(key);
                    if (index == Integer.MIN_VALUE) {
                        throw new IllegalArgumentException("Unknown key! " + key);
                    }
                    return new BlockFluidEntry(0, 0, index);
                }
                else {
                    final BlockPattern.BlockEntry key2 = BlockPattern.BlockEntry.decode(name);
                    final int index = BlockType.getAssetMap().getIndex(key2.blockTypeKey());
                    if (index == Integer.MIN_VALUE) {
                        throw new IllegalArgumentException("Unknown key! " + String.valueOf(key2));
                    }
                    return new BlockFluidEntry(index, key2.rotation(), 0);
                }
            }
            catch (final IllegalArgumentException e) {
                throw new Error("BlockLayer does not exist in BlockTypes", e);
            }
        }
    }
    
    public interface Constants
    {
        public static final String KEY_ENTRIES = "Entries";
        public static final String KEY_ENTRY_TYPE = "Type";
        public static final String KEY_ENTRY_REPEAT = "Repeat";
        public static final String KEY_ENTRY_REPEAT_NOISE = "RepeatNoise";
        public static final String ERROR_NO_ENTRIES = "Could not find entries in block array. Keyword: Entries";
        public static final String ERROR_ENTRY_FAIL = "Failed to load block array entry #%s";
    }
}
