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

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

import java.util.function.Supplier;
import com.hypixel.hytale.server.core.entity.group.EntityGroup;
import com.hypixel.hytale.server.npc.sensorinfo.InfoProvider;
import com.hypixel.hytale.server.flock.Flock;
import com.hypixel.hytale.server.npc.util.DamageData;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.flock.FlockPlugin;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.npc.corecomponents.builders.BuilderSensorBase;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.flock.corecomponents.builders.BuilderSensorInflictedDamage;
import com.hypixel.hytale.server.npc.sensorinfo.EntityPositionProvider;
import com.hypixel.hytale.server.npc.corecomponents.SensorBase;

public class SensorInflictedDamage extends SensorBase
{
    protected final Target target;
    protected final boolean friendlyFire;
    protected final EntityPositionProvider positionProvider;
    
    public SensorInflictedDamage(@Nonnull final BuilderSensorInflictedDamage builder) {
        super(builder);
        this.positionProvider = new EntityPositionProvider();
        this.target = builder.getTarget();
        this.friendlyFire = builder.isFriendlyFire();
    }
    
    @Override
    public boolean matches(@Nonnull final Ref<EntityStore> ref, @Nonnull final Role role, final double dt, @Nonnull final Store<EntityStore> store) {
        if (!super.matches(ref, role, dt, store)) {
            this.positionProvider.clear();
            return false;
        }
        final NPCEntity npcComponent = store.getComponent(ref, NPCEntity.getComponentType());
        DamageData damageData;
        if (this.target == Target.Self) {
            damageData = npcComponent.getDamageData();
        }
        else {
            final Flock npcFlock = FlockPlugin.getFlock(store, ref);
            if (npcFlock == null) {
                this.positionProvider.clear();
                return false;
            }
            damageData = ((this.target == Target.FlockLeader) ? npcFlock.getLeaderDamageData() : npcFlock.getDamageData());
        }
        final Ref<EntityStore> victimReference = damageData.getMostDamagedVictim();
        if (victimReference == null) {
            this.positionProvider.clear();
            return false;
        }
        if (!this.friendlyFire && inSameFlock(ref, victimReference, store)) {
            this.positionProvider.clear();
            return false;
        }
        return this.positionProvider.setTarget(victimReference, store) != null;
    }
    
    @Override
    public InfoProvider getSensorInfo() {
        return this.positionProvider;
    }
    
    protected static boolean inSameFlock(@Nonnull final Ref<EntityStore> selfReference, @Nonnull final Ref<EntityStore> target, @Nonnull final Store<EntityStore> store) {
        final Ref<EntityStore> flockReference = FlockPlugin.getFlockReference(selfReference, store);
        if (flockReference == null) {
            return false;
        }
        final EntityGroup entityGroupComponent = store.getComponent(flockReference, EntityGroup.getComponentType());
        assert entityGroupComponent != null;
        return entityGroupComponent.isMember(target);
    }
    
    public enum Target implements Supplier<String>
    {
        Flock("Check flock"), 
        FlockLeader("Check flock leader only"), 
        Self("Check self");
        
        private final String description;
        
        private Target(final String description) {
            this.description = description;
        }
        
        @Override
        public String get() {
            return this.description;
        }
    }
}
