package net.minecraft.command.commands;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import net.minecraft.command.CommandException;
import net.minecraft.command.CommandNotFoundException;
import net.minecraft.command.CommandUtilities;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.NumberInvalidException;
import net.minecraft.command.SyntaxErrorException;
import net.minecraft.command.arg.CommandArg;
import net.minecraft.command.collections.TypeIDs;
import net.minecraft.command.construction.CommandConstructable;
import net.minecraft.command.construction.CommandDescriptorDefault.CParserData;
import net.minecraft.command.descriptors.CommandDescriptor;
import net.minecraft.command.descriptors.ICommandDescriptor;
import net.minecraft.command.descriptors.ICommandDescriptor.UsageProvider;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.event.ClickEvent;
import net.minecraft.event.ClickEvent.Action;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
public class CommandHelp extends CommandArg<Integer>
{
public static final CommandConstructable constructable = new CommandConstructable()
{
@Override
public CommandArg<Integer> construct(final CParserData data) throws SyntaxErrorException
{
return new CommandHelp(data.get(TypeIDs.StringList));
}
};
private final CommandArg<List<String>> path;
public CommandHelp(final CommandArg<List<String>> path)
{
this.path = path;
}
@Override
public Integer eval(final ICommandSender sender) throws CommandException
{
if (this.path == null)
{
printPage(sender, 1);
return 1;
}
final List<String> path = this.path.eval(sender);
if (path.size() == 1)
try
{
printPage(sender, Integer.parseInt(path.get(0)));
return 1;
} catch (final NumberFormatException ex)
{
}
final UsageProvider usage = getUsageFromPath(path);
if (usage == null)
throw new CommandNotFoundException();
sender.addChatMessage(usage.createMessage(path.subList(1, path.size())));
return 1;
}
private static UsageProvider getUsageFromPath(final List<String> path)
{
final ListIterator<String> it = path.listIterator();
ICommandDescriptor<?> currDesc = CommandDescriptor.getDescriptor(it.next());
if (currDesc == null)
return null;
UsageProvider ret = currDesc.usage;
while (it.hasNext())
{
final String next = it.next();
ICommandDescriptor<?> newDesc = currDesc.getSubDescriptor(next);
if (newDesc == null)
{
it.previous();
newDesc = currDesc.getSubDescriptor("");
if (newDesc == null)
return null;
}
if (newDesc.usage != null)
ret = newDesc.usage;
currDesc = newDesc;
}
return ret;
}
private static void printPage(final ICommandSender sender, final int pageNum) throws NumberInvalidException
{
final List<Entry<String, CommandDescriptor<?>>> commands = CommandDescriptor.getCommands();
final int pageCount = (commands.size() - 1) / 7 + 1;
CommandUtilities.checkInt(pageNum, 1, pageCount);
CommandUtilities.message(sender, EnumChatFormatting.DARK_GREEN, "commands.help.header", pageNum, pageCount);
final int end = Math.min(pageNum * 7, commands.size());
for (final Entry<String, CommandDescriptor<?>> command : commands.subList((pageNum - 1) * 7, end))
{
final IChatComponent message = command.getValue().usage.createMessage(Collections.<String> emptyList());
message.getChatStyle().setChatClickEvent(new ClickEvent(Action.SUGGEST_COMMAND, "/" + command.getKey() + " "));
sender.addChatMessage(message);
}
if (pageNum == 1 && sender instanceof EntityPlayer)
CommandUtilities.message(sender, EnumChatFormatting.GREEN, "commands.help.footer");
}
}