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

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

import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.npc.util.AimingHelper;
import java.util.List;
import com.hypixel.hytale.server.npc.util.expression.Scope;
import com.hypixel.hytale.server.npc.util.expression.ExecutionContext;
import com.hypixel.hytale.server.npc.validators.NPCLoadTimeValidationHelper;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleArrayValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.DoubleSequenceValidator;
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.asset.ItemDropListExistsValidator;
import com.hypixel.hytale.server.npc.asset.builder.BuilderDescriptorState;
import com.hypixel.hytale.server.npc.asset.builder.validators.asset.ItemExistsValidator;
import com.hypixel.hytale.server.npc.asset.builder.validators.AssetValidator;
import com.google.gson.JsonElement;
import com.hypixel.hytale.server.npc.corecomponents.items.ActionDropItem;
import com.hypixel.hytale.server.npc.instructions.Action;
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.corecomponents.builders.BuilderActionWithDelay;

public class BuilderActionDropItem extends BuilderActionWithDelay
{
    public static final double[] DEFAULT_THROW_DISTANCE;
    public static final double[] DEFAULT_DROP_SECTOR;
    protected final AssetHolder item;
    protected final AssetHolder dropList;
    protected float throwSpeed;
    protected double[] distance;
    protected double[] dropSector;
    protected boolean highPitch;
    
    public BuilderActionDropItem() {
        this.item = new AssetHolder();
        this.dropList = new AssetHolder();
    }
    
    @Nonnull
    @Override
    public String getShortDescription() {
        return "Drop an item";
    }
    
    @Nonnull
    @Override
    public String getLongDescription() {
        return "Drop an item. Can be a specific item, or from a drop table";
    }
    
    @Nonnull
    @Override
    public Action build(@Nonnull final BuilderSupport builderSupport) {
        return new ActionDropItem(this, builderSupport);
    }
    
    @Nonnull
    @Override
    public BuilderActionDropItem readConfig(@Nonnull final JsonElement data) {
        this.getAsset(data, "Item", this.item, null, ItemExistsValidator.withConfig(AssetValidator.CanBeEmpty), BuilderDescriptorState.Stable, "A specific item to drop", null);
        this.getAsset(data, "DropList", this.dropList, null, ItemDropListExistsValidator.withConfig(AssetValidator.CanBeEmpty), BuilderDescriptorState.Stable, "A reference to an item drop list", null);
        this.getFloat(data, "ThrowSpeed", s -> this.throwSpeed = s, 1.0f, DoubleRangeValidator.fromExclToIncl(0.0, 3.4028234663852886E38), BuilderDescriptorState.Stable, "The throw speed to use", null);
        this.getDoubleRange(data, "Distance", s -> this.distance = s, BuilderActionDropItem.DEFAULT_THROW_DISTANCE, DoubleSequenceValidator.betweenWeaklyMonotonic(0.0, Double.MAX_VALUE), BuilderDescriptorState.Stable, "The range from which to pick a distance to throw the item", null);
        this.getDoubleRange(data, "DropSector", s -> this.dropSector = s, BuilderActionDropItem.DEFAULT_DROP_SECTOR, DoubleSequenceValidator.betweenWeaklyMonotonic(-360.0, 360.0), BuilderDescriptorState.Stable, "The sector to spread drops in relative to view direction of NPC", "The sector to spread drops in relative to view direction of NPC in degrees.");
        this.getBoolean(data, "PitchHigh", v -> this.highPitch = v, false, BuilderDescriptorState.Stable, "Whether to pitch high or pitch low instead", null);
        this.validateOneSetAsset(this.item, this.dropList);
        return this;
    }
    
    @Nonnull
    @Override
    public BuilderDescriptorState getBuilderDescriptorState() {
        return BuilderDescriptorState.Stable;
    }
    
    @Override
    public boolean validate(final String configName, @Nonnull final NPCLoadTimeValidationHelper validationHelper, final ExecutionContext context, final Scope globalScope, @Nonnull final List<String> errors) {
        boolean result = super.validate(configName, validationHelper, context, globalScope, errors);
        final Model model = validationHelper.getSpawnModel();
        final float height = model.getEyeHeight();
        final double newThrowSpeed = AimingHelper.ensurePossibleThrowSpeed(this.distance[1], height, 32.0, this.throwSpeed);
        if (newThrowSpeed > this.throwSpeed) {
            errors.add(String.format("%s: Throw speed %.2f is too low to achieve distance of %.2f in DropItem action. Needs to be at least %.2f", configName, this.throwSpeed, this.distance[1], Math.ceil(newThrowSpeed * 100.0) / 100.0));
            result = false;
        }
        return result;
    }
    
    public String getItem(@Nonnull final BuilderSupport support) {
        return this.item.get(support.getExecutionContext());
    }
    
    public String getDropList(@Nonnull final BuilderSupport support) {
        return this.dropList.get(support.getExecutionContext());
    }
    
    public float getThrowSpeed() {
        return this.throwSpeed;
    }
    
    public double[] getDropSectorRadians() {
        return this.dropSector;
    }
    
    public double[] getDistance() {
        return this.distance;
    }
    
    public boolean isHighPitch() {
        return this.highPitch;
    }
    
    static {
        DEFAULT_THROW_DISTANCE = new double[] { 1.0, 1.0 };
        DEFAULT_DROP_SECTOR = new double[] { 0.0, 0.0 };
    }
}
