package common.attributes;

import java.util.Collection;

import common.log.Log;
import common.nbt.NBTTagCompound;
import common.nbt.NBTTagList;

public class Attributes
{
    public static final Attribute MAX_HEALTH = (new Attribute("generic.maxHealth", "Maximale Gesundheit", 20.0D, 0.0D, 1024.0D, true));
    public static final Attribute FOLLOW_RANGE = (new Attribute("generic.followRange", "Kreaturen-Folgedistanz", 32.0D, 0.0D, 2048.0D, false));
    public static final Attribute KNOCKBACK_RESISTANCE = (new Attribute("generic.knockbackResistance", "Standfestigkeit", 0.0D, 0.0D, 1.0D, false));
    public static final Attribute MOVEMENT_SPEED = (new Attribute("generic.movementSpeed", "Geschwindigkeit", 0.699999988079071D, 0.0D, 1024.0D, true));
    public static final Attribute ATTACK_DAMAGE = new Attribute("generic.attackDamage", "Angriffsschaden", 2.0D, 0.0D, 2048.0D, false);
    public static final Attribute RADIATION = new Attribute("generic.radiation", "Strahlung", 0.0D, 0.0D, 16384.0D, false);
    public static final Attribute RADIATION_RESISTANCE = new Attribute("generic.radiationResistance", "Strahlungsresistenz", 10.0D, 0.0D, 16384.0D, false);
    public static final Attribute MANA_CAPACITY = new Attribute("generic.manaCapacity", "Mana-Kapazität", 0.0D, 0.0D, 2048.0D, false);
    public static final Attribute MAGIC_RESISTANCE = new Attribute("generic.magicResistance", "Magieresistenz", 0.0D, 0.0D, 4096.0D, false);
	public static final Attribute REINFORCEMENT_CHANCE = (new Attribute("zombie.spawnReinforcements", "Zombie-Verstärkung", 0.0D, 0.0D, 1.0D, false));
	public static final Attribute HORSE_JUMP_STRENGTH = (new Attribute("horse.jumpStrength", "Pferdesprungstärke", 0.7D, 0.0D, 2.0D, true));

//	public static final long ATTACK_SPEED_ID = AttributeModifier.getModifierId("EnderSp");
//	public static final AttributeModifier ATTACK_SPEED_MOD = (new AttributeModifier(ATTACK_SPEED_ID, "Attacking speed boost", 0.15000000596046448D, false, false));
	public static final long RUSHING_SPEED_ID = AttributeModifier.getModifierId("RushSpd");
	public static final AttributeModifier RUSHING_SPEED_MOD = (new AttributeModifier(RUSHING_SPEED_ID, "Attacking speed boost", 0.05D, false, false));
	public static final long MAGE_POTSPEED_ID = AttributeModifier.getModifierId("MagePot");
	public static final AttributeModifier MAGE_POTSPEED_MOD = (new AttributeModifier(MAGE_POTSPEED_ID, "Drinking speed penalty", -0.25D, false, false));
	public static final long ZOMBIE_BABY_ID = AttributeModifier.getModifierId("ZombSpd");
	public static final AttributeModifier ZOMBIE_BABY_MOD = new AttributeModifier(ZOMBIE_BABY_ID, "Baby speed boost", 0.5D, true);
	public static final long FLEEING_SPEED_ID = AttributeModifier.getModifierId("FleeSpd");
	public static final AttributeModifier FLEEING_SPEED_MOD = (new AttributeModifier(FLEEING_SPEED_ID, "Fleeing speed bonus", 2.0D, true, false));
	public static final long SPRINT_SPEED_ID = AttributeModifier.getModifierId("Sprint");
	public static final AttributeModifier SPRINT_SPEED_MOD = (new AttributeModifier(SPRINT_SPEED_ID, "Sprinting speed boost", 0.30000001192092896D, true, false));
	public static final long ITEM_VAL_ID = AttributeModifier.getModifierId("ItemVal");
	public static final long RADIATION_BASE = AttributeModifier.getModifierId("NukeVal");
	public static final long MOUSE_SPEEDY_ID = AttributeModifier.getModifierId("SpeedyG");
	public static final AttributeModifier MOUSE_SPEEDY_MOD = new AttributeModifier(MOUSE_SPEEDY_ID, "Mouse speed boost", 1.0D, true);

    /**
     * Creates an NBTTagList from a BaseAttributeMap, including all its AttributeInstances
     */
    public static NBTTagList writeBaseAttributeMapToNBT(AttributeMap map)
    {
        NBTTagList nbttaglist = new NBTTagList();

        for (AttributeInstance iattributeinstance : map.getAllAttributes())
        {
            nbttaglist.appendTag(writeAttributeInstanceToNBT(iattributeinstance));
        }

        return nbttaglist;
    }

    /**
     * Creates an NBTTagCompound from an AttributeInstance, including its AttributeModifiers
     */
    private static NBTTagCompound writeAttributeInstanceToNBT(AttributeInstance instance)
    {
        NBTTagCompound nbttagcompound = new NBTTagCompound();
        Attribute iattribute = instance.getAttribute();
        nbttagcompound.setString("Name", iattribute.getUnlocalizedName());
        nbttagcompound.setDouble("Base", instance.getBaseValue());
        Collection<AttributeModifier> collection = instance.getModifiers();

        if (collection != null && !collection.isEmpty())
        {
            NBTTagList nbttaglist = new NBTTagList();

            for (AttributeModifier attributemodifier : collection)
            {
                if (attributemodifier.isSaved())
                {
                    nbttaglist.appendTag(writeAttributeModifierToNBT(attributemodifier));
                }
            }

            nbttagcompound.setTag("Modifiers", nbttaglist);
        }

        return nbttagcompound;
    }

    /**
     * Creates an NBTTagCompound from an AttributeModifier
     */
    private static NBTTagCompound writeAttributeModifierToNBT(AttributeModifier modifier)
    {
        NBTTagCompound nbttagcompound = new NBTTagCompound();
        nbttagcompound.setString("Name", modifier.getName());
        nbttagcompound.setDouble("Amount", modifier.getAmount());
        nbttagcompound.setBoolean("Multiply", modifier.isMultiplied());
        nbttagcompound.setLong("AttrId", modifier.getID());
        return nbttagcompound;
    }

    public static void setAttributeModifiers(AttributeMap map, NBTTagList list)
    {
        for (int i = 0; i < list.tagCount(); ++i)
        {
            NBTTagCompound nbttagcompound = list.getCompoundTagAt(i);
            AttributeInstance iattributeinstance = map.getAttributeInstanceByName(nbttagcompound.getString("Name"));

            if (iattributeinstance != null)
            {
                applyModifiersToAttributeInstance(iattributeinstance, nbttagcompound);
            }
            else
            {
            	Log.JNI.warn("Ignoriere unbekannte Attribute \'" + nbttagcompound.getString("Name") + "\'");
            }
        }
    }

    private static void applyModifiersToAttributeInstance(AttributeInstance instance, NBTTagCompound compound)
    {
        instance.setBaseValue(compound.getDouble("Base"));

        if (compound.hasKey("Modifiers", 9))
        {
            NBTTagList nbttaglist = compound.getTagList("Modifiers", 10);

            for (int i = 0; i < nbttaglist.tagCount(); ++i)
            {
                AttributeModifier attributemodifier = readAttributeModifierFromNBT(nbttaglist.getCompoundTagAt(i));

                if (attributemodifier != null)
                {
                    AttributeModifier attributemodifier1 = instance.getModifier(attributemodifier.getID());

                    if (attributemodifier1 != null)
                    {
                        instance.removeModifier(attributemodifier1);
                    }

                    instance.applyModifier(attributemodifier);
                }
            }
        }
    }

    /**
     * Creates an AttributeModifier from an NBTTagCompound
     */
    public static AttributeModifier readAttributeModifierFromNBT(NBTTagCompound compound)
    {
        long id = compound.getLong("AttrId");
        if(id == 0L)
        	return null;

        try
        {
            return new AttributeModifier(id, compound.getString("Name"), compound.getDouble("Amount"), compound.getBoolean("Multiply"));
        }
        catch (Exception exception)
        {
        	Log.JNI.warn("Konnte Attribute nicht erstellen: " + exception.getMessage());
            return null;
        }
    }
}
