package electroblob.wizardry.spell;

import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;

public class PhaseStep extends Spell {

	public PhaseStep(){
		super(Tier.ADVANCED, 35, Element.SORCERY, "phase_step", SpellType.UTILITY, 40, EnumAction.NONE, false);
	}

	@Override
	public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){

		// Phase step does not gain range from range multiplier, instead it increases the thickness
		// of the wall you can teleport through.
		RayTraceResult rayTrace = WizardryUtilities.rayTrace(5, world, caster, false);

		if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){

			BlockPos pos = new BlockPos(rayTrace.getBlockPos().getX(), (int)caster.posY, rayTrace.getBlockPos().getZ());

			// The maximum wall thickness as determined by the range multiplier. The + 0.5f is so that
			// weird float processing doesn't incorrectly round it down.
			int maxThickness = 1 + (int)((modifiers.get(WizardryItems.range_upgrade) - 1) / Constants.RANGE_INCREASE_PER_LEVEL + 0.5f);

			if(rayTrace.sideHit.getAxis().isHorizontal()){

				// i represents how far the player needs to teleport to get through the wall
				for(int i = 0; i <= maxThickness; i++){

					BlockPos pos1 = pos.offset(rayTrace.sideHit.getOpposite(), i);

					// Prevents the player from teleporting through unbreakable blocks, so they cannot cheat in other
					// mods' mazes and dungeons.
					if((WizardryUtilities.isBlockUnbreakable(world, pos1) || WizardryUtilities.isBlockUnbreakable(world, pos1.up()))
							&& !Wizardry.settings.teleportThroughUnbreakableBlocks)
						return false;

					if(!world.getBlockState(pos1).getMaterial().blocksMovement()
							&& !world.getBlockState(pos1.up()).getMaterial().blocksMovement()){

						if(!world.isRemote){
							caster.setPositionAndUpdate(pos1.getX() + 0.5, caster.posY, pos1.getZ() + 0.5);
						}

						caster.swingArm(hand);
						WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f);
						return true;
					}
				}
			}
		}

		// This is here because the conditions are false on the client for whatever reason. (see the Javadoc for cast()
		// for an explanation)
		if(world.isRemote){
			for(int i = 0; i < 10; i++){
				double dx1 = caster.posX;
				double dy1 = WizardryUtilities.getPlayerEyesPos(caster) - 1.5 + 2 * world.rand.nextFloat();
				double dz1 = caster.posZ;
				world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5,
						world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
			}
		}

		return false;
	}

}
