package nivia.modules.exploits;

import net.minecraft.block.Block;
import net.minecraft.block.BlockSign;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.network.play.client.C03PacketPlayer;
import net.minecraft.network.play.client.C0BPacketEntityAction;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import nivia.events.EventTarget;
import nivia.events.events.Event3D;
import nivia.events.events.EventPreMotionUpdates;
import nivia.modules.Module;
import nivia.utils.Helper;

public class Teleport extends Module {

	private boolean canTP;
	private int delay;
	private BlockPos endPos;

	private boolean jump;
	private boolean speedTick;
	private float forward = 0.375F;
	/*
     * Author Trevor
     */
	public Teleport() {
		super("Teleport", Keyboard.KEY_X, 0x999999, Category.EXPLOITS, "Teleport to where you are looking with right click.", new String[]{"teleport", "tele","tp", "telep", "forward", "fwd"}, true);
	}

	@EventTarget
	public void onPreUpdate(EventPreMotionUpdates event){
		this.endPos = mc.objectMouseOver.func_178782_a();
		forward = 0;
		double distance = mc.thePlayer.getDistance(endPos.getX(), endPos.getY(), endPos.getZ());

		if(this.canTP && Mouse.isButtonDown(1) && !mc.thePlayer.isSneaking() && this.delay == 0 && mc.inGameHasFocus) {
			if (mc.thePlayer.getFoodStats().getFoodLevel() > 6)
				Helper.sendPacket(new C0BPacketEntityAction(mc.thePlayer, C0BPacketEntityAction.Action.START_SPRINTING));
			float direction = mc.thePlayer.rotationYaw + (mc.thePlayer.moveForward < 0.0F ? 180 : 0) + (mc.thePlayer.moveStrafing > 0.0F ? -90.0F * (mc.thePlayer.moveForward > 0.0F ? 0.5F : mc.thePlayer.moveForward < 0.0F ? -0.5F : 1.0F) : 0.0F) - (mc.thePlayer.moveStrafing < 0.0F ? -90.0F * (mc.thePlayer.moveForward > 0.0F ? 0.5F : mc.thePlayer.moveForward < 0.0F ? -0.5F : 1.0F) : 0.0F);
			float xDir = (float)Math.cos((direction + 90.0F) * 3.141592653589793D / 180.0D);
			float zDir = (float)Math.sin((direction + 90.0F) * 3.141592653589793D / 180.0D);

			//  Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(mc.thePlayer.posX + xDir * 0.2D, mc.thePlayer.posY, mc.thePlayer.posZ + zDir * 0.2D, mc.thePlayer.onGround));
			for (int i = 0; i < distance + 5; i++) {
				this.speedTick = (!this.speedTick);
				if (this.speedTick)
					this.forward = ((float)(this.forward + 0.49D));
				else this.forward += 1.05F;

				if (this.speedTick)
					Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(mc.thePlayer.posX + xDir * this.forward, mc.thePlayer.posY, mc.thePlayer.posZ + zDir * this.forward, mc.thePlayer.onGround));
				else  Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(mc.thePlayer.posX + xDir * this.forward, mc.thePlayer.posY + 0.42D, mc.thePlayer.posZ + zDir * this.forward, mc.thePlayer.onGround));

				float check = speedTick ? (this.forward + 0.50f) : this.forward;
				if(check >= distance) break;
			}
			speedTick = false;
			delay = 5;
			Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(endPos.getX(),endPos.getY(),endPos.getZ(), false));
			Helper.sendPacket(new C0BPacketEntityAction(mc.thePlayer, C0BPacketEntityAction.Action.STOP_SPRINTING));


			//Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(mc.thePlayer.posX + xDir * 0.5D, mc.thePlayer.posY, mc.thePlayer.posZ + zDir * 0.5D, mc.thePlayer.onGround));
		}

		if (this.delay > 0)
			this.delay -= 1;
	}
	public static void doFWD(double distance) {
		boolean speedTick = false;
		float forward = 0;
		double multiplier = distance;
		double mx = Math.cos(Math.toRadians(Helper.mc().thePlayer.rotationYaw + 90.0F));
		double mz = Math.sin(Math.toRadians(Helper.mc().thePlayer.rotationYaw + 90.0F));
		double x = (Helper.mc().thePlayer.movementInput.moveForward * multiplier * mx + Helper.mc().thePlayer.movementInput.moveStrafe * multiplier * mz);
		double z = (Helper.mc().thePlayer.movementInput.moveForward * multiplier * mz - Helper.mc().thePlayer.movementInput.moveStrafe * multiplier * mx);
		BlockPos endPos = new BlockPos(Helper.player().posX + x, Helper.player().posY, Helper.player().posZ + z);
		if (Helper.player().getFoodStats().getFoodLevel() > 6)
			Helper.sendPacket(new C0BPacketEntityAction(Helper.player(), C0BPacketEntityAction.Action.START_SPRINTING));
		float direction = Helper.player().rotationYaw + (Helper.mc().thePlayer.moveForward < 0.0F ? 180 : 0) + (Helper.mc().thePlayer.moveStrafing > 0.0F ? -90.0F * (Helper.mc().thePlayer.moveForward > 0.0F ? 0.5F : Helper.mc().thePlayer.moveForward < 0.0F ? -0.5F : 1.0F) : 0.0F) - (Helper.mc().thePlayer.moveStrafing < 0.0F ? -90.0F * (Helper.mc().thePlayer.moveForward > 0.0F ? 0.5F : Helper.mc().thePlayer.moveForward < 0.0F ? -0.5F : 1.0F) : 0.0F);
		float xDir = (float)Math.cos((direction + 90.0F) * 3.141592653589793D / 180.0D);
		float zDir = (float)Math.sin((direction + 90.0F) * 3.141592653589793D / 180.0D);

		//  Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(Helper.mc().thePlayer.posX + xDir * 0.2D, Helper.mc().thePlayer.posY, Helper.mc().thePlayer.posZ + zDir * 0.2D, Helper.mc().thePlayer.onGround));

		boolean n = distance < 0;

		for (int i = 0; i < distance + 5; i++) {
			speedTick = (!speedTick);
			if (speedTick)
				forward = ((float)(forward + 0.50D));
			else forward += 1.06F;

			if (speedTick)
				Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(Helper.mc().thePlayer.posX + xDir * forward, Helper.mc().thePlayer.posY, Helper.mc().thePlayer.posZ + zDir * forward, Helper.mc().thePlayer.onGround));
			else  Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(Helper.mc().thePlayer.posX + xDir * forward, Helper.mc().thePlayer.posY + 0.41999998688698D, Helper.mc().thePlayer.posZ + zDir * forward, Helper.mc().thePlayer.onGround));

			float check = speedTick ? (forward + 0.50f) : forward;
			if(check >= distance) break;
		}
		Helper.sendPacket(new C03PacketPlayer.C04PacketPlayerPosition(endPos.getX(),endPos.getY() - 0.5,endPos.getZ(), false));
		Helper.sendPacket(new C0BPacketEntityAction(Helper.mc().thePlayer, C0BPacketEntityAction.Action.STOP_SPRINTING));
	}
	@EventTarget()
	public void onRender(Event3D event){
		int x = mc.objectMouseOver.func_178782_a().getX();
		int y = mc.objectMouseOver.func_178782_a().getY();
		int z = mc.objectMouseOver.func_178782_a().getZ();
		Block block1 = Helper.blockUtils().getBlock(x, y, z);
		Block block2 = Helper.blockUtils().getBlock(x, y + 1, z);
		Block block3 = Helper.blockUtils().getBlock(x, y + 2, z);
		boolean blockBelow = (block1 instanceof BlockSign) ? false : block1.getMaterial().isSolid();
		boolean blockLevel = (block2 instanceof BlockSign) ? false : block1.getMaterial().isSolid();
		boolean blockAbove = (block3 instanceof BlockSign) ? false : block1.getMaterial().isSolid();
		if (Helper.blockUtils().getBlock(mc.objectMouseOver.func_178782_a()).getMaterial() != Material.air && blockBelow && blockLevel && blockAbove){
			this.canTP = true;
			GL11.glPushMatrix();
			Helper.get3DUtils().startDrawing();
			Helper.mc().entityRenderer.setupCameraTransform(Helper.mc().timer.renderPartialTicks, 2);
			GL11.glColor4d(0,0.9,1, 0.3);
			Helper.get3DUtils().drawBoundingBox(new AxisAlignedBB(x - RenderManager.renderPosX, y + 1 - RenderManager.renderPosY, z - RenderManager.renderPosZ, x - RenderManager.renderPosX + 1.0D, y + 1.01D - RenderManager.renderPosY, z - RenderManager.renderPosZ + 1.0D));
			GL11.glColor4f(0.0F, 0.0F, 0.0F, 1.0F);
			Helper.get3DUtils().drawOutlinedBox(new AxisAlignedBB(x - RenderManager.renderPosX, y + 1 - RenderManager.renderPosY, z - RenderManager.renderPosZ, x - RenderManager.renderPosX + 1.0D, y + 1.01D - RenderManager.renderPosY, z - RenderManager.renderPosZ + 1.0D));
			Helper.get3DUtils().stopDrawing();
			GL11.glPopMatrix();
		}
		else
			this.canTP = false;

	}
}