package common.item;

import java.util.List;
import java.util.Map;

import common.collect.Maps;
import common.entity.npc.EntityNPC;
import common.model.Model;
import common.model.ModelProvider;
import common.potion.Potion;
import common.potion.PotionEffect;
import common.potion.PotionHelper;
import common.world.World;

public class ItemFishFood extends ItemFood
{
    /** Indicates whether this fish is "cooked" or not. */
    private final boolean cooked;

    public ItemFishFood(boolean cooked)
    {
        super(0, false);
        this.cooked = cooked;
    }

    public int getHealAmount(ItemStack stack)
    {
        ItemFishFood.FishType itemfishfood$fishtype = ItemFishFood.FishType.byItemStack(stack);
        return this.cooked && itemfishfood$fishtype.canCook() ? itemfishfood$fishtype.getCookedHealAmount() : itemfishfood$fishtype.getUncookedHealAmount();
    }

    public String getPotionEffect(ItemStack stack)
    {
        return ItemFishFood.FishType.byItemStack(stack) == ItemFishFood.FishType.PUFFERFISH ? PotionHelper.pufferfishEffect : null;
    }

    protected void onFoodEaten(ItemStack stack, World worldIn, EntityNPC player)
    {
        ItemFishFood.FishType itemfishfood$fishtype = ItemFishFood.FishType.byItemStack(stack);

        if (itemfishfood$fishtype == ItemFishFood.FishType.PUFFERFISH)
        {
            player.addEffect(new PotionEffect(Potion.POISON, 1200, 3));
            player.addEffect(new PotionEffect(Potion.NAUSEA, 300, 1));
        }

        super.onFoodEaten(stack, worldIn, player);
    }

    /**
     * returns a list of items with the same ID, but different meta (eg: dye returns 16 items)
     */
    public void getSubItems(Item itemIn, CheatTab tab, List<ItemStack> subItems)
    {
        for (ItemFishFood.FishType itemfishfood$fishtype : ItemFishFood.FishType.values())
        {
            if (!this.cooked || itemfishfood$fishtype.canCook())
            {
                subItems.add(new ItemStack(this, 1, itemfishfood$fishtype.getMetadata()));
            }
        }
    }

    /**
     * Returns the unlocalized name of this item. This version accepts an ItemStack so different stacks can have
     * different names based on their damage or NBT.
     */
    public String getDisplay(ItemStack stack)
    {
        ItemFishFood.FishType type = ItemFishFood.FishType.byItemStack(stack);
        return (type.canCook() ? (this.cooked ? "Gebratener " : "Roher ") : "") + type.getName();
    }

    public Model getModel(ModelProvider provider, String name, int meta) {
    	return provider.getModel(this.getTransform(), (this.cooked ? "cooked_" : "") + FishType.byMetadata(meta).getTexture());
    }

    public static enum FishType
    {
        COD("cod", 0, "Kabeljau", 2, 5),
        SALMON("salmon", 1, "Lachs", 2, 6),
        CLOWNFISH("clownfish", 2, "Clownfisch", 1),
        PUFFERFISH("pufferfish", 3, "Kugelfisch", 1);

        private static final Map<Integer, ItemFishFood.FishType> META_LOOKUP = Maps.<Integer, ItemFishFood.FishType>newHashMap();
        private final int meta;
        private final String texture;
        private final String name;
        private final int uncookedHealAmount;
        private final int cookedHealAmount;
        private boolean cookable = false;

        private FishType(String texture, int meta, String name, int uncookedHeal, int cookedHeal)
        {
            this.texture = texture;
            this.meta = meta;
            this.name = name;
            this.uncookedHealAmount = uncookedHeal;
            this.cookedHealAmount = cookedHeal;
            this.cookable = true;
        }

        private FishType(String texture, int meta, String name, int uncookedHeal)
        {
            this.texture = texture;
            this.meta = meta;
            this.name = name;
            this.uncookedHealAmount = uncookedHeal;
            this.cookedHealAmount = 0;
            this.cookable = false;
        }

        public int getMetadata()
        {
            return this.meta;
        }

        public String getName()
        {
            return this.name;
        }

        public String getTexture()
        {
            return this.texture;
        }

        public int getUncookedHealAmount()
        {
            return this.uncookedHealAmount;
        }

        public int getCookedHealAmount()
        {
            return this.cookedHealAmount;
        }

        public boolean canCook()
        {
            return this.cookable;
        }

        public static ItemFishFood.FishType byMetadata(int meta)
        {
            ItemFishFood.FishType itemfishfood$fishtype = (ItemFishFood.FishType)META_LOOKUP.get(Integer.valueOf(meta));
            return itemfishfood$fishtype == null ? COD : itemfishfood$fishtype;
        }

        public static ItemFishFood.FishType byItemStack(ItemStack stack)
        {
            return stack.getItem() instanceof ItemFishFood ? byMetadata(stack.getMetadata()) : COD;
        }

        static {
            for (ItemFishFood.FishType itemfishfood$fishtype : values())
            {
                META_LOOKUP.put(Integer.valueOf(itemfishfood$fishtype.getMetadata()), itemfishfood$fishtype);
            }
        }
    }
}
