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

package com.hypixel.hytale.server.npc.blackboard.view.event.entity;

import com.hypixel.hytale.server.npc.blackboard.view.IBlackboardView;
import com.hypixel.hytale.server.npc.asset.builder.BuilderManager;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.flock.FlockMembership;
import it.unimi.dsi.fastutil.ints.IntSet;
import com.hypixel.hytale.server.npc.blackboard.Blackboard;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.npc.blackboard.view.event.EventNotification;
import com.hypixel.hytale.server.npc.blackboard.view.event.EventTypeRegistration;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.builtin.tagset.TagSetPlugin;
import com.hypixel.hytale.builtin.tagset.config.NPCGroup;
import com.hypixel.hytale.server.core.event.events.player.PlayerInteractEvent;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.npc.blackboard.view.event.EntityEventNotification;
import com.hypixel.hytale.server.npc.blackboard.view.event.EventView;

public class EntityEventView extends EventView<EntityEventView, EntityEventType, EntityEventNotification>
{
    public EntityEventView(@Nonnull final World world) {
        super(EntityEventType.class, EntityEventType.VALUES, new EntityEventNotification(), world);
        this.eventRegistry.register(PlayerInteractEvent.class, world.getName(), this::onPlayerInteraction);
        for (final EntityEventType eventType : EntityEventType.VALUES) {
            this.entityMapsByEventType.put((EventType)eventType, (EventTypeRegistration<EventType, NotificationType>)new EventTypeRegistration<Enum<EventType>, EventNotification>((EventType)eventType, (set, roleIndex) -> TagSetPlugin.get(NPCGroup.class).tagInSet(set, roleIndex), NPCEntity::notifyEntityEvent));
        }
    }
    
    @Override
    public EntityEventView getUpdatedView(@Nonnull final Ref<EntityStore> ref, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final World entityWorld = componentAccessor.getExternalData().getWorld();
        if (!entityWorld.equals(this.world)) {
            final Blackboard blackboardResource = componentAccessor.getResource(Blackboard.getResourceType());
            return blackboardResource.getView(EntityEventView.class, ref, componentAccessor);
        }
        return this;
    }
    
    @Override
    public void initialiseEntity(@Nonnull final Ref<EntityStore> ref, @Nonnull final NPCEntity npcComponent) {
        for (int i = 0; i < EntityEventType.VALUES.length; ++i) {
            final EntityEventType type = EntityEventType.VALUES[i];
            final IntSet eventSets = npcComponent.getBlackboardEntityEventSet(type);
            if (eventSets != null) {
                this.entityMapsByEventType.get(type).initialiseEntity(ref, eventSets);
            }
        }
    }
    
    @Override
    protected void onEvent(final int senderTypeId, final double x, final double y, final double z, final Ref<EntityStore> initiator, @Nonnull final Ref<EntityStore> skip, @Nonnull final ComponentAccessor<EntityStore> componentAccessor, final EntityEventType type) {
        final FlockMembership membership = componentAccessor.getComponent(skip, FlockMembership.getComponentType());
        final Ref<EntityStore> flockReference = (membership != null) ? membership.getFlockRef() : null;
        ((EntityEventNotification)this.reusableEventNotification).setFlockReference(flockReference);
        super.onEvent(senderTypeId, x, y, z, initiator, skip, componentAccessor, type);
    }
    
    private void onPlayerInteraction(@Nonnull final PlayerInteractEvent event) {
        final Player playerComponent = event.getPlayer();
        final Ref<EntityStore> playerRef = playerComponent.getReference();
        final Store<EntityStore> store = playerRef.getStore();
        if (event.isCancelled()) {
            return;
        }
        if (playerComponent.getGameMode() == GameMode.Creative) {
            final PlayerSettings playerSettingsComponent = store.getComponent(playerRef, PlayerSettings.getComponentType());
            if (playerSettingsComponent == null || !playerSettingsComponent.creativeSettings().allowNPCDetection()) {
                return;
            }
        }
        final Entity entity = event.getTargetEntity();
        if (entity == null || event.getActionType() != InteractionType.Use || !(entity instanceof NPCEntity)) {
            return;
        }
        final Ref<EntityStore> entityRef = event.getTargetRef();
        final TransformComponent transformComponent = store.getComponent(entityRef, TransformComponent.getComponentType());
        assert transformComponent != null;
        final Vector3d pos = transformComponent.getPosition();
        this.onEvent(((NPCEntity)entity).getRoleIndex(), pos.x, pos.y, pos.z, playerRef, entityRef, store, EntityEventType.INTERACTION);
    }
    
    public void processAttackedEvent(@Nonnull final Ref<EntityStore> victim, @Nonnull final Ref<EntityStore> attacker, @Nonnull final ComponentAccessor<EntityStore> componentAccessor, final EntityEventType eventType) {
        int roleIndex;
        if (componentAccessor.getArchetype(victim).contains(Player.getComponentType())) {
            roleIndex = BuilderManager.getPlayerGroupID();
        }
        else {
            final NPCEntity npc = componentAccessor.getComponent(victim, NPCEntity.getComponentType());
            if (npc == null) {
                return;
            }
            roleIndex = npc.getRoleIndex();
        }
        final Store<EntityStore> store = victim.getStore();
        final Vector3d pos = store.getComponent(victim, TransformComponent.getComponentType()).getPosition();
        this.onEvent(roleIndex, pos.x, pos.y, pos.z, attacker, attacker, componentAccessor, eventType);
    }
}
