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

package com.hypixel.hytale.server.npc.corecomponents.movement.builders;

import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.hypixel.hytale.server.npc.asset.builder.Feature;
import com.hypixel.hytale.server.npc.asset.builder.validators.RelationalOperator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSingleValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleArrayValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSequenceValidator;
import com.google.gson.JsonElement;
import com.hypixel.hytale.server.npc.asset.builder.BuilderDescriptorState;
import com.hypixel.hytale.server.npc.corecomponents.movement.BodyMotionFind;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import com.hypixel.hytale.server.npc.asset.builder.holder.DoubleHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.NumberArrayHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.BooleanHolder;

public class BuilderBodyMotionFind extends BuilderBodyMotionFindWithTarget
{
    private static final double[] DEFAULT_HEIGHT_DIFFERENCE;
    private final BooleanHolder reachable;
    private final NumberArrayHolder heightDifference;
    private final DoubleHolder slowDownDistance;
    private final DoubleHolder stopDistance;
    private final DoubleHolder abortDistance;
    private final DoubleHolder falloff;
    private final DoubleHolder switchToSteeringDistance;
    
    public BuilderBodyMotionFind() {
        this.reachable = new BooleanHolder();
        this.heightDifference = new NumberArrayHolder();
        this.slowDownDistance = new DoubleHolder();
        this.stopDistance = new DoubleHolder();
        this.abortDistance = new DoubleHolder();
        this.falloff = new DoubleHolder();
        this.switchToSteeringDistance = new DoubleHolder();
    }
    
    @Override
    public BodyMotionFind build(@Nonnull final BuilderSupport builderSupport) {
        return new BodyMotionFind(this, builderSupport);
    }
    
    @Nonnull
    @Override
    public String getShortDescription() {
        return "Chase target";
    }
    
    @Nonnull
    @Override
    public String getLongDescription() {
        return "Move towards a target using path finding or steering";
    }
    
    @Nonnull
    @Override
    public BuilderDescriptorState getBuilderDescriptorState() {
        return BuilderDescriptorState.Experimental;
    }
    
    @Nonnull
    @Override
    public BuilderBodyMotionFind readConfig(@Nonnull final JsonElement data) {
        super.readConfig(data);
        this.getBoolean(data, "Reachable", this.reachable, false, BuilderDescriptorState.Experimental, "Target must be reachable so that hitboxes can overlap", null);
        this.getDoubleRange(data, "HeightDifference", this.heightDifference, BuilderBodyMotionFind.DEFAULT_HEIGHT_DIFFERENCE, DoubleSequenceValidator.monotonic(), BuilderDescriptorState.Experimental, "Height difference allowed to target", null);
        this.getDouble(data, "SlowDownDistance", this.slowDownDistance, 8.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Distance when to slow down when approaching", null);
        this.getDouble(data, "StopDistance", this.stopDistance, 10.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Distance to stop at", null);
        this.getDouble(data, "AbortDistance", this.abortDistance, 96.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Distance to abort behaviour", null);
        this.getDouble(data, "Falloff", this.falloff, 3.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Deceleration when approaching target", null);
        this.getDouble(data, "SwitchToSteeringDistance", this.switchToSteeringDistance, 20.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "Distance below NPC can test if target is reachable and abort existing path", null);
        this.validateDoubleRelation(this.slowDownDistance, RelationalOperator.GreaterEqual, this.stopDistance);
        this.requireFeature(Feature.AnyPosition);
        return this;
    }
    
    public boolean getReachable(@Nonnull final BuilderSupport support) {
        return this.reachable.get(support.getExecutionContext());
    }
    
    public double getStopDistance(@Nonnull final BuilderSupport support) {
        return this.stopDistance.get(support.getExecutionContext());
    }
    
    public double[] getHeightDifference(@Nonnull final BuilderSupport support) {
        return this.heightDifference.get(support.getExecutionContext());
    }
    
    public double getAbortDistance(@Nonnull final BuilderSupport support) {
        return this.abortDistance.get(support.getExecutionContext());
    }
    
    public double getFalloff(@Nonnull final BuilderSupport support) {
        return this.falloff.get(support.getExecutionContext());
    }
    
    public double getSlowDownDistance(@Nonnull final BuilderSupport builderSupport) {
        return this.slowDownDistance.get(builderSupport.getExecutionContext());
    }
    
    public double getSwitchToSteeringDistance(@Nonnull final BuilderSupport support) {
        return this.switchToSteeringDistance.get(support.getExecutionContext());
    }
    
    static {
        DEFAULT_HEIGHT_DIFFERENCE = new double[] { -1.0, 1.0 };
    }
}
