package net.minecraft.entity;

import java.util.UUID;
import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.pathfinding.PathEntity;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;

public abstract class EntityCreature extends EntityLiving
{
	public static final UUID field_110179_h = UUID.fromString("E199AD21-BA8A-4C53-8D13-6182D5C69D3A");
	public static final AttributeModifier field_110181_i = (new AttributeModifier(field_110179_h, "Fleeing speed bonus", 2.0D, 2)).setSaved(false);
	private PathEntity pathToEntity;
	protected Entity entityToAttack;
	protected boolean hasAttacked;
	protected int fleeingTick;
	private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0);
	private float maximumHomeDistance = -1.0F;
	private EntityAIBase field_110178_bs = new EntityAIMoveTowardsRestriction(this, 1.0D);
	private boolean field_110180_bt;
	private static final String __OBFID = "CL_00001558";

	public EntityCreature(World par1World)
	{
		super(par1World);
	}

	protected boolean isMovementCeased()
	{
		return false;
	}

	protected void updateEntityActionState()
	{
		this.worldObj.theProfiler.startSection("ai");

		if (this.fleeingTick > 0 && --this.fleeingTick == 0)
		{
			IAttributeInstance iattributeinstance = this.getEntityAttribute(SharedMonsterAttributes.movementSpeed);
			iattributeinstance.removeModifier(field_110181_i);
		}

		this.hasAttacked = this.isMovementCeased();
		float f4 = 16.0F;

		if (this.entityToAttack == null)
		{
			this.entityToAttack = this.findPlayerToAttack();

			if (this.entityToAttack != null)
			{
				this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, f4, true, false, false, true);
			}
		}
		else if (this.entityToAttack.isEntityAlive())
		{
			float f = this.entityToAttack.getDistanceToEntity(this);

			if (this.canEntityBeSeen(this.entityToAttack))
			{
				this.attackEntity(this.entityToAttack, f);
			}
		}
		else
		{
			this.entityToAttack = null;
		}

		if (this.entityToAttack instanceof EntityPlayerMP && ((EntityPlayerMP)this.entityToAttack).theItemInWorldManager.isCreative())
		{
			this.entityToAttack = null;
		}

		this.worldObj.theProfiler.endSection();

		if (!this.hasAttacked && this.entityToAttack != null && (this.pathToEntity == null || this.rand.nextInt(20) == 0))
		{
			this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, f4, true, false, false, true);
		}
		else if (!this.hasAttacked && (this.pathToEntity == null && this.rand.nextInt(180) == 0 || this.rand.nextInt(120) == 0 || this.fleeingTick > 0) && this.entityAge < 100)
		{
			this.updateWanderPath();
		}

		int i = MathHelper.floor_double(this.boundingBox.minY + 0.5D);
		boolean flag = this.isInWater();
		boolean flag1 = this.handleLavaMovement();
		this.rotationPitch = 0.0F;

		if (this.pathToEntity != null && this.rand.nextInt(100) != 0)
		{
			this.worldObj.theProfiler.startSection("followpath");
			Vec3 vec3 = this.pathToEntity.getPosition(this);
			double d0 = (double)(this.width * 2.0F);

			while (vec3 != null && vec3.squareDistanceTo(this.posX, vec3.yCoord, this.posZ) < d0 * d0)
			{
				this.pathToEntity.incrementPathIndex();

				if (this.pathToEntity.isFinished())
				{
					vec3 = null;
					this.pathToEntity = null;
				}
				else
				{
					vec3 = this.pathToEntity.getPosition(this);
				}
			}

			this.isJumping = false;

			if (vec3 != null)
			{
				double d1 = vec3.xCoord - this.posX;
				double d2 = vec3.zCoord - this.posZ;
				double d3 = vec3.yCoord - (double)i;
				float f1 = (float)(Math.atan2(d2, d1) * 180.0D / Math.PI) - 90.0F;
				float f2 = MathHelper.wrapAngleTo180_float(f1 - this.rotationYaw);
				this.moveForward = (float)this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue();

				if (f2 > 30.0F)
				{
					f2 = 30.0F;
				}

				if (f2 < -30.0F)
				{
					f2 = -30.0F;
				}

				this.rotationYaw += f2;

				if (this.hasAttacked && this.entityToAttack != null)
				{
					double d4 = this.entityToAttack.posX - this.posX;
					double d5 = this.entityToAttack.posZ - this.posZ;
					float f3 = this.rotationYaw;
					this.rotationYaw = (float)(Math.atan2(d5, d4) * 180.0D / Math.PI) - 90.0F;
					f2 = (f3 - this.rotationYaw + 90.0F) * (float)Math.PI / 180.0F;
					this.moveStrafing = -MathHelper.sin(f2) * this.moveForward * 1.0F;
					this.moveForward = MathHelper.cos(f2) * this.moveForward * 1.0F;
				}

				if (d3 > 0.0D)
				{
					this.isJumping = true;
				}
			}

			if (this.entityToAttack != null)
			{
				this.faceEntity(this.entityToAttack, 30.0F, 30.0F);
			}

			if (this.isCollidedHorizontally && !this.hasPath())
			{
				this.isJumping = true;
			}

			if (this.rand.nextFloat() < 0.8F && (flag || flag1))
			{
				this.isJumping = true;
			}

			this.worldObj.theProfiler.endSection();
		}
		else
		{
			super.updateEntityActionState();
			this.pathToEntity = null;
		}
	}

	protected void updateWanderPath()
	{
		this.worldObj.theProfiler.startSection("stroll");
		boolean flag = false;
		int i = -1;
		int j = -1;
		int k = -1;
		float f = -99999.0F;

		for (int l = 0; l < 10; ++l)
		{
			int i1 = MathHelper.floor_double(this.posX + (double)this.rand.nextInt(13) - 6.0D);
			int j1 = MathHelper.floor_double(this.posY + (double)this.rand.nextInt(7) - 3.0D);
			int k1 = MathHelper.floor_double(this.posZ + (double)this.rand.nextInt(13) - 6.0D);
			float f1 = this.getBlockPathWeight(i1, j1, k1);

			if (f1 > f)
			{
				f = f1;
				i = i1;
				j = j1;
				k = k1;
				flag = true;
			}
		}

		if (flag)
		{
			this.pathToEntity = this.worldObj.getEntityPathToXYZ(this, i, j, k, 10.0F, true, false, false, true);
		}

		this.worldObj.theProfiler.endSection();
	}

	protected void attackEntity(Entity par1Entity, float par2) {}

	public float getBlockPathWeight(int par1, int par2, int par3)
	{
		return 0.0F;
	}

	protected Entity findPlayerToAttack()
	{
		return null;
	}

	public boolean getCanSpawnHere()
	{
		int i = MathHelper.floor_double(this.posX);
		int j = MathHelper.floor_double(this.boundingBox.minY);
		int k = MathHelper.floor_double(this.posZ);
		return super.getCanSpawnHere() && this.getBlockPathWeight(i, j, k) >= 0.0F;
	}

	public boolean hasPath()
	{
		return this.pathToEntity != null;
	}

	public void setPathToEntity(PathEntity par1PathEntity)
	{
		this.pathToEntity = par1PathEntity;
	}

	public Entity getEntityToAttack()
	{
		return this.entityToAttack;
	}

	public void setTarget(Entity par1Entity)
	{
		this.entityToAttack = par1Entity;
	}

	public boolean isWithinHomeDistanceCurrentPosition()
	{
		return this.isWithinHomeDistance(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
	}

	public boolean isWithinHomeDistance(int par1, int par2, int par3)
	{
		return this.maximumHomeDistance == -1.0F ? true : this.homePosition.getDistanceSquared(par1, par2, par3) < this.maximumHomeDistance * this.maximumHomeDistance;
	}

	public void setHomeArea(int par1, int par2, int par3, int par4)
	{
		this.homePosition.set(par1, par2, par3);
		this.maximumHomeDistance = (float)par4;
	}

	public ChunkCoordinates getHomePosition()
	{
		return this.homePosition;
	}

	public float func_110174_bM()
	{
		return this.maximumHomeDistance;
	}

	public void detachHome()
	{
		this.maximumHomeDistance = -1.0F;
	}

	public boolean hasHome()
	{
		return this.maximumHomeDistance != -1.0F;
	}

	protected void updateLeashedState()
	{
		super.updateLeashedState();

		if (this.getLeashed() && this.getLeashedToEntity() != null && this.getLeashedToEntity().worldObj == this.worldObj)
		{
			Entity entity = this.getLeashedToEntity();
			this.setHomeArea((int)entity.posX, (int)entity.posY, (int)entity.posZ, 5);
			float f = this.getDistanceToEntity(entity);

			if (this instanceof EntityTameable && ((EntityTameable)this).isSitting())
			{
				if (f > 10.0F)
				{
					this.clearLeashed(true, true);
				}

				return;
			}

			if (!this.field_110180_bt)
			{
				this.tasks.addTask(2, this.field_110178_bs);
				this.getNavigator().setAvoidsWater(false);
				this.field_110180_bt = true;
			}

			this.func_142017_o(f);

			if (f > 4.0F)
			{
				this.getNavigator().tryMoveToEntityLiving(entity, 1.0D);
			}

			if (f > 6.0F)
			{
				double d0 = (entity.posX - this.posX) / (double)f;
				double d1 = (entity.posY - this.posY) / (double)f;
				double d2 = (entity.posZ - this.posZ) / (double)f;
				this.motionX += d0 * Math.abs(d0) * 0.4D;
				this.motionY += d1 * Math.abs(d1) * 0.4D;
				this.motionZ += d2 * Math.abs(d2) * 0.4D;
			}

			if (f > 10.0F)
			{
				this.clearLeashed(true, true);
			}
		}
		else if (!this.getLeashed() && this.field_110180_bt)
		{
			this.field_110180_bt = false;
			this.tasks.removeTask(this.field_110178_bs);
			this.getNavigator().setAvoidsWater(true);
			this.detachHome();
		}
	}

	protected void func_142017_o(float par1) {}
}