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

package com.hypixel.hytale.procedurallib.json;

import com.hypixel.hytale.procedurallib.logic.ResultBuffer;
import javax.annotation.Nullable;
import com.hypixel.hytale.procedurallib.logic.cell.MeasurementMode;
import com.hypixel.hytale.procedurallib.logic.cell.PointDistanceFunction;
import com.hypixel.hytale.procedurallib.logic.DistanceNoise;
import com.hypixel.hytale.procedurallib.logic.cell.evaluator.PointEvaluator;
import com.hypixel.hytale.procedurallib.logic.cell.CellDistanceFunction;
import com.google.gson.JsonElement;
import java.nio.file.Path;
import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.NoiseFunction;

public class DistanceNoiseJsonLoader<K extends SeedResource> extends JsonLoader<K, NoiseFunction>
{
    public DistanceNoiseJsonLoader(@Nonnull final SeedString<K> seed, final Path dataFolder, final JsonElement json) {
        super(seed.append(".DistanceNoise"), dataFolder, json);
    }
    
    @Nonnull
    @Override
    public NoiseFunction load() {
        final CellDistanceFunction cellDistanceFunction = this.loadCellDistanceFunction();
        final PointEvaluator pointEvaluator = this.loadPointEvaluator();
        final DistanceNoise.Distance2Function distance2Function = this.loadDistance2Function();
        return new LoadedDistanceNoise(cellDistanceFunction, pointEvaluator, distance2Function, this.seed.get());
    }
    
    @Nullable
    protected CellDistanceFunction loadCellDistanceFunction() {
        final MeasurementMode measurementMode = this.loadMeasurementMode();
        return new CellDistanceFunctionJsonLoader(this.seed, this.dataFolder, this.json, measurementMode, null).load();
    }
    
    @Nullable
    protected PointEvaluator loadPointEvaluator() {
        return new PointEvaluatorJsonLoader(this.seed, this.dataFolder, this.json).load();
    }
    
    @Nonnull
    protected MeasurementMode loadMeasurementMode() {
        if (this.has("Measurement")) {
            return MeasurementMode.valueOf(this.get("Measurement").getAsString());
        }
        return Constants.DEFAULT_MEASUREMENT;
    }
    
    protected DistanceNoise.Distance2Function loadDistance2Function() {
        DistanceNoise.Distance2Mode distance2Mode = Constants.DEFAULT_DISTANCE_2_MODE;
        if (this.has("Distance2Mode")) {
            distance2Mode = DistanceNoise.Distance2Mode.valueOf(this.get("Distance2Mode").getAsString());
        }
        return distance2Mode.getFunction();
    }
    
    private static class LoadedDistanceNoise extends DistanceNoise
    {
        private final SeedResource seedResource;
        
        public LoadedDistanceNoise(final CellDistanceFunction cellDistanceFunction, final PointEvaluator pointEvaluator, final Distance2Function distance2Function, final SeedResource seedResource) {
            super(cellDistanceFunction, pointEvaluator, distance2Function);
            this.seedResource = seedResource;
        }
        
        @Nonnull
        @Override
        protected ResultBuffer.ResultBuffer2d localBuffer2d() {
            return this.seedResource.localBuffer2d();
        }
        
        @Nonnull
        @Override
        protected ResultBuffer.ResultBuffer3d localBuffer3d() {
            return this.seedResource.localBuffer3d();
        }
    }
    
    public interface Constants
    {
        public static final String KEY_MEASUREMENT = "Measurement";
        public static final String KEY_DISTANCE_2_MODE = "Distance2Mode";
        public static final MeasurementMode DEFAULT_MEASUREMENT = MeasurementMode.CENTRE_DISTANCE;
        public static final DistanceNoise.Distance2Mode DEFAULT_DISTANCE_2_MODE = DistanceNoise.Distance2Mode.SUB;
    }
}
