package thebetweenlands.common.item.misc;

import java.util.ArrayList;
import java.util.List;

import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import thebetweenlands.api.item.IBigSwingAnimation;
import thebetweenlands.client.tab.BLCreativeTabs;
import thebetweenlands.common.block.misc.BlockMistBridge;
import thebetweenlands.common.block.misc.BlockShadowWalker;
import thebetweenlands.common.entity.EntityMistBridge;
import thebetweenlands.common.registries.SoundRegistry;

public class ItemShadowStaff extends Item implements IBigSwingAnimation {

	public ItemShadowStaff() {
		setMaxStackSize(1);
		setMaxDamage(64);
		setCreativeTab(BLCreativeTabs.SPECIALS);
	}

	@Override
	public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {	
		ItemStack stack = player.getHeldItem(hand);
		BlockPos pos = player.getPosition();

		if(player.getCooldownTracker().hasCooldown(this))
			return new ActionResult<ItemStack>(EnumActionResult.PASS, stack);

		if (world.isAirBlock(pos)) {
			if (!world.isRemote) {
				stack.damageItem(2, player);

				double direction = Math.toRadians(player.rotationYaw);
				Vec3d diag = new Vec3d(Math.sin(direction + Math.PI / 2.0D), 0, Math.cos(direction + Math.PI / 2.0D)).normalize();
				List<BlockPos> spawnedPos = new ArrayList<BlockPos>();
				List<BlockPos> convertPos = new ArrayList<BlockPos>();
				List<Integer> blockDistance = new ArrayList<Integer>();

				for (int distance = -1; distance <= 16; distance++) {
					for (int distance2 = -distance; distance2 <= distance; distance2++) {
						for (int yo = 0; yo <= 1; yo++) {
							int originX = MathHelper.floor(pos.getX() + 0.5D - Math.sin(direction) * distance - diag.x * distance2 * 0.25D);
							int originY = pos.getY() + yo;
							int originZ = MathHelper.floor(pos.getZ() + 0.5D + Math.cos(direction) * distance + diag.z * distance2 * 0.25D);
							BlockPos origin = new BlockPos(originX, originY, originZ);

							if (spawnedPos.contains(origin))
								continue;

							spawnedPos.add(origin);

							IBlockState block = world.getBlockState(new BlockPos(originX, originY, originZ));

							if (isShadowableBlock(world, player, origin, block)) {
								convertPos.add(origin);
								blockDistance.add(distance);
								break;
							}
						}
					}
				}

				spawnEntity(world, pos, blockDistance, convertPos);
				world.playSound((EntityPlayer) null, pos, SoundRegistry.MIST_STAFF_CAST, SoundCategory.BLOCKS, 1F, 1.0F);
				player.getCooldownTracker().setCooldown(this, 200);
			}
			
			player.swingArm(hand);
		} else {
			return new ActionResult<>(EnumActionResult.FAIL, stack);
		}

		return new ActionResult<>(EnumActionResult.SUCCESS, stack);
	}

	private boolean isShadowableBlock (World world, EntityPlayer player, BlockPos pos, IBlockState state) {
		return (state.isNormalCube() || state.getBlock().isReplaceable(world, pos)) && !state.getBlock().hasTileEntity(state) && state.getPlayerRelativeBlockHardness(player, world, pos) > 0.0001 && !(state.getBlock() instanceof BlockMistBridge) && !(state.getBlock() instanceof BlockShadowWalker) && !world.isAirBlock(pos);
	}

	private void spawnEntity(World world, BlockPos pos, List<Integer> blockDistance, List<BlockPos> convertPos) {
		if (!world.isRemote) {// && world.getDifficulty() != EnumDifficulty.PEACEFUL) {
			EntityMistBridge mist_bridge = new EntityMistBridge(world);
			mist_bridge.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5);
			mist_bridge.setBlockList(blockDistance, convertPos, false);
			if (mist_bridge.getCanSpawnHere()) {
				mist_bridge.onInitialSpawn(world.getDifficultyForLocation(mist_bridge.getPosition()), null);
				world.spawnEntity(mist_bridge);
			}
		}
	}

	@Override
	public boolean shouldUseBigSwingAnimation(ItemStack stack) {
		return true;
	}

	@Override
	public float getSwingSpeedMultiplier(EntityLivingBase entity, ItemStack stack) {
		return 0.35f;
	}

}
