package common.tileentity;

import common.entity.Entity;
import common.entity.types.EntityLiving;
import common.init.Blocks;
import common.init.Config;
import common.init.EntityRegistry;
import common.model.ParticleType;
import common.nbt.NBTTagCompound;
import common.network.Packet;
import common.packet.S35PacketUpdateTileEntity;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.world.World;

public class TileEntityMobSpawner extends TileEntity implements ITickable
{
    private int spawnDelay = 20;
    private String mobID = "Pig";
    private double mobRotation;
    private double prevMobRotation;
    private int minSpawnDelay = 200;
    private int maxSpawnDelay = 800;
    private int spawnCount = 4;
    private Entity cachedEntity;
    private int maxNearbyEntities = 6;
    private int activatingRangeFromPlayer = 16;
    private int spawnRange = 4;
    
    public Packet getDescriptionPacket()
    {
        return new S35PacketUpdateTileEntity(this);
    }

    public boolean receiveClientEvent(int id, int type)
    {
        if (id == 1 && this.worldObj.client)
        {
            this.spawnDelay = this.minSpawnDelay;
            return true;
        }
        else
        {
            return super.receiveClientEvent(id, type);
        }
    }

//    public boolean hasSpecialNBT()
//    {
//        return true;
//    }
    
    public int getColor() {
    	return 0xff0000;
    }
    
    public void update()
    {
        BlockPos blockpos = this.pos;
        if (this.worldObj.isAnyPlayerWithinRangeAt((double)blockpos.getX() + 0.5D, (double)blockpos.getY() + 0.5D, (double)blockpos.getZ() + 0.5D, (double)this.activatingRangeFromPlayer))
        {
            if (this.worldObj.client)
            {
                double d3 = (double)((float)blockpos.getX() + this.worldObj.rand.floatv());
                double d4 = (double)((float)blockpos.getY() + this.worldObj.rand.floatv());
                double d5 = (double)((float)blockpos.getZ() + this.worldObj.rand.floatv());
                this.worldObj.spawnParticle(ParticleType.SMOKE_NORMAL, d3, d4, d5, 0.0D, 0.0D, 0.0D);
                this.worldObj.spawnParticle(ParticleType.FLAME, d3, d4, d5, 0.0D, 0.0D, 0.0D);

                if (this.spawnDelay > 0)
                {
                    --this.spawnDelay;
                }

                this.prevMobRotation = this.mobRotation;
                this.mobRotation = (this.mobRotation + (double)(1000.0F / ((float)this.spawnDelay + 200.0F))) % 360.0D;
            }
            else
            {
            	if(!Config.mobs || !Config.spawners) {
            		return;
            	}
            	
                if (this.spawnDelay == -1)
                {
                    this.resetTimer();
                }

                if (this.spawnDelay > 0)
                {
                    --this.spawnDelay;
                    return;
                }

                boolean flag = false;

                for (int i = 0; i < this.spawnCount; ++i)
                {
                    Entity entity = EntityRegistry.createEntityByName(this.mobID, this.worldObj);

                    if (entity == null)
                    {
                        return;
                    }

                    int j = this.worldObj.getEntitiesWithinAABB(entity.getClass(), (new BoundingBox((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ(), (double)(blockpos.getX() + 1), (double)(blockpos.getY() + 1), (double)(blockpos.getZ() + 1))).expand((double)this.spawnRange, (double)this.spawnRange, (double)this.spawnRange)).size();

                    if (j >= this.maxNearbyEntities)
                    {
                        this.resetTimer();
                        return;
                    }

                    double d0 = (double)blockpos.getX() + (this.worldObj.rand.doublev() - this.worldObj.rand.doublev()) * (double)this.spawnRange + 0.5D;
                    double d1 = (double)(blockpos.getY() + this.worldObj.rand.zrange(3) - 1);
                    double d2 = (double)blockpos.getZ() + (this.worldObj.rand.doublev() - this.worldObj.rand.doublev()) * (double)this.spawnRange + 0.5D;
                    EntityLiving entityliving = entity instanceof EntityLiving ? (EntityLiving)entity : null;
                    entity.setLocationAndAngles(d0, d1, d2, this.worldObj.rand.floatv() * 360.0F, 0.0F);

                    if (entityliving == null || entityliving.getCanSpawnHere() && entityliving.isNotColliding())
                    {
                        if (entity instanceof EntityLiving && entity.worldObj != null)
						{
//						    if (entity instanceof EntityLiving)
//						    {
						    ((EntityLiving)entity).onInitialSpawn(null);
//						    }
						
						    entity.worldObj.spawnEntityInWorld(entity);
						}
                        this.worldObj.playAuxSFX(2004, blockpos, 0);

                        if (entityliving != null)
                        {
                            entityliving.spawnExplosionParticle();
                        }

                        flag = true;
                    }
                }

                if (flag)
                {
                    this.resetTimer();
                }
            }
        }
    }

    private void resetTimer()
    {
        if (this.maxSpawnDelay <= this.minSpawnDelay)
        {
            this.spawnDelay = this.minSpawnDelay;
        }
        else
        {
            int i = this.maxSpawnDelay - this.minSpawnDelay;
            this.spawnDelay = this.minSpawnDelay + this.worldObj.rand.zrange(i);
        }

        this.worldObj.addBlockEvent(TileEntityMobSpawner.this.pos, Blocks.mob_spawner, 1, 0);
    }

    public void readFromNBT(NBTTagCompound nbt)
    {
        super.readFromNBT(nbt);
        this.mobID = nbt.getString("EntityId");
        this.spawnDelay = nbt.getShort("Delay");

        if (nbt.hasKey("MinSpawnDelay", 99))
        {
            this.minSpawnDelay = nbt.getShort("MinSpawnDelay");
            this.maxSpawnDelay = nbt.getShort("MaxSpawnDelay");
            this.spawnCount = nbt.getShort("SpawnCount");
        }

        if (nbt.hasKey("MaxNearbyEntities", 99))
        {
            this.maxNearbyEntities = nbt.getShort("MaxNearbyEntities");
            this.activatingRangeFromPlayer = nbt.getShort("RequiredPlayerRange");
        }

        if (nbt.hasKey("SpawnRange", 99))
        {
            this.spawnRange = nbt.getShort("SpawnRange");
        }

        if (this.worldObj != null)
        {
            this.cachedEntity = null;
        }
    }

    public void writeToNBT(NBTTagCompound nbt)
    {
        super.writeToNBT(nbt);
        String s = this.mobID;

        if (s != null && !s.isEmpty())
        {
            nbt.setString("EntityId", s);
            nbt.setShort("Delay", (short)this.spawnDelay);
            nbt.setShort("MinSpawnDelay", (short)this.minSpawnDelay);
            nbt.setShort("MaxSpawnDelay", (short)this.maxSpawnDelay);
            nbt.setShort("SpawnCount", (short)this.spawnCount);
            nbt.setShort("MaxNearbyEntities", (short)this.maxNearbyEntities);
            nbt.setShort("RequiredPlayerRange", (short)this.activatingRangeFromPlayer);
            nbt.setShort("SpawnRange", (short)this.spawnRange);
        }
    }

    public Entity createRenderEntity(World worldIn)
    {
        if (this.cachedEntity == null)
        {
        	this.cachedEntity = EntityRegistry.createEntityByName(this.mobID, worldIn);

//            if (entity != null)
//            {
////                entity = this.spawnNewEntity(entity, false);
//                this.cachedEntity = entity;
//            }
        }

        return this.cachedEntity;
    }

    public double getMobRotation()
    {
        return this.mobRotation;
    }

    public double getPrevMobRotation()
    {
        return this.prevMobRotation;
    }

    public void setEntityName(String name)
    {
        this.mobID = name;
    }
}
