package net.mc_pandacraft.java.plugin.pandacraftutils.modules.player_control;


import java.util.Collection;

import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils;
import net.mc_pandacraft.java.plugin.pandacraftutils.config.ConfigManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayer;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayerManager;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerEggThrowEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.scheduler.BukkitRunnable;

public class AfkManager extends BukkitRunnable implements Listener  {
	private PandacraftUtils plugin = PandacraftUtils.getInstance();

	
	
	public AfkManager()
	{
		
        plugin.getServer().getScheduler().runTaskTimer(plugin, this, 5*20L, 20L);
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
        
		
	}
	
	
	
	

	
	// ----------------------------------------
	// ----------- Analyse Auto-AFK -----------
	// ----------------------------------------

	@Override
	public void run() {
		// methode exécutée toute les secondes
		int timeoutAutoAfkMessage = ConfigManager.getInstance().defaultConfig.afk_timeoutAutoMessage;
		int timeoutAutoAfkKick = ConfigManager.getInstance().defaultConfig.afk_timeoutAutoKick;
		Collection<OnlinePlayer> oPlayers = OnlinePlayerManager.getAll();
		for (OnlinePlayer ap : oPlayers.toArray(new OnlinePlayer[oPlayers.size()]))
		{	// parcours de tout les joueurs
			if (ap == null)
				continue;
			
			
			if (ap.getPlayer().hasPermission("pandacraft.afk.exempt.autoafk"))
				continue;	// les joueurs exemptés de l'auto-afk sont ignorés
			
			Player p = ap.getPlayer();
			
			double timeElapsed = ap.getDurationSinceLastAction();
			
			if (!ap.isAfk() && timeElapsed > timeoutAutoAfkMessage)
				ap.setAfk(true);	// on indique le changement d'état AFK de la personne
			else if (ap.isAfk() && timeElapsed > timeoutAutoAfkKick && !p.hasPermission("pandacraft.afk.exempt.kick"))
				p.kickPlayer("Vous avez été inactif pendant plus de "+Math.floor(timeoutAutoAfkKick/60)+" minutes");
							// on kick le joueur restant trop longtemps, si il n'est pas exempt� du kick
			
			
		}
	}
	
	
	
	
	
	

	
	// ----------------------------------------
	// -------------- Evènements --------------
	// ----------------------------------------
	
	@EventHandler
	public void onPlayerMove (PlayerMoveEvent event)
	{
		Location from = event.getFrom();
		Location to = event.getTo();
		
		if (	(from.getPitch() == to.getPitch() && from.getYaw() == to.getYaw())
			|| 	(from.getX() == to.getX() && from.getY() == to.getY() && from.getZ() == to.getZ()))
			return;
		OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
	}
	
	
	@EventHandler
	public void onPlayerCommandPreprocess (PlayerCommandPreprocessEvent event)
	{
		if (event.getPlayer().hasPermission("pandacraft.afk.exempt.commandcheck"))
			return;

		String[] split = event.getMessage().split(" ");
		if (split.length > 0 &&
					(
					   split[0].equalsIgnoreCase("/afk")
					|| split[0].equalsIgnoreCase("/away")
					|| split[0].equalsIgnoreCase("/mail")
					|| split[0].equalsIgnoreCase("/email")
					|| split[0].equalsIgnoreCase("/m")
					|| split[0].equalsIgnoreCase("/msg")
					|| split[0].equalsIgnoreCase("/t")
					|| split[0].equalsIgnoreCase("/tell")
					|| split[0].equalsIgnoreCase("/w")
					|| split[0].equalsIgnoreCase("/whisper")
					|| split[0].equalsIgnoreCase("/r")
					|| split[0].equalsIgnoreCase("/reply")
					)
			)
				return;
		
		
		OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
	}
	
	@EventHandler
	public void onPlayerInteract (PlayerInteractEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}
	
	@EventHandler
	public void onPlayerInteractEntity (PlayerInteractEntityEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}
	
	@EventHandler
	public void onPlayerTeleport (PlayerTeleportEvent event)
	{
		try
		{
			// on sors de l'AFK que si la téléportation ne se fait qu'à partir de 2 blocs d'espace
			// pour éviter qu'on sorte de l'AFK en se faisait pousser par des pistons
			// car un piston "téléporte" le joueur (techniquement parlant, dans le jeu) à 1 bloc de distance
			if (event.getFrom().getWorld() != event.getTo().getWorld()
					|| event.getFrom().distanceSquared(event.getTo()) > 2*2)
				OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}

	@EventHandler
	public void onPlayerToggleSprint (PlayerToggleSprintEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}
	@EventHandler
	public void onPlayerToggleFlight (PlayerToggleFlightEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}
	@EventHandler
	public void onPlayerToggleSneak (PlayerToggleSneakEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}

	@EventHandler
	public void onAsyncPlayerChat (AsyncPlayerChatEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}

	@EventHandler
	public void onPlayerDropItem (PlayerDropItemEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}

	@EventHandler
	public void onPlayerEggThrow (PlayerEggThrowEvent event)
	{
		try
		{
			OnlinePlayerManager.get(event.getPlayer()).isDoingAction();
		}
		catch (NullPointerException e) { }
	}
	
}

