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

package com.hypixel.hytale.server.core.universe.world.spawn;

import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nullable;
import com.hypixel.hytale.math.util.HashUtil;
import java.util.UUID;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.math.vector.Transform;
import javax.annotation.Nonnull;
import com.hypixel.hytale.codec.builder.BuilderCodec;

public class IndividualSpawnProvider implements ISpawnProvider
{
    @Nonnull
    public static BuilderCodec<IndividualSpawnProvider> CODEC;
    private Transform[] spawnPoints;
    
    public IndividualSpawnProvider() {
    }
    
    public IndividualSpawnProvider(@Nonnull final Transform spawnPoint) {
        (this.spawnPoints = new Transform[1])[0] = spawnPoint;
    }
    
    public IndividualSpawnProvider(@Nonnull final Transform[] spawnPoints) {
        this.spawnPoints = spawnPoints;
    }
    
    @Override
    public Transform getSpawnPoint(@Nonnull final World world, @Nonnull final UUID uuid) {
        return this.spawnPoints[Math.abs((int)HashUtil.hashUuid(uuid)) % this.spawnPoints.length].clone();
    }
    
    @Override
    public Transform[] getSpawnPoints() {
        return this.spawnPoints;
    }
    
    @Nullable
    public Transform getFirstSpawnPoint() {
        return (this.spawnPoints.length == 0) ? null : this.spawnPoints[0];
    }
    
    @Override
    public boolean isWithinSpawnDistance(@Nonnull final Vector3d position, final double distance) {
        final double distanceSquared = distance * distance;
        for (final Transform point : this.spawnPoints) {
            if (position.distanceSquaredTo(point.getPosition()) < distanceSquared) {
                return true;
            }
        }
        return false;
    }
    
    static {
        IndividualSpawnProvider.CODEC = BuilderCodec.builder(IndividualSpawnProvider.class, IndividualSpawnProvider::new).documentation("A spawn provider that selects a spawn point from a list based on the player being spawned in. This gives random but consistent spawn points for players.").append(new KeyedCodec("SpawnPoints", new ArrayCodec(Transform.CODEC, Transform[]::new)), (o, i) -> o.spawnPoints = i, o -> o.spawnPoints).documentation("The list of spawn points to select from.").add().build();
    }
}
