package net.mc_pandacraft.java.plugin.pandacraftutils;

import java.sql.SQLException;

import net.mc_pandacraft.java.plugin.pandacraftutils.commands.PandacraftUtilsCommandsManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.config.ConfigManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.AutoMessagesManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.CalculatorManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.CommandAliasManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.LoginLogoutMessageManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.PacketOutServerInfoListener;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.SpawnTimeManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.TPSAnalysisManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.WESelectionDisplayManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.fun.HeartThrowManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.player_control.AfkManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.player_control.ChatAnalysisManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.protection.CreativCheatManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.protection.EntitySpamManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.protection.NoPvpProtectManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.protection.SurvivalCuboManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.protection.TamedEntityProtectManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.protection.WorldBorderManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.modules.staff.StaffQueueManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.network_api.NetworkAPI;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayer;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayerManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.players.PlayerDataCleaner;
import net.mc_pandacraft.java.util.mysql.DBConnection;

import org.bukkit.plugin.java.JavaPlugin;

public class PandacraftUtils extends JavaPlugin {
	
	private static PandacraftUtils instance;
	public static PandacraftUtils getInstance() {
		if (instance == null) (new Exception("Plugin PandacraftUtils non chargé")).printStackTrace();
		return instance;
	
	}
	
	
	
	
	
	private static ServerState serverState = ServerState.STOPPED;
	
	public static ServerState getServerState() { return serverState; }
	public static void setServerState(ServerState s) { serverState = s; }
	
	public enum ServerState{
		STOPPED,
		LOADING,
		RUNNING,
		STOPPING
	}
	
	
	
	
	public DBConnection databaseConnection;
	
	public PacketOutServerInfoListener serverPingListener;
	public AfkManager afkManager;
	public WESelectionDisplayManager wESelectionDisplayManager;
	public CommandAliasManager commandAliasManager;
	public SpawnTimeManager spawnTimeManager;
	public ChatAnalysisManager chatAnalysisManager;
	public CreativCheatManager creativCheatManager;
	public NoPvpProtectManager noPvpProtectManager;
	public LoginLogoutMessageManager loginLogoutMessageManager;
	public CalculatorManager calculatorManager;
	public SurvivalCuboManager survivalCuboManager;
	public StaffQueueManager staffQueueManager;
	public TPSAnalysisManager tpsAnalysisManager;
	public AutoMessagesManager autoMessagesManager;
	public EntitySpamManager entitySpamManager;
	public TamedEntityProtectManager tamedEntityProtectManager;
	public WorldBorderManager worldBorderManager;
	public HeartThrowManager heartThrowManager;
	
	
	

	
	@Override
    public void onEnable(){
		
		setServerState(ServerState.LOADING);
		
		instance = this;
		
		
		try {
			databaseConnection = new DBConnection(ConfigManager.getInstance().defaultConfig.database_host,
											ConfigManager.getInstance().defaultConfig.database_port,
											ConfigManager.getInstance().defaultConfig.database_base,
											ConfigManager.getInstance().defaultConfig.database_user,
											ConfigManager.getInstance().defaultConfig.database_pass);
		} catch (ClassNotFoundException | SQLException e) {
			getLogger().severe("Impossible de se connecter à la base de donnée !");
			e.printStackTrace();
		}
		
		
		ConfigManager.loadNewInstance();
		OnlinePlayerManager.loadNewInstance();
		PandacraftUtilsCommandsManager.loadNewInstance();
		
		
		serverPingListener = new PacketOutServerInfoListener();
		afkManager = new AfkManager();
		wESelectionDisplayManager = new WESelectionDisplayManager();
		commandAliasManager = new CommandAliasManager();
		spawnTimeManager = new SpawnTimeManager();
		chatAnalysisManager = new ChatAnalysisManager();
		creativCheatManager = new CreativCheatManager();
		noPvpProtectManager = new NoPvpProtectManager();
		loginLogoutMessageManager = new LoginLogoutMessageManager();
		calculatorManager = new CalculatorManager();
		survivalCuboManager = new SurvivalCuboManager();
		staffQueueManager = new StaffQueueManager();
		tpsAnalysisManager = new TPSAnalysisManager();
		autoMessagesManager = new AutoMessagesManager();
		entitySpamManager = new EntitySpamManager();
		tamedEntityProtectManager = new TamedEntityProtectManager();
		worldBorderManager = new WorldBorderManager();
		heartThrowManager = new HeartThrowManager();
		
		
		NetworkAPI.loadNewInstance();
		
		getServer().getScheduler().runTaskLater(this, new Runnable() {
			@Override public void run() {
				new PlayerDataCleaner(instance);
			}
		}, 1);
		
		getServer().getScheduler().runTaskLater(this, new Runnable() {
			@Override public void run() {
				setServerState(ServerState.RUNNING);
			}
		}, 30);
		
		
    }
	
	
	@Override
	public void onDisable(){
		
		setServerState(ServerState.STOPPING);
		
		ConfigManager.getInstance().saveAll();
        
        afkManager = null;
        wESelectionDisplayManager = null;
        commandAliasManager = null;
        spawnTimeManager = null;
        chatAnalysisManager = null;
        creativCheatManager = null;
        noPvpProtectManager = null;
        calculatorManager = null;
        survivalCuboManager = null;
        serverPingListener = null;
        staffQueueManager = null;
        tpsAnalysisManager = null;
        autoMessagesManager = null;
        entitySpamManager = null;
        tamedEntityProtectManager = null;
        worldBorderManager = null;
        heartThrowManager = null;
        
        instance = null;
        
        
        //try { databaseConnection.getConnection().close(); } catch (SQLException e) { }
    }
	

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * Envoi d'un message groupé à plusieurs ou à tout les joueurs et peut-être à la console
	 * @param message message à envoyer
	 * @param prefix <i>true</i> si le message doit être précédé de "[Pandacraft] "
	 * @param console défini si le message doit être affiché sur la console
	 * @param permission défini la permission que doit avoir le joueur pour voir le message, ou <i>null</i> si le message est adressé à tous les joueurs
	 * @throws IllegalArgumentException si message est <i>null</i>
	 */
	public void broadcast(String message, boolean prefix, boolean console, String permission) {
		if (message == null)
			throw new IllegalArgumentException("Un message doit être défini");
		
		if (prefix)
			message = ConfigManager.getInstance().defaultConfig.serverMessages_prefix + message;
		
		
		for (OnlinePlayer op : OnlinePlayerManager.getAll())
		{
			if (permission != null && !op.hasPermission(permission)) continue;
			op.getPlayer().sendMessage(message);
		}
		
		if (console)
			getServer().getConsoleSender().sendMessage(message);
		
	}
	

	/**
	 * Envoi d'un message groupé à tout les joueurs et peut-être à la console
	 * @param message message à envoyer
	 * @param prefix <i>true</i> si le message doit être précédé de "[Pandacraft] "
	 * @param console défini si le message doit être affiché sur la console
	 * @throws IllegalArgumentException si message est <i>null</i>
	 */
	public void broadcast(String message, boolean prefix, boolean console) {
		broadcast(message, prefix, console, null);
	}


	/**
	 * Envoi d'un message groupé à plusieurs ou à tout les joueurs, et à la console si le paramètre <b>permission</b> est <i>null</i>
	 * @param message message à envoyer
	 * @param prefix <i>true</i> si le message doit être précédé de "[Pandacraft] "
	 * @param permission défini la permission que doit avoir le joueur pour voir le message, ou <i>null</i> si le message est adressé à tous les joueurs et à la console
	 * @throws IllegalArgumentException si message est <i>null</i>
	 */
	public void broadcast(String message, boolean prefix, String permission) {
		broadcast(message, prefix, (permission == null), permission);
	}

	/**
	 * Envoi d'un message groupé à tout les joueurs et à la console
	 * @param message message à envoyer
	 * @param prefix <i>true</i> si le message doit être précédé de "[Pandacraft] "
	 */
	public void broadcast(String message, boolean prefix) {
		broadcast(message, prefix, true, null);
	}
	
	

}