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

package com.hypixel.hytale.builtin.portals.utils.posqueries.generators;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.portals.utils.posqueries.SpatialQueryDebug;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.builtin.portals.utils.posqueries.SpatialQuery;

public class SearchCone implements SpatialQuery
{
    private final Vector3d direction;
    private final double minRadius;
    private final double maxRadius;
    private final double maxDegrees;
    private final int attempts;
    
    public SearchCone(final Vector3d direction, final double radius, final double maxDegrees, final int attempts) {
        this(direction, radius, radius, maxDegrees, attempts);
    }
    
    public SearchCone(final Vector3d direction, final double minRadius, final double maxRadius, final double maxDegrees, final int attempts) {
        this.direction = direction;
        this.minRadius = minRadius;
        this.maxRadius = maxRadius;
        this.maxDegrees = maxDegrees;
        this.attempts = attempts;
    }
    
    @Override
    public Stream<Vector3d> createCandidates(final World world, final Vector3d origin, @Nullable final SpatialQueryDebug debug) {
        if (debug != null) {
            final String radiusFmt = (this.minRadius == this.maxRadius) ? String.format("%.1f", this.minRadius) : (String.format("%.1f", this.minRadius) + "-" + String.format("%.1f", this.maxRadius));
            debug.appendLine("Searching in a " + radiusFmt + " radius cone (max " + String.format("%.1f", this.maxDegrees) + "°) in direction " + debug.fmt(this.direction) + " from " + debug.fmt(origin));
        }
        final double maxRadians = Math.toRadians(this.maxDegrees);
        return Stream.generate(() -> {
            final ThreadLocalRandom rand = ThreadLocalRandom.current();
            final double distance = this.minRadius + rand.nextDouble() * (this.maxRadius - this.minRadius);
            final double yawOffset = (rand.nextDouble() - 0.5) * maxRadians;
            final Vector3d dir = this.direction.clone().rotateY((float)yawOffset).setLength(distance);
            return dir.add(origin);
        }).limit(this.attempts);
    }
}
