/*
This file is part of leafdigital leafChat.
leafChat is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
leafChat is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with leafChat. If not, see <http://www.gnu.org/licenses/>.
Copyright 2012 Samuel Marshall.
*/
package com.leafdigital.irc.api;
import java.util.*;
import util.xml.XML;
import leafchat.core.api.Msg;
/**
* Message sent to get a list of available / commands.
*/
public class UserCommandListMsg extends Msg
{
/** IRC server (null if none) */
private Server server = null;
/** True if retrieving all commands. */
private boolean all = false;
/** List of all supported commands. */
private SortedSet<CommandDetails> list = new TreeSet<CommandDetails>();
/**
* Command is frequently typed by ordinary users.
*/
public final static int FREQ_COMMON = 100;
/**
* Command may be typed by ordinary users, but is used less frequently.
*/
public final static int FREQ_UNCOMMON = 200;
/**
* Command is used only by IRC operators, is normally handled internally
* by clients, or is normally used only when scripting.
*/
public final static int FREQ_OBSCURE = 300;
private static class CommandDetails implements Comparable<CommandDetails>
{
private String command;
private int frequency;
private String description;
private CommandDetails(String command, int frequency, String description)
{
this.command = command;
this.frequency = frequency;
this.description = description;
}
@Override
public int compareTo(CommandDetails other)
{
if(frequency < other.frequency)
{
return -1;
}
else if(frequency > other.frequency)
{
return 1;
}
return command.compareTo(other.command);
}
@Override
public boolean equals(Object o)
{
if (!(o instanceof CommandDetails))
{
return false;
}
CommandDetails other = (CommandDetails)o;
return other.frequency == frequency && other.command.equals(command);
}
@Override
public int hashCode()
{
return command.hashCode() ^ frequency;
}
}
/**
* Used to retrieve commands that are appropriate for current server.
* @param server Server for command (null if none)
*/
public UserCommandListMsg(Server server)
{
this.server = server;
}
/**
* Used to retrieve all commands, regardless of whether currently connected
* to a server or not.
*/
public UserCommandListMsg()
{
all = true;
}
/** @return Server that command should run on (null if none) */
public Server getServer()
{
return server;
}
/**
* For use by whoever despatched the message, after its despatch. Returns
* all the commands that were added (as strings without leading /,
* in common-first order).
* @return All the commands
*/
public String[] getCommands()
{
String[] commands = new String[list.size()];
int i = 0;
for(CommandDetails d : list)
{
commands[i++] = d.command;
}
return commands;
}
/**
* For user by whoever despatched the message, after its despatch. Returns
* the description of a given command, or null if it isn't known. The
* description is in XML format ready for output.
* @param command Command (must be lower-case with no slash)
* @return Description or null if none
*/
public String getDescription(String command)
{
for(CommandDetails d : list)
{
if(d.command.equals(command))
{
return d.description;
}
}
return null;
}
/**
* Adds a supported command to the list. The frequency value relates to the
* chance of an ordinary user typing this command.
* @param onServer True if command only applies when connected to a server
* @param command Command (not including /)
* @param freq Frequency (FREQ_xx constant)
* @param example Example command (plain text)
* @param explanation Explanation of what the example command does (XML)
*/
public void addCommand(boolean onServer, String command, int freq, String example,
String explanation)
{
// Don't add command if it requires a server connection and we don't have one.
if (onServer && !all && server == null)
{
return;
}
StringBuilder out = new StringBuilder("<command><example>");
example = XML.esc(example).replaceFirst("^(/[^ ]+)", "<name>$1</name>");
out.append(example);
out.append("</example><description>");
out.append(explanation);
out.append("</description></command>");
list.add(new CommandDetails(command, freq, out.toString()));
}
}