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

package com.hypixel.hytale.server.flock.corecomponents;

import javax.annotation.Nullable;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.npc.sensorinfo.InfoProvider;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.npc.corecomponents.builders.BuilderActionBase;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.flock.corecomponents.builders.BuilderActionFlockBeacon;
import com.hypixel.hytale.server.core.entity.group.EntityGroup;
import com.hypixel.hytale.server.flock.FlockMembership;
import com.hypixel.hytale.server.npc.components.messaging.BeaconSupport;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.npc.corecomponents.ActionBase;

public class ActionFlockBeacon extends ActionBase
{
    protected static final ComponentType<EntityStore, BeaconSupport> BEACON_SUPPORT_COMPONENT_TYPE;
    protected static final ComponentType<EntityStore, FlockMembership> FLOCK_MEMBERSHIP_COMPONENT_TYPE;
    protected static final ComponentType<EntityStore, EntityGroup> ENTITY_GROUP_COMPONENT_TYPE;
    protected final String message;
    protected final double expirationTime;
    protected final boolean sendToSelf;
    protected final boolean sendToLeaderOnly;
    protected final int sendTargetSlot;
    
    public ActionFlockBeacon(@Nonnull final BuilderActionFlockBeacon builderActionFlockBeacon, @Nonnull final BuilderSupport builderSupport) {
        super(builderActionFlockBeacon);
        this.message = builderActionFlockBeacon.getMessage(builderSupport);
        this.sendTargetSlot = builderActionFlockBeacon.getSendTargetSlot(builderSupport);
        this.expirationTime = builderActionFlockBeacon.getExpirationTime();
        this.sendToSelf = builderActionFlockBeacon.isSendToSelf();
        this.sendToLeaderOnly = builderActionFlockBeacon.isSendToLeaderOnly();
    }
    
    @Override
    public boolean canExecute(@Nonnull final Ref<EntityStore> ref, @Nonnull final Role role, final InfoProvider sensorInfo, final double dt, @Nonnull final Store<EntityStore> store) {
        return super.canExecute(ref, role, sensorInfo, dt, store) && store.getArchetype(ref).contains(ActionFlockBeacon.FLOCK_MEMBERSHIP_COMPONENT_TYPE) && (this.sendTargetSlot == Integer.MIN_VALUE || role.getMarkedEntitySupport().hasMarkedEntityInSlot(this.sendTargetSlot));
    }
    
    @Override
    public boolean execute(@Nonnull final Ref<EntityStore> ref, @Nonnull final Role role, final InfoProvider sensorInfo, final double dt, @Nonnull final Store<EntityStore> store) {
        super.execute(ref, role, sensorInfo, dt, store);
        final FlockMembership flockMembership = store.getComponent(ref, ActionFlockBeacon.FLOCK_MEMBERSHIP_COMPONENT_TYPE);
        final Ref<EntityStore> flockReference = (flockMembership != null) ? flockMembership.getFlockRef() : null;
        if (flockReference == null || !flockReference.isValid()) {
            return true;
        }
        final EntityGroup entityGroup = store.getComponent(flockReference, ActionFlockBeacon.ENTITY_GROUP_COMPONENT_TYPE);
        if (entityGroup == null) {
            return true;
        }
        final Ref<EntityStore> targetRef = (this.sendTargetSlot >= 0) ? role.getMarkedEntitySupport().getMarkedEntityRef(this.sendTargetSlot) : ref;
        if (this.sendToLeaderOnly) {
            final Ref<EntityStore> leaderReference = entityGroup.getLeaderRef();
            if ((this.sendToSelf || targetRef == null || !targetRef.equals(leaderReference)) && leaderReference.isValid()) {
                this.sendNPCMessage(leaderReference, targetRef, store);
            }
        }
        else {
            entityGroup.forEachMember((flockMember, entity, _target) -> this.sendNPCMessage(flockMember, _target, store), ref, targetRef, this.sendToSelf ? null : ref);
        }
        return true;
    }
    
    protected void sendNPCMessage(@Nonnull final Ref<EntityStore> ref, @Nullable final Ref<EntityStore> targetRef, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final BeaconSupport beaconSupport = componentAccessor.getComponent(ref, ActionFlockBeacon.BEACON_SUPPORT_COMPONENT_TYPE);
        if (beaconSupport != null) {
            beaconSupport.postMessage(this.message, targetRef, this.expirationTime);
        }
    }
    
    static {
        BEACON_SUPPORT_COMPONENT_TYPE = BeaconSupport.getComponentType();
        FLOCK_MEMBERSHIP_COMPONENT_TYPE = FlockMembership.getComponentType();
        ENTITY_GROUP_COMPONENT_TYPE = EntityGroup.getComponentType();
    }
}
