package com.zivilon.cinder_loe.entity.animals;

import com.zivilon.cinder_loe.CinderAchievement;
import com.zivilon.cinder_loe.entity.MonkeyBananaAI;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import lotr.common.LOTRAchievement;
import lotr.common.LOTRLevelData;
import lotr.common.LOTRMod;
import lotr.common.entity.ai.*;
import lotr.common.entity.npc.LOTRCharacter;
import lotr.common.entity.npc.LOTREntityGollum;
import lotr.common.entity.npc.LOTREntityNPC;
import lotr.common.entity.npc.LOTRSpeech;
import lotr.common.inventory.LOTRInventoryNPC;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.*;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemFood;
import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.world.World;

import java.util.List;

public class Monkey extends LOTREntityGollum {

    public static int INV_ROWS = 1;
    private int eatingTick;
    public int prevFishTime = 400;
    public boolean isFishing;
    public LOTRInventoryNPC inventory = new LOTRInventoryNPC("gollum", this, INV_ROWS * 9);
    public int prevFishRequired;
    public int fishRequired = this.prevFishRequired = 32;

    public Monkey(World world) {
        super(world);
        this.setSize(0.6f, 1.2f);
        this.getNavigator().setAvoidsWater(true);
        this.tasks.addTask(0, (EntityAIBase)new EntityAISwimming((EntityLiving)this));
        this.tasks.addTask(1, (EntityAIBase)new LOTREntityAIGollumRemainStill(this));
        this.tasks.addTask(2, (EntityAIBase)new LOTREntityAIGollumPanic(this, 1.4));
        this.tasks.addTask(3, (EntityAIBase)new LOTREntityAIGollumAvoidEntity(this, LOTREntityNPC.class, 8.0f, 1.2, 1.4));
        this.tasks.addTask(4, (EntityAIBase)new MonkeyBananaAI(this, 1.5));
        this.tasks.addTask(5, (EntityAIBase)new LOTREntityAIGollumFollowOwner(this, 1.2, 6.0f, 4.0f));
        this.tasks.addTask(6, (EntityAIBase)new EntityAIWander((EntityCreature)this, 1.0));
        this.tasks.addTask(7, (EntityAIBase)new EntityAIWatchClosest((EntityLiving)this, EntityPlayer.class, 8.0f, 0.1f));
        this.tasks.addTask(8, (EntityAIBase)new EntityAILookIdle((EntityLiving)this));

    }

    @Override
    public void onLivingUpdate() {
        double d;
        super.onLivingUpdate();
        if (!this.worldObj.isRemote && this.rand.nextInt(500) == 0) {
            this.heal(1.0f);
        }
        if (this.eatingTick > 0) {
            if (this.eatingTick % 4 == 0) {
                this.worldObj.playSoundAtEntity((Entity)this, "random.eat", 0.5f + 0.5f * (float)this.rand.nextInt(2), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2f + 1.0f);
            }
            --this.eatingTick;
        }
        if (this.prevFishTime > 0) {
            --this.prevFishTime;
        }
        if (this.isGollumSitting() && !this.worldObj.isRemote && this.onGround) {
            this.getJumpHelper().setJumping();
        }
        if (!this.worldObj.isRemote && this.getEquipmentInSlot(0) != null && this.getGollumOwner() != null && (d = this.getDistanceSqToEntity((Entity)this.getGollumOwner())) < 4.0) {
            this.getLookHelper().setLookPositionWithEntity((Entity)this.getGollumOwner(), 100.0f, 100.0f);
            this.getLookHelper().onUpdateLook();
            EntityItem entityitem = new EntityItem(this.worldObj, this.posX, this.posY + (double)this.getEyeHeight(), this.posZ, this.getEquipmentInSlot(0));
            entityitem.delayBeforeCanPickup = 40;
            float f = 0.3f;
            entityitem.motionX = -MathHelper.sin((float)(this.rotationYawHead / 180.0f * (float)Math.PI)) * MathHelper.cos((float)(this.rotationPitch / 180.0f * (float)Math.PI)) * f;
            entityitem.motionZ = MathHelper.cos((float)(this.rotationYawHead / 180.0f * (float)Math.PI)) * MathHelper.cos((float)(this.rotationPitch / 180.0f * (float)Math.PI)) * f;
            entityitem.motionY = -MathHelper.sin((float)(this.rotationPitch / 180.0f * (float)Math.PI)) * f + 0.1f;
            f = 0.02f;
            float f1 = this.rand.nextFloat() * (float)Math.PI * 2.0f;
            entityitem.motionX += Math.cos(f1) * (double)(f *= this.rand.nextFloat());
            entityitem.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1f);
            entityitem.motionZ += Math.sin(f1) * (double)f;
            this.worldObj.spawnEntityInWorld((Entity)entityitem);
            this.setCurrentItemOrArmor(0, null);
        }
        if (!this.worldObj.isRemote && StringUtils.isNullOrEmpty((String)this.getGollumOwnerUUID()) && this.rand.nextInt(40) == 0) {
            List nearbyPlayers = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.boundingBox.expand(80.0, 80.0, 80.0));
            for (Object entityplayer : nearbyPlayers) {
                double d2 = this.getDistanceToEntity((Entity)entityplayer);
                int chance = (int)(d2 / 8.0);
                if (this.rand.nextInt(chance = Math.max(2, chance)) != 0) continue;
                this.worldObj.playSoundAtEntity((Entity)entityplayer, this.getLivingSound(), this.getSoundVolume(), this.getSoundPitch());
            }
        }
    }

    @Override
    protected void applyEntityAttributes() {
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25);
    }

    private boolean canGollumEat(ItemStack itemstack) {
        if (itemstack.getItem() == LOTRMod.mango || itemstack.getItem() == LOTRMod.banana) {
            return true;
        }
        ItemFood food = (ItemFood)itemstack.getItem();
        return food.isWolfsFavoriteMeat();
    }

    @Override
    public boolean interact(EntityPlayer entityplayer) {
        if (!this.worldObj.isRemote) {
            if (this.getGollumOwner() != null && entityplayer == this.getGollumOwner()) {
                ItemStack itemstack = entityplayer.inventory.getCurrentItem();
                if (itemstack != null && itemstack.getItem() instanceof ItemFood && this.canGollumEat(itemstack) && this.getHealth() < this.getMaxHealth()) {
                    if (!entityplayer.capabilities.isCreativeMode) {
                        --itemstack.stackSize;
                        if (itemstack.stackSize <= 0) {
                            entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null);
                        }
                    }
                    this.heal(((ItemFood)itemstack.getItem()).func_150905_g(itemstack));
                    this.eatingTick = 20;
                    return true;
                }
                if (entityplayer.isSneaking()) {
                    entityplayer.openGui((Object)LOTRMod.instance, 10, this.worldObj, this.getEntityId(), 0, 0);
                    return true;
                }
                this.setGollumSitting(!this.isGollumSitting());
                if (this.isGollumSitting()) {
                    LOTRSpeech.sendSpeech(this.getGollumOwner(), this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", this.getGollumOwner()));
                } else {
                    LOTRSpeech.sendSpeech(this.getGollumOwner(), this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", this.getGollumOwner()));
                }
                return true;
            }
            ItemStack itemstack = entityplayer.inventory.getCurrentItem();
            if (itemstack != null && itemstack.getItem() == LOTRMod.banana) {
                boolean tamed = false;
                if (itemstack.stackSize >= this.fishRequired) {
                    if (!entityplayer.capabilities.isCreativeMode) {
                        itemstack.stackSize -= this.fishRequired;
                        if (itemstack.stackSize <= 0) {
                            entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null);
                        }
                    }
                    this.fishRequired = 0;
                } else {
                    this.fishRequired -= itemstack.stackSize;
                    if (!entityplayer.capabilities.isCreativeMode) {
                        entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null);
                    }
                }
                this.eatingTick = 20;
                if (this.fishRequired <= 0) {
                    this.setGollumOwnerUUID(entityplayer.getUniqueID().toString());

                    LOTRLevelData.getData(entityplayer).addAchievement(CinderAchievement.tameMonkey);
                    LOTRSpeech.messageAllPlayers((IChatComponent)new ChatComponentTranslation("chat.lotr.tameMonkey", new Object[]{entityplayer.getCommandSenderName(), this.getCommandSenderName()}));
                    LOTRSpeech.sendSpeech(entityplayer, this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", entityplayer));

                    this.spawnHearts();
                    this.prevFishRequired = this.fishRequired = Math.round((float)this.prevFishRequired * (1.5f + this.rand.nextFloat() * 0.25f));
                } else {
                    LOTRSpeech.sendSpeech(entityplayer, this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", entityplayer));
                }
                return true;
            }
        }
        return super.interact(entityplayer);
    }

    @Override
    public String getSpeechBank(EntityPlayer entityplayer) {
        if (!this.isGollumFleeing()) {
            return "monkey/say";
        }
        return super.getSpeechBank(entityplayer);
    }

    @Override
    public void onDeath(DamageSource damagesource) {
        if (!this.worldObj.isRemote && !StringUtils.isNullOrEmpty((String)this.getGollumOwnerUUID())) {
            LOTRSpeech.messageAllPlayers(this.func_110142_aN().func_151521_b());
        }
        super.onDeath(damagesource);
        if (!this.worldObj.isRemote) {
            this.inventory.dropAllItems();
        }
    }

    public String getLivingSound() {
        return "cinder_loe:monkey.idle";
    }

    public String getHurtSound() {
        return "cinder_loe:monkey.hurt";
    }

    public String getDeathSound() {
        return "cinder_loe:monkey.death";
    }

    public String getSplashSound() {
        return "lotr:ent.mallorn.summonEnt";
    }

    @SideOnly(value= Side.CLIENT)
    public void handleHealthUpdate(byte b) {
        if (b == 15) {
            for (int i = 0; i < 4; ++i) {
                double d = this.rand.nextGaussian() * 0.02;
                double d1 = this.rand.nextGaussian() * 0.02;
                double d2 = this.rand.nextGaussian() * 0.02;
                this.worldObj.spawnParticle(this.rand.nextBoolean() ? "bubble" : "splash", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0f) - (double)this.width, this.posY + 0.5 + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0f) - (double)this.width, d, d1, d2);
            }
        } else {
            super.handleHealthUpdate(b);
        }
    }

    @Override
    public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) {

    }

    @Override
    public boolean attackEntityFrom(DamageSource damagesource, float f) {
        EntityPlayer owner = this.getGollumOwner();
        if (owner != null && damagesource.getEntity() == owner) {
            f = 0.0f;
            if (!this.worldObj.isRemote) {
                LOTRSpeech.sendSpeech(owner, this, LOTRSpeech.getRandomSpeechForPlayer(this, "monkey/say", owner));
            }
        }
        if (super.attackEntityFrom(damagesource, f)) {
            this.setGollumSitting(false);
            return true;
        }
        return false;
    }
}
