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

package com.hypixel.hytale.procedurallib.json;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.property.NoiseProperty;
import javax.annotation.Nullable;
import com.google.gson.JsonElement;
import java.nio.file.Path;
import com.hypixel.hytale.procedurallib.property.BlendNoiseProperty;

public class BlendNoisePropertyJsonLoader<K extends SeedResource> extends JsonLoader<K, BlendNoiseProperty>
{
    public BlendNoisePropertyJsonLoader(final SeedString<K> seed, final Path dataFolder, @Nullable final JsonElement json) {
        super(seed, dataFolder, json);
    }
    
    @Nonnull
    @Override
    public BlendNoiseProperty load() {
        final NoiseProperty alpha = this.loadAlpha();
        final NoiseProperty[] noise = this.loadNoise();
        final double[] thresholds = this.loadThresholds();
        validate(noise, thresholds);
        return new BlendNoiseProperty(alpha, noise, thresholds);
    }
    
    protected NoiseProperty loadAlpha() {
        return new NoisePropertyJsonLoader(this.seed, this.dataFolder, this.mustGetObject("Alpha", null)).load();
    }
    
    protected NoiseProperty[] loadNoise() {
        final JsonArray noise = this.mustGetArray("Noise", Constants.EMPTY_ARRAY);
        final NoiseProperty[] noises = new NoiseProperty[noise.size()];
        for (int i = 0; i < noise.size(); ++i) {
            noises[i] = new NoisePropertyJsonLoader(this.seed, this.dataFolder, noise.get(i)).load();
        }
        return noises;
    }
    
    protected double[] loadThresholds() {
        final JsonArray thresholds = this.mustGetArray("Thresholds", Constants.EMPTY_ARRAY);
        final double[] values = new double[thresholds.size()];
        for (int i = 0; i < thresholds.size(); ++i) {
            values[i] = JsonLoader.mustGet("$" + i, thresholds.get(i), (Number)null, Number.class, JsonLoader::isNumber, JsonElement::getAsNumber).doubleValue();
        }
        return values;
    }
    
    protected static void validate(final NoiseProperty[] noises, final double[] thresholds) {
        if (noises.length != thresholds.length) {
            throw new IllegalStateException("Number of noises must match number of thresholds");
        }
        double previous = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < thresholds.length; ++i) {
            if (thresholds[i] <= previous) {
                throw new IllegalStateException("Thresholds must be in ascending order and cannot be equal");
            }
            previous = thresholds[i];
        }
    }
    
    public interface Constants
    {
        public static final String KEY_ALPHA = "Alpha";
        public static final String KEY_NOISE = "Noise";
        public static final String KEY_THRESHOLDS = "Thresholds";
        public static final JsonArray EMPTY_ARRAY = new JsonArray();
    }
}
