package common.enchantment;

import common.entity.DamageSource;
import common.entity.Entity;
import common.util.ExtMath;


public class EnchantmentProtection extends Enchantment
{
    private static final String[] NAMES = new String[] {"Schutz", "Feuerschutz", "Federfall", "Explosionsschutz", "Schusssicher"};

    /**
     * Holds the base factor of enchantability needed to be able to use the enchant.
     */
    private static final int[] baseEnchantability = new int[] {1, 10, 5, 5, 3};

    /**
     * Holds how much each level increased the enchantability factor to be able to use this enchant.
     */
    private static final int[] levelEnchantability = new int[] {11, 8, 6, 8, 6};

    /**
     * Used on the formula of base enchantability, this is the 'window' factor of values to be able to use thing
     * enchant.
     */
    private static final int[] thresholdEnchantability = new int[] {20, 12, 10, 12, 15};

    /**
     * Defines the type of protection of the enchantment, 0 = all, 1 = fire, 2 = fall (feather fall), 3 = explosion and
     * 4 = projectile.
     */
    public final int protectionType;

    public EnchantmentProtection(int id, String name, int weight, int type)
    {
        super(id, name, weight, EnumEnchantmentType.ARMOR);
        this.protectionType = type;

        if (type == 2)
        {
            this.type = EnumEnchantmentType.ARMOR_FEET;
        }
    }

    /**
     * Returns the minimal value of enchantability needed on the enchantment level passed.
     */
    public int getMinEnchantability(int enchantmentLevel)
    {
        return baseEnchantability[this.protectionType] + (enchantmentLevel - 1) * levelEnchantability[this.protectionType];
    }

    /**
     * Returns the maximum value of enchantability nedded on the enchantment level passed.
     */
    public int getMaxEnchantability(int enchantmentLevel)
    {
        return this.getMinEnchantability(enchantmentLevel) + thresholdEnchantability[this.protectionType];
    }

    /**
     * Returns the maximum level that the enchantment can have.
     */
    public int getMaxLevel()
    {
        return 4;
    }

    /**
     * Calculates the damage protection of the enchantment based on level and damage source passed.
     */
    public int calcDamageReduction(int level, DamageSource source)
    {
        if (source == DamageSource.outOfWorld)
        {
            return 0;
        }
        else
        {
            float f = (float)(6 + level * level) / 3.0F;
            return this.protectionType == 0 ? ExtMath.floorf(f * 0.75F) : (this.protectionType == 1 && source.isFireDamage() ? ExtMath.floorf(f * 1.25F) : (this.protectionType == 2 && source == DamageSource.fall ? ExtMath.floorf(f * 2.5F) : (this.protectionType == 3 && source.isExplosion() ? ExtMath.floorf(f * 1.5F) : (this.protectionType == 4 && source.isProjectile() ? ExtMath.floorf(f * 1.5F) : 0))));
        }
    }
    
    public String getName()
    {
        return NAMES[this.protectionType];
    }

    /**
     * Determines if the enchantment passed can be applyied together with this enchantment.
     */
    public boolean canApplyTogether(Enchantment ench)
    {
        if (ench instanceof EnchantmentProtection)
        {
            EnchantmentProtection enchantmentprotection = (EnchantmentProtection)ench;
            return enchantmentprotection.protectionType == this.protectionType ? false : this.protectionType == 2 || enchantmentprotection.protectionType == 2;
        }
        else
        {
            return super.canApplyTogether(ench);
        }
    }

    /**
     * Gets the amount of ticks an entity should be set fire, adjusted for fire protection.
     */
    public static int getFireTimeForEntity(Entity entity, int duration)
    {
        int i = EnchantmentHelper.getMaxEnchantmentLevel(Enchantment.fireProtection.effectId, entity.getInventory());

        if (i > 0)
        {
            duration -= ExtMath.floorf((float)duration * (float)i * 0.15F);
        }

        return duration;
    }

    public static double getKnockbackFactor(Entity entity, double strength)
    {
        int i = EnchantmentHelper.getMaxEnchantmentLevel(Enchantment.blastProtection.effectId, entity.getInventory());

        if (i > 0)
        {
            strength -= (double)ExtMath.floord(strength * (double)((float)i * 0.15F));
        }

        return strength;
    }
}
