package halo.items;
import java.lang.reflect.InvocationTargetException;

import halo.ClientBridge;
import halo.HaloMod;
import halo.ProjectileHelper;
import halo.entities.EntityBullet;
import halo.entities.EntityProjectile;

import org.lwjgl.util.vector.Vector3f;

import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;

public class ItemGun extends Item
{
	public int FireDelay;
	public int BulletDamage;
	public String SoundEffect;
	public String Icon;
	public int Burst = 1;
	public int Ammo;
	public int roundsLeft;
	public int clipSize = 32;
	private int roundsFired = 0;
	public int shotsFired = 1;
	public double Recoil = .19f;
	public boolean Automatic = false;
	public boolean clientFired = false;
	private int clientTicks = 0;
	private int clientRoundsFired;
	@Override
	public void registerIcons(IconRegister ir)
	{
		this.itemIcon = ir.registerIcon(this.Icon);
	}
	public ItemGun(int ID, int delay, int damage, String sound, String icon)
	{
		super(ID);
		this.roundsLeft = clipSize;
		this.FireDelay = delay;
		this.BulletDamage = damage;
		this.SoundEffect = sound;
		this.Icon = icon;
	}
	public ItemGun(int par1)
	{
		super(par1);
	}

	private long ticksSinceLastShot = 0;
	private boolean gunFired = false;
	private boolean canZoom = true;
	private float FOV;
	protected boolean canFire(EntityPlayer plyer)
	{
		if (plyer.capabilities.isCreativeMode)
		{
			return true;
		}
		else if (plyer.inventory.consumeInventoryItem(this.Ammo))
		{
			return true;
		}

		return false;
	}
	@Override
	public void onUpdate(ItemStack par1ItemStack, World par2World, Entity entityLiving, int par4, boolean par5)
	{
		
		if (this.roundsFired < this.Burst  && gunFired && !par2World.isRemote)
		{
			if (canFire((EntityPlayer)entityLiving))
			{
				try
				{
					shoot((EntityPlayer)entityLiving);
					clientFired = false;
				}
				catch (Exception e)
				{
				}
			}

			if (!entityLiving.worldObj.isRemote)
			{
				this.roundsFired++;
			}
		}
		else if (clientFired && par2World.isRemote) {
			shoot((EntityPlayer)entityLiving);
			clientRoundsFired++;
			if(clientRoundsFired >= this.Burst) {
				clientFired = false;
				clientRoundsFired = 0;
			}
		}
		if (!entityLiving.worldObj.isRemote)
			if (gunFired && ticksSinceLastShot <= FireDelay)
			{
				ticksSinceLastShot++;
			}
			else
			{
				gunFired = false;
			}
	}
	public void shoot(EntityPlayer entityLiving) {
		for (int i = 0; i < this.shotsFired; i++)
		{
			Entity round;

			try
			{
				round  = (Entity)(ProjectileHelper.getProjectileFromAmmo(this.Ammo).getDeclaredConstructor(new Class[] {World.class, EntityLivingBase.class})).newInstance(entityLiving.worldObj, (EntityLivingBase)entityLiving);
				((EntityProjectile)round).Damage = this.BulletDamage;
				entityLiving.worldObj.spawnEntityInWorld(round);
			}
			catch (Exception e)
			{
			}
		}
	}
	public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer entityLiving)
	{
		if (!gunFired )
		{
			if (canFire((EntityPlayer)entityLiving) && !par2World.isRemote)
			{
				ClientBridge.BroadcastSound(this.SoundEffect, entityLiving.posX, entityLiving.posY, entityLiving.posZ);
				ClientBridge.CreateRecoil(this.Recoil + 1, (Player)entityLiving);
				shoot(entityLiving);
				clientFired = true;
				this.roundsFired = 1;

				this.roundsLeft--;

				if (this.roundsLeft <= 0)
				{
					this.roundsLeft = this.clipSize;
				}

				ticksSinceLastShot = 0;

				if (this.FireDelay != 0)
				{
					gunFired = true;
				}

			}
			else if (!par2World.isRemote)
			{
				ClientBridge.BroadcastSound("halo:dryfire", entityLiving.posX, entityLiving.posY, entityLiving.posZ);
			}
		}

		return par1ItemStack;
	}
}
