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

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

import java.util.Arrays;
import com.hypixel.hytale.procedurallib.logic.ResultBuffer;
import com.hypixel.hytale.math.util.HashUtil;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.worldgen.chunk.MaskProvider;
import com.hypixel.hytale.procedurallib.logic.point.IPointGenerator;

public class ZonePatternGenerator
{
    protected final IPointGenerator pointGenerator;
    protected final Zone[] zones;
    protected final Zone.Unique[] uniqueZones;
    protected final MaskProvider maskProvider;
    protected final ZoneColorMapping zoneColorMapping;
    
    public ZonePatternGenerator(final IPointGenerator pointGenerator, final Zone[] zones, final Zone.Unique[] uniqueZones, final MaskProvider maskProvider, final ZoneColorMapping zoneColorMapping) {
        this.pointGenerator = pointGenerator;
        this.zones = zones;
        this.uniqueZones = uniqueZones;
        this.maskProvider = maskProvider;
        this.zoneColorMapping = zoneColorMapping;
    }
    
    public Zone[] getZones() {
        return this.zones;
    }
    
    public Zone.Unique[] getUniqueZones() {
        return this.uniqueZones;
    }
    
    @Nonnull
    public ZoneGeneratorResult generate(final int seed, final double x, final double z) {
        return this.generate(seed, x, z, new ZoneGeneratorResult());
    }
    
    @Nonnull
    public ZoneGeneratorResult generate(final int seed, final double x, final double z, @Nonnull final ZoneGeneratorResult result) {
        final double rx = this.maskProvider.getX(seed, x, z);
        final double rz = this.maskProvider.getY(seed, x, z);
        final int mask = this.maskProvider.get(seed, rx, rz) & 0xFFFFFF;
        final Zone[] zoneArr = this.zoneColorMapping.get(mask);
        if (zoneArr == null) {
            throw new Error("Unknown zone colour mapping for mask: " + mask);
        }
        if (zoneArr.length == 1) {
            double distance = Double.POSITIVE_INFINITY;
            if (this.maskProvider.inBounds(rx, rz)) {
                distance = this.maskProvider.distance(rx, rz);
            }
            result.setZone(zoneArr[0]);
            result.setBorderDistance(distance);
        }
        else {
            this.getZone(seed, x, z, result, zoneArr);
        }
        return result;
    }
    
    protected void getZone(final int seed, final double x, final double z, @Nonnull final ZoneGeneratorResult result, @Nonnull final Zone[] zoneArr) {
        final ResultBuffer.ResultBuffer2d buf = this.pointGenerator.nearest2D(seed, x, z);
        final int index = ((int)HashUtil.hash(seed, buf.ix, buf.iy) & Integer.MAX_VALUE) % zoneArr.length;
        result.setZone(zoneArr[index]);
        result.setBorderDistance(buf.distance);
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "ZonePatternGenerator{pointGenerator=" + String.valueOf(this.pointGenerator) + ", zones=" + Arrays.toString(this.zones) + ", maskProvider=" + String.valueOf(this.maskProvider) + ", zoneColorMapping=" + String.valueOf(this.zoneColorMapping);
    }
}
