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

package com.hypixel.hytale.server.npc.util;

import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.Iterator;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.modules.entity.damage.Damage;
import javax.annotation.Nonnull;
import com.hypixel.hytale.component.CommandBuffer;
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
import java.util.HashMap;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageCause;
import it.unimi.dsi.fastutil.objects.Object2DoubleMap;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import java.util.Map;

public class DamageData
{
    private final Map<Ref<EntityStore>, Vector3d> kills;
    private final Object2DoubleMap<Ref<EntityStore>> damageInflicted;
    private final Object2DoubleMap<Ref<EntityStore>> damageSuffered;
    private final Object2DoubleMap<DamageCause> damageByCause;
    private double maxDamageSuffered;
    private double maxDamageInflicted;
    @Nullable
    private Ref<EntityStore> mostPersistentAttacker;
    @Nullable
    private Ref<EntityStore> mostDamagedVictim;
    
    public DamageData() {
        this.kills = new HashMap<Ref<EntityStore>, Vector3d>();
        this.damageInflicted = new Object2DoubleOpenHashMap<Ref<EntityStore>>();
        this.damageSuffered = new Object2DoubleOpenHashMap<Ref<EntityStore>>();
        this.damageByCause = new Object2DoubleOpenHashMap<DamageCause>();
        this.reset();
    }
    
    public void reset() {
        this.kills.clear();
        this.damageInflicted.clear();
        this.damageSuffered.clear();
        this.damageByCause.clear();
        this.maxDamageInflicted = 0.0;
        this.maxDamageSuffered = 0.0;
        this.mostPersistentAttacker = null;
        this.mostDamagedVictim = null;
    }
    
    public void onInflictedDamage(final Ref<EntityStore> target, final double amount) {
        final double d = this.damageInflicted.mergeDouble(target, amount, Double::sum);
        if (d > this.maxDamageInflicted) {
            this.maxDamageInflicted = d;
            this.mostDamagedVictim = target;
        }
    }
    
    public void onSufferedDamage(@Nonnull final CommandBuffer<EntityStore> commandBuffer, @Nonnull final Damage damage) {
        this.damageByCause.mergeDouble(damage.getCause(), damage.getAmount(), Double::sum);
        if (!(damage.getSource() instanceof Damage.EntitySource)) {
            return;
        }
        final Ref<EntityStore> ref = ((Damage.EntitySource)damage.getSource()).getRef();
        if (!ref.isValid()) {
            return;
        }
        final Player playerComponent = commandBuffer.getComponent(ref, Player.getComponentType());
        if (playerComponent != null && playerComponent.getGameMode() == GameMode.Creative) {
            final PlayerSettings playerSettingsComponent = commandBuffer.getComponent(ref, PlayerSettings.getComponentType());
            if (playerSettingsComponent == null || !playerSettingsComponent.creativeSettings().allowNPCDetection()) {
                return;
            }
        }
        final double damageByEntity = this.damageSuffered.mergeDouble(ref, damage.getAmount(), Double::sum);
        if (damageByEntity > this.maxDamageSuffered) {
            this.maxDamageSuffered = damageByEntity;
            this.mostPersistentAttacker = ref;
        }
    }
    
    public void onKill(@Nonnull final Ref<EntityStore> victim, @Nonnull final Vector3d position) {
        this.kills.put(victim, position);
    }
    
    public boolean haveKill() {
        return !this.kills.isEmpty();
    }
    
    public boolean haveKilled(final Ref<EntityStore> entity) {
        return this.kills.containsKey(entity);
    }
    
    @Nullable
    public Ref<EntityStore> getAnyKilled() {
        if (this.kills.isEmpty()) {
            return null;
        }
        for (final Ref<EntityStore> kill : this.kills.keySet()) {
            if (kill.isValid()) {
                return kill;
            }
        }
        return null;
    }
    
    public Vector3d getKillPosition(final Ref<EntityStore> entity) {
        return this.kills.get(entity);
    }
    
    public double getMaxDamageInflicted() {
        return this.maxDamageInflicted;
    }
    
    public double getMaxDamageSuffered() {
        return this.maxDamageSuffered;
    }
    
    public double getDamage(final DamageCause cause) {
        return this.damageByCause.getDouble(cause);
    }
    
    public boolean hasSufferedDamage(final DamageCause cause) {
        return this.damageByCause.containsKey(cause);
    }
    
    @Nullable
    public Ref<EntityStore> getMostDamagedVictim() {
        return (this.mostDamagedVictim != null && this.mostDamagedVictim.isValid()) ? this.mostDamagedVictim : null;
    }
    
    @Nullable
    public Ref<EntityStore> getMostDamagingAttacker() {
        return (this.mostPersistentAttacker != null && this.mostPersistentAttacker.isValid()) ? this.mostPersistentAttacker : null;
    }
    
    @Nullable
    public Ref<EntityStore> getAnyAttacker() {
        if (this.damageSuffered.isEmpty()) {
            return null;
        }
        for (final Ref<EntityStore> attacker : this.damageSuffered.keySet()) {
            if (attacker.isValid()) {
                return attacker;
            }
        }
        return null;
    }
    
    @Nonnull
    public DamageData clone() {
        final DamageData damageData = new DamageData();
        damageData.kills.putAll(this.kills);
        damageData.damageInflicted.putAll((Map<?, ?>)this.damageInflicted);
        damageData.damageSuffered.putAll((Map<?, ?>)this.damageSuffered);
        damageData.damageByCause.putAll((Map<?, ?>)this.damageByCause);
        damageData.maxDamageSuffered = this.maxDamageSuffered;
        damageData.maxDamageInflicted = this.maxDamageInflicted;
        damageData.mostPersistentAttacker = this.mostPersistentAttacker;
        damageData.mostDamagedVictim = this.mostDamagedVictim;
        return damageData;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "DamageData{kills=" + String.valueOf(this.kills) + ", damageInflicted=" + String.valueOf(this.damageInflicted) + ", damageSuffered=" + String.valueOf(this.damageSuffered) + ", damageByCause=" + String.valueOf(this.damageByCause) + ", maxDamageSuffered=" + this.maxDamageSuffered + ", maxDamageInflicted=" + this.maxDamageInflicted + ", mostPersistentAttacker=" + String.valueOf(this.mostPersistentAttacker) + ", mostDamagedVictim=" + String.valueOf(this.mostDamagedVictim);
    }
}
