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

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

import java.util.Set;
import com.hypixel.hytale.server.worldgen.loader.util.ColorUtil;
import com.google.gson.JsonObject;
import javax.annotation.Nonnull;
import com.google.gson.JsonArray;
import javax.annotation.Nullable;
import com.google.gson.JsonElement;
import java.nio.file.Path;
import com.hypixel.hytale.procedurallib.json.SeedString;
import java.util.Map;
import com.hypixel.hytale.server.worldgen.zone.Zone;
import com.hypixel.hytale.server.worldgen.SeedStringResource;
import com.hypixel.hytale.procedurallib.json.JsonLoader;

public class UniqueZoneEntryJsonLoader extends JsonLoader<SeedStringResource, Zone.UniqueEntry[]>
{
    protected final Map<String, Zone> zoneLookup;
    
    public UniqueZoneEntryJsonLoader(final SeedString<SeedStringResource> seed, final Path dataFolder, @Nullable final JsonElement json, final Map<String, Zone> zoneLookup) {
        super(seed, dataFolder, json);
        this.zoneLookup = zoneLookup;
    }
    
    @Nonnull
    @Override
    public Zone.UniqueEntry[] load() {
        if (this.json == null) {
            return Zone.UniqueEntry.EMPTY_ARRAY;
        }
        if (!this.json.isJsonArray()) {
            throw new Error("Unexpected type for 'UniqueZones' field, expected array");
        }
        final JsonArray arrayJson = this.json.getAsJsonArray();
        final Zone.UniqueEntry[] entries = new Zone.UniqueEntry[arrayJson.size()];
        for (int i = 0; i < arrayJson.size(); ++i) {
            final JsonElement entry = arrayJson.get(i);
            if (!entry.isJsonObject()) {
                throw new Error("Unexpected type for unique zone entry: #" + i);
            }
            entries[i] = this.loadEntry(i, entry.getAsJsonObject());
        }
        return entries;
    }
    
    protected Zone.UniqueEntry loadEntry(final int index, final JsonObject json) {
        final JsonElement zoneJson = json.get("Zone");
        if (zoneJson == null) {
            throw new Error("Missing 'Zone' field in unique zone entry: #" + index);
        }
        final JsonElement colorJson = json.get("Color");
        if (colorJson == null) {
            throw new Error("Missing 'Color' field in unique zone entry: #" + index);
        }
        final JsonElement parentJson = json.get("Parent");
        if (parentJson == null) {
            throw new Error("Missing 'Parent' field in unique zone entry: #" + index);
        }
        final JsonElement radiusJson = json.get("Radius");
        final JsonElement paddingJson = json.get("Padding");
        final Zone zone = this.zoneLookup.get(zoneJson.getAsString());
        if (zone == null) {
            throw new Error("Unknown zone '" + zoneJson.getAsString() + "' in unique zone entry: #" + index);
        }
        final int color = ColorUtil.hexString(colorJson.getAsString());
        final int[] parent = loadParentColors(index, parentJson);
        final int radius = (radiusJson != null) ? radiusJson.getAsInt() : 1;
        final int padding = (paddingJson != null) ? paddingJson.getAsInt() : 0;
        return new Zone.UniqueEntry(zone, color, parent, radius, padding);
    }
    
    protected static int[] loadParentColors(final int index, final JsonElement json) {
        if (json.isJsonArray()) {
            final JsonArray arr = json.getAsJsonArray();
            final int[] colors = new int[arr.size()];
            for (int i = 0; i < arr.size(); ++i) {
                colors[i] = ColorUtil.hexString(arr.get(i).getAsString());
            }
            return colors;
        }
        if (json.isJsonPrimitive()) {
            return new int[] { ColorUtil.hexString(json.getAsString()) };
        }
        throw new Error("Unexpected type for 'Parent' field in unique zone entry: #" + index);
    }
    
    public static void collectZones(final Set<String> zoneSet, @Nullable final JsonElement json) {
        if (json == null) {
            return;
        }
        if (!json.isJsonArray()) {
            throw new Error("Unexpected type for 'UniqueZones' field, expected array");
        }
        final JsonArray arrayJson = json.getAsJsonArray();
        for (int i = 0; i < arrayJson.size(); ++i) {
            final JsonElement entry = arrayJson.get(i);
            if (!entry.isJsonObject()) {
                throw new Error("Unexpected type for unique zone entry: #" + i);
            }
            final JsonElement zone = entry.getAsJsonObject().get("Zone");
            if (zone == null) {
                throw new Error("Missing 'Zone' field in unique zone entry: #" + i);
            }
            zoneSet.add(zone.getAsString());
        }
    }
    
    public interface Constants
    {
        public static final String KEY_ZONE = "Zone";
        public static final String KEY_COLOR = "Color";
        public static final String KEY_PARENT = "Parent";
        public static final String KEY_RADIUS = "Radius";
        public static final String KEY_PADDING = "Padding";
        public static final int DEFAULT_RADIUS = 1;
        public static final int DEFAULT_PADDING = 0;
        public static final String ERROR_ENTRIES_TYPE = "Unexpected type for 'UniqueZones' field, expected array";
        public static final String ERROR_ENTRY_TYPE = "Unexpected type for unique zone entry: #";
        public static final String ERROR_PARENT_TYPE = "Unexpected type for 'Parent' field in unique zone entry: #";
        public static final String ERROR_MISSING_ZONE = "Missing 'Zone' field in unique zone entry: #";
        public static final String ERROR_MISSING_COLOR = "Missing 'Color' field in unique zone entry: #";
        public static final String ERROR_MISSING_PARENT = "Missing 'Parent' field in unique zone entry: #";
    }
}
