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

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

import com.hypixel.hytale.server.core.asset.type.blockset.config.BlockSet;
import com.hypixel.hytale.server.npc.asset.builder.Feature;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSingleValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.AssetValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.asset.BlockSetExistsValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleRangeValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.StringValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.StringNotEmptyValidator;
import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.google.gson.JsonElement;
import com.hypixel.hytale.server.npc.asset.builder.BuilderDescriptorState;
import com.hypixel.hytale.server.npc.corecomponents.world.SensorSearchRay;
import com.hypixel.hytale.server.npc.instructions.Sensor;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.npc.asset.builder.holder.AssetHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.DoubleHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.FloatHolder;
import com.hypixel.hytale.server.npc.asset.builder.holder.StringHolder;
import com.hypixel.hytale.server.npc.corecomponents.builders.BuilderSensorBase;

public class BuilderSensorSearchRay extends BuilderSensorBase
{
    protected final StringHolder id;
    protected final FloatHolder angle;
    protected final DoubleHolder range;
    protected final AssetHolder blockSet;
    protected final FloatHolder minRetestAngle;
    protected final DoubleHolder minRetestMove;
    protected final DoubleHolder throttleTime;
    
    public BuilderSensorSearchRay() {
        this.id = new StringHolder();
        this.angle = new FloatHolder();
        this.range = new DoubleHolder();
        this.blockSet = new AssetHolder();
        this.minRetestAngle = new FloatHolder();
        this.minRetestMove = new DoubleHolder();
        this.throttleTime = new DoubleHolder();
    }
    
    @Nonnull
    @Override
    public String getShortDescription() {
        return "Fire a ray at a specific angle to see if what it hits matches a given sought block";
    }
    
    @Nonnull
    @Override
    public String getLongDescription() {
        return this.getShortDescription();
    }
    
    @Nonnull
    @Override
    public Sensor build(@Nonnull final BuilderSupport builderSupport) {
        return new SensorSearchRay(this, builderSupport);
    }
    
    @Nonnull
    @Override
    public BuilderDescriptorState getBuilderDescriptorState() {
        return BuilderDescriptorState.Stable;
    }
    
    @Nonnull
    @Override
    public Builder<Sensor> readConfig(@Nonnull final JsonElement data) {
        this.requireString(data, "Name", this.id, StringNotEmptyValidator.get(), BuilderDescriptorState.Stable, "The id of this search ray sensor so the position can be cached", null);
        this.requireFloat(data, "Angle", this.angle, DoubleRangeValidator.between(-90.0, 90.0), BuilderDescriptorState.Stable, "Angle to fire the ray", "Angle to fire the ray. Horizontal is 0. Positive is downwards");
        this.requireDouble(data, "Range", this.range, DoubleRangeValidator.fromExclToIncl(0.0, 96.0), BuilderDescriptorState.Stable, "How far to search", null);
        this.requireAsset(data, "Blocks", this.blockSet, BlockSetExistsValidator.required(), BuilderDescriptorState.Stable, "The blockset to search for", null);
        this.getFloat(data, "MinRetestAngle", this.minRetestAngle, 5.0, DoubleRangeValidator.between(0.0, 360.0), BuilderDescriptorState.Stable, "The minimum change in NPC rotation before rays stop being throttled", null);
        this.getDouble(data, "MinRetestMove", this.minRetestMove, 1.0, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "The minimum distance the NPC needs to move while facing the same direction before rays stop being throttled", null);
        this.getDouble(data, "ThrottleTime", this.throttleTime, 0.5, DoubleSingleValidator.greater0(), BuilderDescriptorState.Stable, "The delay between retests when an NPC is facing the same direction", null);
        this.provideFeature(Feature.Position);
        return this;
    }
    
    public float getAngle(@Nonnull final BuilderSupport support) {
        return this.angle.get(support.getExecutionContext()) * 0.017453292f;
    }
    
    public double getRange(@Nonnull final BuilderSupport support) {
        return this.range.get(support.getExecutionContext());
    }
    
    public int getBlockSet(@Nonnull final BuilderSupport support) {
        final String blockSetId = this.blockSet.get(support.getExecutionContext());
        final int index = BlockSet.getAssetMap().getIndex(blockSetId);
        if (index == Integer.MIN_VALUE) {
            throw new IllegalArgumentException("Unknown key! " + blockSetId);
        }
        return index;
    }
    
    public float getMinRetestAngle(@Nonnull final BuilderSupport support) {
        return this.minRetestAngle.get(support.getExecutionContext()) * 0.017453292f;
    }
    
    public double getMinRetestMove(@Nonnull final BuilderSupport support) {
        return this.minRetestMove.get(support.getExecutionContext());
    }
    
    public double getThrottleTime(@Nonnull final BuilderSupport support) {
        return this.throttleTime.get(support.getExecutionContext());
    }
    
    public int getId(@Nonnull final BuilderSupport support) {
        return support.getSearchRaySlot(this.id.get(support.getExecutionContext()));
    }
}
