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

package com.hypixel.hytale.server.npc.components.messaging;

import it.unimi.dsi.fastutil.ints.Int2DoubleMap;
import javax.annotation.Nullable;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import javax.annotation.Nonnull;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import java.util.Map;
import com.hypixel.hytale.server.npc.blackboard.view.event.EventNotification;

public abstract class EventSupport<EventType extends Enum<EventType>, NotificationType extends EventNotification> extends MessageSupport
{
    protected static final double EVENT_AGE = 2.0;
    protected EventMessage[] messageSlots;
    protected Map<EventType, Int2IntMap> messageIndices;
    
    public void postMessage(final EventType type, @Nonnull final NotificationType notification, @Nonnull final Ref<EntityStore> parent, @Nonnull final Store<EntityStore> store) {
        final EventMessage slot = this.getMessageSlot(type, notification);
        if (slot == null || !slot.isEnabled()) {
            return;
        }
        final Vector3d parentEntityPosition = store.getComponent(parent, TransformComponent.getComponentType()).getPosition();
        final Vector3d pos = notification.getPosition();
        final double x = pos.getX();
        final double y = pos.getY();
        final double z = pos.getZ();
        final double distanceSquared = parentEntityPosition.distanceSquaredTo(x, y, z);
        if (distanceSquared <= slot.getMaxRangeSquared() && (!slot.isActivated() || distanceSquared < slot.getPosition().distanceSquaredTo(parentEntityPosition))) {
            slot.activate(x, y, z, notification.getInitiator(), 2.0);
        }
    }
    
    @Nullable
    public EventMessage getMessageSlot(final EventType type, @Nonnull final NotificationType notification) {
        if (this.messageSlots == null) {
            return null;
        }
        final Int2IntMap typeSlots = this.messageIndices.get(type);
        if (typeSlots == null) {
            return null;
        }
        final int slotIdx = typeSlots.get(notification.getSet());
        if (slotIdx == Integer.MIN_VALUE) {
            return null;
        }
        return this.messageSlots[slotIdx];
    }
    
    public boolean hasMatchingMessage(final int messageIndex, @Nonnull final Vector3d parentPosition, final double range) {
        if (!this.isMessageQueued(messageIndex)) {
            return false;
        }
        final EventMessage event = this.messageSlots[messageIndex];
        return event.getPosition().distanceSquaredTo(parentPosition) < range * range;
    }
    
    @Nullable
    public Ref<EntityStore> pollMessage(final int messageIndex) {
        final EventMessage event = this.messageSlots[messageIndex];
        event.deactivate();
        return event.getTarget();
    }
    
    public void initialise(final Map<EventType, Int2IntMap> setIndices, @Nonnull final Int2DoubleMap messageRanges, final int count) {
        this.messageIndices = setIndices;
        final EventMessage[] messages = new EventMessage[count];
        for (int i = 0; i < messages.length; ++i) {
            messages[i] = new EventMessage(messageRanges.get(i));
        }
        this.messageSlots = messages;
    }
    
    public void cloneTo(@Nonnull final EventSupport<EventType, NotificationType> other) {
        other.messageSlots = new EventMessage[this.messageSlots.length];
        for (int i = 0; i < other.messageSlots.length; ++i) {
            other.messageSlots[i] = this.messageSlots[i].clone();
        }
        other.messageIndices = this.messageIndices;
    }
    
    @Override
    public NPCMessage[] getMessageSlots() {
        return this.messageSlots;
    }
}
