package hmggirlfront.block.tile;
 
import java.util.List;

import javax.annotation.Nullable;

import hmggirlfront.mod_GirlFront;
import hmggirlfront.entity.mob.EntityIBC01;
import hmggirlfront.entity.mob.EntityIBC04;
import hmggirlfront.entity.mob.EntityIBC05;
import hmggirlfront.entity.mob.EntityIBC06;
import hmggirlfront.entity.mob.EntityIBC07;
import hmggirlfront.entity.mob.EntityIBC13;
import hmggirlfront.entity.mob.EntityIBC14;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
 
public class TileEntity_Spawn extends TileEntity implements ITickable
{
	public boolean spawn = false;
	
	public int count = 0;
	
	public int id = 0;
    
	@SideOnly(Side.CLIENT)
    public double getMaxRenderDistanceSquared()
    {
        return 65536.0D;
    }
	
    @Override
	public void update() {
    	Block block = this.world.getBlockState(this.pos).getBlock();
        
        int x = this.pos.getX();
        int y= this.pos.getY();
        int z = this.pos.getZ();
        
        if(this.world.getBlockState(new BlockPos(x, y + 1, z)).getBlock() == Blocks.IRON_BLOCK) {
        	this.canspawn(x, y, z, 80, 16);
        }
        else {
        	this.canspawn(x, y, z, mod_GirlFront.cfg_spawner_range, 16);
        }
        if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc01) {
        	id = 1;
        }else if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc04) {
        	id = 4;
        }else if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc05) {
        	id = 5;
        }else if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc06) {
        	id = 6;
        }else if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc07) {
        	id = 7;
        }else if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc13) {
        	id = 13;
        }else if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc14) {
        	id = 14;
        }
        
        if(spawn) {
        	 //if(!this.world.isRemote)++count;
        	 ++count;
             if(!this.world.isRemote)
             {
            	 boolean canspawn = false;
            	 if(mod_GirlFront.cfg_spawner_one_time_onry) {
            		 canspawn = true;
            	 }else {
            		 if(count > mod_GirlFront.cfg_spawner_time) {
            			 canspawn = true;
            		 }
            	 }
            	 if(canspawn) {
            		 if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc01) {
              			int i = this.world.rand.nextInt(4)+3+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC01 entityskeleton = new EntityIBC01(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc04) {
              			int i = this.world.rand.nextInt(3)+2+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC04 entityskeleton = new EntityIBC04(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(mod_GirlFront.dollgun_ibc04smg));
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.OFFHAND, new ItemStack(mod_GirlFront.dollgun_ibc04smg));
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc05) {
              			int i = this.world.rand.nextInt(3)+2+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC05 entityskeleton = new EntityIBC05(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(mod_GirlFront.dollgun_ibc05ar));
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc06) {
              			int i = this.world.rand.nextInt(2)+1+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC06 entityskeleton = new EntityIBC06(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(mod_GirlFront.dollgun_ibc06rf));
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc07) {
              			int i = this.world.rand.nextInt(2)+1+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC07 entityskeleton = new EntityIBC07(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(mod_GirlFront.dollgun_ibc07hg));
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.OFFHAND, new ItemStack(mod_GirlFront.dollgun_ibc07sd));
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc13) {
              			int i = this.world.rand.nextInt(2)+1+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC13 entityskeleton = new EntityIBC13(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(mod_GirlFront.dollgun_ibc13glg));
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(this.world.getBlockState(this.pos).getBlock() == mod_GirlFront.b_spanwer_ibc14) {
              			int i = this.world.rand.nextInt(2)+1+this.world.getDifficulty().getDifficultyId();
          		        for(int ii = 0; ii < i; ++ii){
          		        	int ix = this.world.rand.nextInt(8);
          					int iz = this.world.rand.nextInt(8);
          		        	EntityIBC14 entityskeleton = new EntityIBC14(this.world);
          		        	entityskeleton.setLocationAndAngles(x - 4 +ix, y+1, z - 4 +iz, 0, 0.0F);
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(mod_GirlFront.dollgun_ibc14sw));
          		        	entityskeleton.setItemStackToSlot(EntityEquipmentSlot.OFFHAND, new ItemStack(mod_GirlFront.dollgun_ibc14sw));
          		        	if(mod_GirlFront.cfg_spawner_one_time_onry) entityskeleton.setcanDespawn(1);
          			        this.world.spawnEntity(entityskeleton);
          		        }
      		        }
              		if(!this.world.isRemote)count = 0;
              		if(!this.world.isRemote){
              			if(mod_GirlFront.cfg_spawner_one_time_onry)this.world.setBlockToAir(this.pos);
                     }
            	 }
             }
        }
       
	}
	
    public void canspawn(double x, double y, double z, int han, int han2) {
    	
    	if(!mod_GirlFront.cfg_spawner_one_time_onry) {
    		boolean canspawn = false;
    		spawn = false;
        	int mob = 0;
        	
        	{
        		Entity entity = null;
            	AxisAlignedBB axisalignedbb2 = (new AxisAlignedBB((double)(x-han), (double)(y-han), (double)(z-han), 
            			(double)(x + han), (double)(y + han), (double)(z+ han)))
                		.grow(1);
                List llist2 = this.world.getEntitiesWithinAABBExcludingEntity(entity, axisalignedbb2);
                if(llist2!=null){
                    for (int lj = 0; lj < llist2.size(); lj++) {
                    	
                    	Entity entity1 = (Entity)llist2.get(lj);
                    	if (entity1.canBeCollidedWith())
                        {
                    		if (entity1 instanceof EntityPlayer && entity1 != null)
                            {
                    			EntityPlayer ss = (EntityPlayer) entity1;
                    			ItemStack itemstack = ss.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
                        		if(!itemstack.isEmpty() && itemstack.getItem() == Items.GOLDEN_HELMET){
                        		}else {
                        			canspawn = true;
                        		}
                            }
                        }
                    }
                }
        	}
        	if(canspawn){
        		Entity entity = null;
            	AxisAlignedBB axisalignedbb2 = (new AxisAlignedBB((double)(x-han2), (double)(y-han2), (double)(z-han2), 
            			(double)(x + han2), (double)(y + han2), (double)(z+ han2)))
                		.grow(1);
                List llist2 = this.world.getEntitiesWithinAABBExcludingEntity(entity, axisalignedbb2);
                if(llist2!=null){
                    for (int lj = 0; lj < llist2.size(); lj++) {
                    	
                    	Entity entity1 = (Entity)llist2.get(lj);
                    	if (entity1.canBeCollidedWith())
                        {
                    		if (entity1 instanceof IMob && entity1 != null)
                            {
                    			++mob;
                            }
                        }
                    }
                }
                if(mob < mod_GirlFront.cfg_spawner_limit) {
                	spawn = true;
                }else {
                	spawn = false;
                }
        	}
    	}else {
    	/*if(this.world.isRemote)return;
    	Entity entity = null;
    	boolean player = false;
    	{
    		AxisAlignedBB axisalignedbb2 = (new AxisAlignedBB((double)(x-han), (double)(y-han), (double)(z-han), 
        			(double)(x + han), (double)(y + han), (double)(z+ han)))
            		.grow(1);
            List llist2 = this.world.getEntitiesWithinAABBExcludingEntity(entity, axisalignedbb2);
            if(llist2!=null){
                for (int lj = 0; lj < llist2.size(); lj++) {
                	
                	Entity entity1 = (Entity)llist2.get(lj);
                	if (entity1.canBeCollidedWith())
                    {
                		if (entity1 instanceof EntityPlayer && entity1 != null)
                        {
                			EntityPlayer ss = (EntityPlayer) entity1;
                			ItemStack itemstack = ss.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
                    		if(!itemstack.isEmpty() && itemstack.getItem() == Items.GOLDEN_HELMET){
                    		}else {
                    			player = true;
                    		}
                        }
                    }
                }
            }
    	}
    	int mob = 0;
    	if(player){
    		AxisAlignedBB axisalignedbb2 = (new AxisAlignedBB((double)(x-han2), (double)(y-han2), (double)(z-han2), 
        			(double)(x + han2), (double)(y + han2), (double)(z+ han2)))
            		.grow(1);
            List llist2 = this.world.getEntitiesWithinAABBExcludingEntity(entity, axisalignedbb2);
            if(llist2!=null){
                for (int lj = 0; lj < llist2.size(); lj++) {
                	Entity entity1 = (Entity)llist2.get(lj);
                	if (entity1.canBeCollidedWith())
                    {
                		if (entity1 != null && entity1 instanceof EntityLivingBase)
                        {
                			++mob;
                        }
                    }
                }
            }
            //if(mob < mod_GirlFront.cfg_spawner_limit) 
            if(mob < 10) 
            {
        		spawn = true;
        	}
    	}*/
    	Entity entity = null;
    	AxisAlignedBB axisalignedbb2 = (new AxisAlignedBB((double)(x-han), (double)(y-han), (double)(z-han), 
    			(double)(x + han), (double)(y + han), (double)(z+ han)))
        		.grow(1);
        List llist2 = this.world.getEntitiesWithinAABBExcludingEntity(entity, axisalignedbb2);
        if(llist2!=null){
            for (int lj = 0; lj < llist2.size(); lj++) {
            	
            	Entity entity1 = (Entity)llist2.get(lj);
            	if (entity1.canBeCollidedWith())
                {
            		if (entity1 instanceof EntityPlayer && entity1 != null)
                    {
            			EntityPlayer ss = (EntityPlayer) entity1;
            			ItemStack itemstack = ss.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
                		if(!itemstack.isEmpty() && itemstack.getItem() == Items.GOLDEN_HELMET){
                		}else {
                			double d5 = entity1.posX - this.pos.getX();
							double d7 = entity1.posZ - this.pos.getZ();
							double ddx = Math.abs(d5);
							double ddz = Math.abs(d7);
							if ((ddx < 15 && ddz < 15)) {
								spawn = true;
							}else 
                			/*if(this.world.rayTraceBlocks(new Vec3d(this.pos.getX()+0.2, this.pos.getY()+0.2, this.pos.getZ()+0.2), 
                					new Vec3d(entity1.posX, entity1.posY + (double)entity1.getEyeHeight(), entity1.posZ), false, true, false) == null) */
                			if(rayTraceBlocks(new Vec3d(this.pos.getX() + 0.1, this.pos.getY() + 0.85, this.pos.getZ() + 0.1), 
                					new Vec3d(entity1.posX, entity1.posY + (double)entity1.getEyeHeight(), entity1.posZ), false, true, false) == null) 
                			{
                				spawn = true;
                			}
                		}
                    }
                }
            }
        }
    	}
    }
    
    
    
    
    /**
     * Performs a raycast against all blocks in the world. Args : Vec1, Vec2, stopOnLiquid,
     * ignoreBlockWithoutBoundingBox, returnLastUncollidableBlock
     */
    @Nullable
    public RayTraceResult rayTraceBlocks(Vec3d vec31, Vec3d vec32, boolean stopOnLiquid, boolean ignoreBlockWithoutBoundingBox, boolean returnLastUncollidableBlock)
    {
        if (!Double.isNaN(vec31.x) && !Double.isNaN(vec31.y) && !Double.isNaN(vec31.z))
        {
            if (!Double.isNaN(vec32.x) && !Double.isNaN(vec32.y) && !Double.isNaN(vec32.z))
            {
                int i = MathHelper.floor(vec32.x);
                int j = MathHelper.floor(vec32.y);
                int k = MathHelper.floor(vec32.z);
                int l = MathHelper.floor(vec31.x);
                int i1 = MathHelper.floor(vec31.y);
                int j1 = MathHelper.floor(vec31.z);
                BlockPos blockpos = new BlockPos(l, i1, j1);
                IBlockState iblockstate = this.world.getBlockState(blockpos);
                Block block = iblockstate.getBlock();

                //if ((!ignoreBlockWithoutBoundingBox || iblockstate.getCollisionBoundingBox(this.world, blockpos) != Block.NULL_AABB) && block.canCollideCheck(iblockstate, stopOnLiquid))
                 if ((!ignoreBlockWithoutBoundingBox && block.canCollideCheck(iblockstate, stopOnLiquid)))
                {
                    RayTraceResult raytraceresult = iblockstate.collisionRayTrace(this.world, blockpos, vec31, vec32);

                    if (raytraceresult != null)
                    {
                        return raytraceresult;
                    }
                }

                RayTraceResult raytraceresult2 = null;
                int k1 = 200;

                while (k1-- >= 0)
                {
                    if (Double.isNaN(vec31.x) || Double.isNaN(vec31.y) || Double.isNaN(vec31.z))
                    {
                        return null;
                    }

                    if (l == i && i1 == j && j1 == k)
                    {
                        return returnLastUncollidableBlock ? raytraceresult2 : null;
                    }

                    boolean flag2 = true;
                    boolean flag = true;
                    boolean flag1 = true;
                    double d0 = 999.0D;
                    double d1 = 999.0D;
                    double d2 = 999.0D;

                    if (i > l)
                    {
                        d0 = (double)l + 1.0D;
                    }
                    else if (i < l)
                    {
                        d0 = (double)l + 0.0D;
                    }
                    else
                    {
                        flag2 = false;
                    }

                    if (j > i1)
                    {
                        d1 = (double)i1 + 1.0D;
                    }
                    else if (j < i1)
                    {
                        d1 = (double)i1 + 0.0D;
                    }
                    else
                    {
                        flag = false;
                    }

                    if (k > j1)
                    {
                        d2 = (double)j1 + 1.0D;
                    }
                    else if (k < j1)
                    {
                        d2 = (double)j1 + 0.0D;
                    }
                    else
                    {
                        flag1 = false;
                    }

                    double d3 = 999.0D;
                    double d4 = 999.0D;
                    double d5 = 999.0D;
                    double d6 = vec32.x - vec31.x;
                    double d7 = vec32.y - vec31.y;
                    double d8 = vec32.z - vec31.z;

                    if (flag2)
                    {
                        d3 = (d0 - vec31.x) / d6;
                    }

                    if (flag)
                    {
                        d4 = (d1 - vec31.y) / d7;
                    }

                    if (flag1)
                    {
                        d5 = (d2 - vec31.z) / d8;
                    }

                    if (d3 == -0.0D)
                    {
                        d3 = -1.0E-4D;
                    }

                    if (d4 == -0.0D)
                    {
                        d4 = -1.0E-4D;
                    }

                    if (d5 == -0.0D)
                    {
                        d5 = -1.0E-4D;
                    }

                    EnumFacing enumfacing;

                    if (d3 < d4 && d3 < d5)
                    {
                        enumfacing = i > l ? EnumFacing.WEST : EnumFacing.EAST;
                        vec31 = new Vec3d(d0, vec31.y + d7 * d3, vec31.z + d8 * d3);
                    }
                    else if (d4 < d5)
                    {
                        enumfacing = j > i1 ? EnumFacing.DOWN : EnumFacing.UP;
                        vec31 = new Vec3d(vec31.x + d6 * d4, d1, vec31.z + d8 * d4);
                    }
                    else
                    {
                        enumfacing = k > j1 ? EnumFacing.NORTH : EnumFacing.SOUTH;
                        vec31 = new Vec3d(vec31.x + d6 * d5, vec31.y + d7 * d5, d2);
                    }

                    l = MathHelper.floor(vec31.x) - (enumfacing == EnumFacing.EAST ? 1 : 0);
                    i1 = MathHelper.floor(vec31.y) - (enumfacing == EnumFacing.UP ? 1 : 0);
                    j1 = MathHelper.floor(vec31.z) - (enumfacing == EnumFacing.SOUTH ? 1 : 0);
                    blockpos = new BlockPos(l, i1, j1);
                    IBlockState iblockstate1 = this.world.getBlockState(blockpos);
                    Block block1 = iblockstate1.getBlock();

                    if (!ignoreBlockWithoutBoundingBox || iblockstate1.getMaterial() == Material.PORTAL || iblockstate1.getCollisionBoundingBox(this.world, blockpos) != Block.NULL_AABB)
                  //  if (!ignoreBlockWithoutBoundingBox || iblockstate1.getMaterial() == Material.PORTAL)
                    {
                        if (block1.canCollideCheck(iblockstate1, stopOnLiquid))
                        {
                            RayTraceResult raytraceresult1 = iblockstate1.collisionRayTrace(this.world, blockpos, vec31, vec32);

                            if (raytraceresult1 != null)
                            {
                                return raytraceresult1;
                            }
                        }
                        else
                        {
                            raytraceresult2 = new RayTraceResult(RayTraceResult.Type.MISS, vec31, enumfacing, blockpos);
                        }
                    }
                }

                return returnLastUncollidableBlock ? raytraceresult2 : null;
            }
            else
            {
                return null;
            }
        }
        else
        {
            return null;
        }
    }
}