package totemic_commons.pokefenn.item.equipment.weapon;

import static totemic_commons.pokefenn.Totemic.logger;

import java.lang.reflect.Method;

import org.apache.logging.log4j.Level;

import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemArrow;
import net.minecraft.item.ItemBow;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.util.SoundCategory;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import totemic_commons.pokefenn.Totemic;
import totemic_commons.pokefenn.entity.projectile.EntityInvisArrow;
import totemic_commons.pokefenn.lib.Strings;

public class ItemBaykokBow extends ItemBow
{
    private static final Method getArrowMethod = ReflectionHelper.findMethod(ItemBow.class, null, new String[] {"func_185060_a"}, EntityPlayer.class);

    public ItemBaykokBow()
    {
        setRegistryName(Strings.BAYKOK_BOW_NAME);
        setUnlocalizedName(Strings.RESOURCE_PREFIX + Strings.BAYKOK_BOW_NAME);
        setCreativeTab(Totemic.tabsTotem);
        setMaxDamage(576);
    }

    @Override
    public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase entity, int timeLeft)
    {
        //TODO: Make it work properly with all types of arrows
        if(!(entity instanceof EntityPlayer))
            return;

        EntityPlayer player = (EntityPlayer)entity;
        boolean infinity = player.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantments.INFINITY, stack) > 0;
        ItemStack arrow = getArrow(player);

        int chargeTicks = this.getMaxItemUseDuration(stack) - timeLeft;
        chargeTicks = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, world, player, chargeTicks, arrow != null || infinity);
        if(chargeTicks < 0) return;

        if(arrow != null || infinity)
        {
            if (arrow == null)
                arrow = new ItemStack(Items.ARROW);

            float charge = getArrowVelocity(chargeTicks);

            if(charge >= 0.1D)
            {
                boolean flag1 = infinity && arrow.getItem() instanceof ItemArrow; //Forge: Fix consuming custom arrows.

                if(!world.isRemote)
                {
                    //ItemArrow itemarrow = ((ItemArrow)(arrow.getItem() instanceof ItemArrow ? arrow.getItem() : Items.arrow));
                    EntityArrow entityarrow = new EntityInvisArrow(world, player);//itemarrow.makeTippedArrow(world, arrow, player);
                    entityarrow.setDamage(2.5);
                    entityarrow.setAim(player, player.rotationPitch, player.rotationYaw, 0.0F, charge * 3.0F, 1.0F);

                    if(charge == 1.0F)
                        entityarrow.setIsCritical(true);

                    int power = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack);
                    if(power > 0)
                        entityarrow.setDamage(entityarrow.getDamage() + power * 0.5D + 0.5D);

                    int punch = EnchantmentHelper.getEnchantmentLevel(Enchantments.PUNCH, stack);
                    if(punch > 0)
                        entityarrow.setKnockbackStrength(punch);

                    if(EnchantmentHelper.getEnchantmentLevel(Enchantments.FLAME, stack) > 0)
                        entityarrow.setFire(100);

                    stack.damageItem(1, player);

                    if(flag1)
                        entityarrow.pickupStatus = EntityArrow.PickupStatus.CREATIVE_ONLY;

                    world.spawnEntityInWorld(entityarrow);
                }

                world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.NEUTRAL, 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + charge * 0.5F);

                if(!flag1)
                {
                    --arrow.stackSize;

                    if(arrow.stackSize == 0)
                        player.inventory.deleteStack(arrow);
                }

                player.addStat(StatList.getObjectUseStats(this));
            }
        }
    }

    private ItemStack getArrow(EntityPlayer player)
    {
        try
        {
            return (ItemStack)getArrowMethod.invoke(this, player);
        }
        catch(ReflectiveOperationException e)
        {
            logger.catching(Level.ERROR, e);
            return null;
        }
    }

    @Override
    public int getItemEnchantability()
    {
        return 5;
    }

    @Override
    public boolean hasEffect(ItemStack stack)
    {
        return true;
    }
}

@@ -1003,24 +1003,24 @@
  Method 
-getArrow
+findAmmo
 Method =
@@ -1098,16 +1098,28 @@
 85060_a%22
+, %22findAmmo%22
 %7D, Entit
@@ -1846,24 +1846,24 @@
 arrow = 
-getArrow
+findAmmo
 (player)
@@ -2105,16 +2105,28 @@
 cks %3C 0)
+%0A           
  return;
@@ -2189,17 +2189,16 @@
       if
- 
 (arrow =
@@ -4395,21 +4395,23 @@
 %0A%0A    pr
-ivate
+otected
  ItemSta
@@ -4413,24 +4413,24 @@
 emStack 
-getArrow
+findAmmo
 (EntityP
@@ -4501,24 +4501,24 @@
 emStack)
-getArrow
+findAmmo
 Method.i

Fix reflection crash