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

package com.hypixel.hytale.server.npc.role.support;

import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import com.hypixel.hytale.server.core.entity.group.EntityGroup;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.flock.FlockPlugin;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.component.Ref;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import javax.annotation.Nonnull;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentType;

public class MarkedEntitySupport
{
    public static final String DEFAULT_TARGET_SLOT = "LockedTarget";
    @Nullable
    protected static final ComponentType<EntityStore, NPCEntity> NPC_COMPONENT_TYPE;
    @Nonnull
    private static final Object2IntMap<String> EMPTY_TARGET_SLOT_MAP;
    protected final NPCEntity parent;
    protected Object2IntMap<String> targetSlotMappings;
    @Nullable
    protected Int2ObjectMap<String> slotToNameMap;
    protected Ref<EntityStore>[] entityTargets;
    @Nullable
    protected Vector3d[] storedPositions;
    protected int defaultTargetSlot;
    protected int targetSlotToIgnoreForAvoidance;
    
    public MarkedEntitySupport(final NPCEntity parent) {
        this.targetSlotToIgnoreForAvoidance = Integer.MIN_VALUE;
        this.parent = parent;
    }
    
    public Ref<EntityStore>[] getEntityTargets() {
        return this.entityTargets;
    }
    
    public void postRoleBuilder(@Nonnull final BuilderSupport support) {
        final Object2IntMap<String> slotMappings = support.getTargetSlotMappings();
        if (slotMappings != null) {
            this.targetSlotMappings = slotMappings;
            this.slotToNameMap = support.getTargetSlotToNameMap();
            this.entityTargets = new Ref[this.targetSlotMappings.size()];
            this.defaultTargetSlot = this.targetSlotMappings.getInt("LockedTarget");
        }
        else {
            this.targetSlotMappings = MarkedEntitySupport.EMPTY_TARGET_SLOT_MAP;
            this.slotToNameMap = null;
            this.entityTargets = (Ref<EntityStore>[])Ref.EMPTY_ARRAY;
            this.defaultTargetSlot = Integer.MIN_VALUE;
        }
        this.storedPositions = support.allocatePositionSlots();
    }
    
    public void clearMarkedEntity(final int targetSlot) {
        this.entityTargets[targetSlot] = null;
    }
    
    public void setMarkedEntity(final String targetSlot, final Ref<EntityStore> target) {
        final int slot = this.targetSlotMappings.getInt(targetSlot);
        if (slot >= 0) {
            this.setMarkedEntity(slot, target);
        }
    }
    
    public void setMarkedEntity(final int targetSlot, @Nullable final Ref<EntityStore> target) {
        if (target == null || !target.isValid()) {
            this.clearMarkedEntity(targetSlot);
            return;
        }
        this.entityTargets[targetSlot] = target;
    }
    
    @Nullable
    public Ref<EntityStore> getMarkedEntityRef(final String targetSlot) {
        final int slot = this.targetSlotMappings.getInt(targetSlot);
        if (slot >= 0) {
            return this.getMarkedEntityRef(slot);
        }
        return null;
    }
    
    @Nullable
    public Ref<EntityStore> getMarkedEntityRef(final int targetSlot) {
        final Ref<EntityStore> ref = this.entityTargets[targetSlot];
        return (ref != null && ref.isValid()) ? ref : null;
    }
    
    public int getMarkedEntitySlotCount() {
        return this.entityTargets.length;
    }
    
    public Vector3d getStoredPosition(final int slot) {
        return this.storedPositions[slot];
    }
    
    public boolean hasMarkedEntity(@Nonnull final Ref<EntityStore> entityReference, final int targetSlot) {
        return entityReference.equals(this.getMarkedEntityRef(targetSlot));
    }
    
    public boolean hasMarkedEntityInSlot(final String targetSlot) {
        final int slot = this.targetSlotMappings.getInt(targetSlot);
        return slot >= 0 && this.hasMarkedEntityInSlot(slot);
    }
    
    public boolean hasMarkedEntityInSlot(final int targetSlot) {
        return this.getMarkedEntityRef(targetSlot) != null;
    }
    
    public void flockSetTarget(@Nonnull final String targetSlot, @Nullable final Ref<EntityStore> targetRef, @Nonnull final Store<EntityStore> store) {
        final Ref<EntityStore> parentRef = this.parent.getReference();
        final Ref<EntityStore> flockReference = FlockPlugin.getFlockReference(parentRef, store);
        if (flockReference != null) {
            store.getComponent(flockReference, EntityGroup.getComponentType()).forEachMember((member, sender, _target, _targetSlot) -> {
                final NPCEntity npcComponent = member.getStore().getComponent(member, MarkedEntitySupport.NPC_COMPONENT_TYPE);
                if (npcComponent != null) {
                    npcComponent.onFlockSetTarget(_targetSlot, _target);
                }
            }, parentRef, targetRef, targetSlot);
        }
    }
    
    public void setTargetSlotToIgnoreForAvoidance(final int targetSlotToIgnoreForAvoidance) {
        this.targetSlotToIgnoreForAvoidance = targetSlotToIgnoreForAvoidance;
    }
    
    @Nullable
    public Ref<EntityStore> getTargetReferenceToIgnoreForAvoidance() {
        final int slot = (this.targetSlotToIgnoreForAvoidance >= 0) ? this.targetSlotToIgnoreForAvoidance : this.defaultTargetSlot;
        if (slot < 0) {
            return null;
        }
        return this.getMarkedEntityRef(slot);
    }
    
    public String getSlotName(final int slot) {
        return this.slotToNameMap.get(slot);
    }
    
    public void unloaded() {
        for (int i = 0; i < this.entityTargets.length; ++i) {
            this.clearMarkedEntity(i);
        }
    }
    
    static {
        NPC_COMPONENT_TYPE = NPCEntity.getComponentType();
        (EMPTY_TARGET_SLOT_MAP = new Object2IntOpenHashMap<String>(0)).defaultReturnValue(Integer.MIN_VALUE);
    }
}
