package me.taylory5.hackdetective.events;

import me.taylory5.hackdetective.Main;
import me.taylory5.hackdetective.objects.HDPlayer;
import me.taylory5.hackdetective.objects.PlayerLocationChangeEvent;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.util.NumberConversions;

public class PlayerMove implements Listener{

	@EventHandler(ignoreCancelled = true)
	public void onPlayerMove(PlayerMoveEvent event){
		int x = Math.abs(fixLocation(event.getFrom().getBlock().getLocation()).getBlockX() - fixLocation(event.getTo().getBlock().getLocation()).getBlockX());
		int y = Math.abs(fixLocation(event.getFrom().getBlock().getLocation()).getBlockY() - fixLocation(event.getTo().getBlock().getLocation()).getBlockY());
		int z = Math.abs(fixLocation(event.getFrom().getBlock().getLocation()).getBlockZ() - fixLocation(event.getTo().getBlock().getLocation()).getBlockZ());

		HDPlayer player = Main.getPlayer(event.getPlayer());
		if(event.getTo().getBlockY() > event.getFrom().getBlockY()){
			if(!player.isAscending()){
				player.setAscending(true);
				player.setDescending(false);
			}
		}else if(event.getTo().getBlockY() < event.getFrom().getBlockY()){
			if(!player.isDescending()){
				player.setDescending(true);
				player.setAscending(false);
			}
		}else{
			player.setAscending(false);
			player.setDescending(false);
		}

		if(x + y + z > 0){
			PlayerLocationChangeEvent plce = new PlayerLocationChangeEvent(event.getPlayer(), fixLocation(event.getTo()), fixLocation(event.getFrom()));
			Bukkit.getServer().getPluginManager().callEvent(plce);		
		}

	}

	@EventHandler
	public void onPlayerMoveLocs(PlayerLocationChangeEvent event){
		HDPlayer player = Main.getPlayer(event.getPlayer());

		//player.setLastLocation(event.getTo());
		//The player will be still moving if true, so we want to add to their last y
		if(event.getTo().getBlock().getRelative(0, -1, 0).getType() == Material.AIR || event.getTo().getBlock().getRelative(0, -1, 0).isLiquid()){
			final Location f = event.getFrom();
			final Location t = event.getTo();

			double d = (t.getY() - f.getY());
			int distance = t.getBlockY() - f.getBlockY();

			if(d > 0)
				player.setLastY(distance + player.getLastY());
			else if(d < 0){
				if(player.getLastY() > 0)
					player.setLastY(0 + distance); 
				else
					player.setLastY(player.getLastY() + distance);
			}

		}else{
			if(player.getLastY() != 0)
				player.setLastLargeY(player.getLastY());
			player.setLastY(0);
		}

		//Reset the player's largest Y because they are on the same block Y-level as their last Y-level so they can't be changing the largest
		if(player.getPlayer().getLocation().getBlockY() == player.getLastLocation().getBlockY())
			player.setLastLargeY(0);

		double amount;
		Material mat;
		if(event.getTo().getBlock().getType().name().contains("WATER")){
			amount = 2;
			mat = event.getTo().getBlock().getType();
		}else if((event.getTo().getBlock().getType() == Material.AIR || !event.getTo().getBlock().getType().isSolid()) && event.getTo().getBlock().getType() != Material.WEB){
			switch(event.getTo().getBlock().getRelative(BlockFace.DOWN).getType()){
			case SOUL_SAND: 
				amount = 2; mat = Material.SOUL_SAND; break;
			case LADDER:
				amount = 2.5; mat = Material.LADDER; break;
			case AIR:
				amount = 0.5; mat = Material.AIR; break;
			case ICE:
				amount = 0.5; mat = Material.ICE; break;
			default:
				amount = 1; mat = event.getTo().getBlock().getRelative(BlockFace.DOWN).getType(); break;
			}
		}else{
			switch(event.getTo().getBlock().getType()){
			case STATIONARY_WATER:
				amount = 2; mat = Material.STATIONARY_WATER; break;
			case WEB:
				amount = 9; mat = Material.WEB; break;
			default:
				amount = 1; mat = event.getTo().getBlock().getType(); break;
			}
		}
		player.setBlocksMoved(player.getBlocksMoved() + amount);
	    
		//player.getPlayer().sendMessage("+ " + amount + " block(s) added for " + mat.name() + ", total = " + player.getBlocksMoved()); 
	}

	public Location fixLocation(Location loc){
		double newX = loc.getX();
		double rem = newX - Math.round(newX) + 0.01D;
		if(rem < 0.30D)
			newX = NumberConversions.floor(loc.getX()) - 1;

		return new Location(loc.getWorld(), newX, loc.getY(), loc.getZ());
	}

}
