package common.item;

import java.util.Map;
import java.util.Set;

import common.attributes.Attribute;
import common.attributes.AttributeModifier;
import common.attributes.Attributes;
import common.block.Block;
import common.collect.Sets;
import common.entity.types.EntityLiving;
import common.init.ToolMaterial;
import common.model.Transforms;
import common.util.BlockPos;
import common.world.World;

public abstract class ItemTool extends Item
{
//    private Set<Block> effectiveBlocks;
    protected float efficiencyOnProperMaterial = 4.0F;

    /** Damage versus entities. */
    private int damageVsEntity;

    /** The material this tool is made from. */
    protected ToolMaterial toolMaterial;

    public ItemTool(int attackDamage, ToolMaterial material)
    {
        this.toolMaterial = material;
//        this.effectiveBlocks = effectiveBlocks;
        this.maxStackSize = 1;
        this.setMaxDamage(material.getMaxUses());
        this.efficiencyOnProperMaterial = material.getEfficiencyOnProperMaterial();
        this.damageVsEntity = attackDamage + material.getDamageVsEntity();
        this.setTab(CheatTab.tabTools);
    }
    
    public abstract boolean canUseOn(ItemStack stack, Block state);

    public float getStrVsBlock(ItemStack stack, Block state) {
    	return !this.canUseOn(stack, state) ? 1.0F : this.efficiencyOnProperMaterial;
    }
//    {
//        return this.effectiveBlocks.contains(state) ? this.efficiencyOnProperMaterial : 1.0F;
//    }

    /**
     * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise
     * the damage on the stack.
     */
    public boolean hitEntity(ItemStack stack, EntityLiving target, EntityLiving attacker)
    {
        stack.damageItem(2, attacker);
        return true;
    }

    /**
     * Called when a Block is destroyed using this Item. Return true to trigger the "Use Item" statistic.
     */
    public boolean onBlockDestroyed(ItemStack stack, World worldIn, Block blockIn, BlockPos pos, EntityLiving playerIn)
    {
        if ((double)blockIn.getBlockHardness(worldIn, pos) != 0.0D)
        {
            stack.damageItem(1, playerIn);
        }

        return true;
    }

//    /**
//     * Returns True is the item is renderer in full 3D when hold.
//     */
//    public boolean isFull3D()
//    {
//        return true;
//    }

    public ToolMaterial getToolMaterial()
    {
        return this.toolMaterial;
    }

    /**
     * Return the enchantability factor of the item, most of the time is based on material.
     */
    public int getItemEnchantability()
    {
        return this.toolMaterial.getEnchantability();
    }

//    /**
//     * Return the name for this tool's material.
//     */
//    public String getToolMaterialName()
//    {
//        return this.toolMaterial.toString();
//    }

    /**
     * Return whether this item is repairable in an anvil.
     */
    public boolean getIsRepairable(ItemStack toRepair, ItemStack repair)
    {
        return this.toolMaterial.isRepairItem(repair.getItem()) ? true : super.getIsRepairable(toRepair, repair);
    }

    public Map<Attribute, Set<AttributeModifier>> getItemAttributeModifiers()
    {
    	Map<Attribute, Set<AttributeModifier>> multimap = super.getItemAttributeModifiers();
        multimap.put(Attributes.ATTACK_DAMAGE, Sets.newHashSet(new AttributeModifier(Attributes.ITEM_VAL_ID, "Tool modifier", this.damageVsEntity, false)));
        return multimap;
    }
    
    public boolean isMagnetic() {
    	return this.toolMaterial.isMagnetic();
    }

    public Transforms getTransform() {
    	return Transforms.TOOL;
    }
    
    public boolean canBeWielded() {
    	return true;
    }
}
