package org.ultramine.mods.hawkeye.commands;

import java.util.ArrayList;
import java.util.List;

import org.ultramine.mods.hawkeye.HawkEye;
import org.ultramine.mods.hawkeye.PlayerSession;
import org.ultramine.mods.hawkeye.SessionManager;
import org.ultramine.mods.hawkeye.util.HawkUtil;

import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;

/**
 * Abstract class representing a command. When run by the command manager (
 * {@link HawkEye}), it pre-processes all the data into more useful forms.
 * Extending classes should adjust required fields in their constructor
 * 
 * @author Oli
 *
 */
public abstract class BaseCommand
{
	public ICommandSender sender;
	public List<String> args = new ArrayList<String>();
	public String name;
	public int argLength = 0;
	public String usage;
	public boolean bePlayer = true;
	public EntityPlayerMP player;
	public String usedCommand;
	public PlayerSession session;
	public HawkEye plugin;

	/**
	 * Method called by the command manager in {@link HawkEye} to run the
	 * command. Arguments are processed into a list for easier manipulating.
	 * Argument lengths, permissions and sender types are all handled.
	 * 
	 * @param csender
	 *            {@link ICommandSender} to send data to
	 * @param preArgs
	 *            arguments to be processed
	 * @param cmd
	 *            command being executed
	 * @return true on success, false if there is an error in the checks or if
	 *         the extending command returns false
	 */
	public boolean run(HawkEye instace, ICommandSender csender, String[] preArgs, String cmd)
	{
		plugin = instace;
		sender = csender;
		session = SessionManager.getSession(sender);
		usedCommand = cmd;

		//Sort out arguments
		args.clear();
		for(String arg : preArgs)
			args.add(arg);

		//Remove commands from arguments
		for(int i = 0; i < name.split(" ").length && i < args.size(); i++)
			args.remove(0);

		//Check arg lengths
		if(argLength > args.size())
		{
			sendUsage();
			return true;
		}

		//Check if sender should be a player
		if(bePlayer && !(sender instanceof EntityPlayerMP))
			return false;
		if(sender instanceof EntityPlayerMP)
			player = (EntityPlayerMP)sender;
		if(!permission())
		{
			HawkUtil.sendMessage(sender, "&cYou do not have permission to do that!");
			return false;
		}

		return execute();
	}

	/**
	 * Runs the extending command. Should only be run by the BaseCommand after
	 * all pre-processing is done
	 * 
	 * @return true on success, false otherwise
	 */
	public abstract boolean execute();

	/**
	 * Performs the extending command's permission check.
	 * 
	 * @return true if the user has permission, false if not
	 */
	public abstract boolean permission();

	/**
	 * Sends advanced help to the sender
	 */
	public abstract void moreHelp();

	/**
	 * Displays the help information for this command
	 */
	public void sendUsage()
	{
		HawkUtil.sendMessage(sender, "&c/" + usedCommand + " " + name + " " + usage);
	}
}
