package com.massivecraft.factions.listeners;

import org.bukkit.block.Block;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; 
import org.bukkit.Location;
import org.bukkit.Material;

import com.massivecraft.factions.ConfServer;


public class FactionsExploitListener implements Listener
{
	@EventHandler(priority = EventPriority.NORMAL)
	public void obsidianGenerator(BlockFromToEvent event)
	{
		if (event.isCancelled() == true || ! ConfServer.handleExploitObsidianGenerators) return;

		// thanks to ObGenBlocker and WorldGuard for this method
		Block block = event.getToBlock();
		int source = event.getBlock().getTypeId();
		int target = block.getTypeId();
		if ((target == 55 || target == 132) && (source == 0 || source == 10 || source == 11))
			block.setTypeId(0);
	}


	@EventHandler(priority = EventPriority.NORMAL)
	public void enderPearlTeleport(PlayerTeleportEvent event)
	{
		if (event.isCancelled() == true || ! ConfServer.handleExploitEnderPearlClipping) return;
		if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) return;

		// this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar...
		Location target = event.getTo();
		Location from = event.getFrom();

		// blocks who occupy less than 1 block width or length wise need to be handled differently
		Material mat = event.getTo().getBlock().getType();
		if (
				((mat == Material.THIN_GLASS || mat == Material.IRON_FENCE) && clippingThrough(target, from, 0.65))
			 || ((mat == Material.FENCE || mat == Material.NETHER_FENCE) && clippingThrough(target, from, 0.45))
			)
		{            
			event.setTo(from);
			return;
		}

		// simple fix otherwise: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges
		target.setX(target.getBlockX() + 0.5);
		target.setZ(target.getBlockZ() + 0.5);
		event.setTo(target);
		
	}

	public static boolean clippingThrough(Location target, Location from, double thickness)
	{
		return
		(
			(from.getX() > target.getX() && (from.getX() - target.getX() < thickness))
		 || (target.getX() > from.getX() && (target.getX() - from.getX() < thickness))
		 || (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness))
		 || (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))
		);
	}
}
