package chatty.gui.components.menus;
import chatty.Helper;
import chatty.util.commands.CustomCommand;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author tduva
*/
public class CommandMenuItems {
public enum MenuType {
USER, CHANNEL, STREAMS
}
private static final Map<MenuType, List<CommandMenuItem>> commands = new HashMap<>();
public static void setCommands(MenuType type, String data) {
List<CommandMenuItem> parsed = parse(data);
commands.put(type, parsed);
}
public static void addCommands(MenuType type, ContextMenu menu) {
List<CommandMenuItem> c = commands.get(type);
if (c != null) {
for (CommandMenuItem item : c) {
menu.addCommandItem(item);
}
}
}
public static List<CommandMenuItem> parse(String input) {
List<CommandMenuItem> result = new LinkedList<>();
if (input == null || input.isEmpty()) {
return result;
}
String[] lines = input.split("\n");
String submenuName = null;
for (String line : lines) {
CommandMenuItem submenu;
CommandMenuItem separator;
CommandMenuItem item;
if ((submenu = parseSubmenu(line)) != null) {
submenuName = submenu.getLabel();
result.add(submenu);
}
else if ((separator = parseSeparator(line, submenuName)) != null) {
result.add(separator);
}
else if ((item = parseCommand(line, submenuName)) != null) {
result.add(item);
}
else {
result.addAll(addCustomCommands(line, submenuName));
}
}
return result;
}
private static final String POS_KEY_PATTERN = "(?:\\{(\\d+)\\})?(?:\\[([^]]*)\\])?";
private static final Pattern SUBMENU_PATTERN = Pattern.compile("@([^\\[{]+)"+POS_KEY_PATTERN);
private static CommandMenuItem parseSubmenu(String line) {
line = line.trim();
Matcher m = SUBMENU_PATTERN.matcher(line);
if (m.matches()) {
String name = m.group(1).trim();
int pos = m.group(2) == null ? -1 : Integer.parseInt(m.group(2));
String key = m.group(3);
return new CommandMenuItem(name, null, null, pos, key);
}
return null;
}
private static final Pattern SEPARTOR_PATTERN = Pattern.compile("(\\.)?-"+POS_KEY_PATTERN);
private static CommandMenuItem parseSeparator(String line, String currentSubmenu) {
line = line.trim();
Matcher m = SEPARTOR_PATTERN.matcher(line);
if (m.matches()) {
String submenu = m.group(1) != null ? currentSubmenu : null;
int pos = m.group(2) == null ? -1 : Integer.parseInt(m.group(2));
return new CommandMenuItem(null, null, submenu, pos, null);
}
return null;
}
public static void main(String[] args) {
List<CommandMenuItem> items = parse("/slap\n"
+ "[Joshimuz]\n"
+ " FAQ=FAQ: http://blahblah\n"
+ "Message=/openUrl http://twitch.tv/inbox/compose?target=$$1");
for (CommandMenuItem item : items) {
System.out.println(item);
}
System.out.println(true || false && false);
}
private static final Pattern PATTERN = Pattern.compile("([^\\[{=]+)"+POS_KEY_PATTERN+"=(.+)");
private static CommandMenuItem parseCommand(String line, String currentSubmenu) {
Matcher m = PATTERN.matcher(line);
if (!m.matches()) {
return null;
}
String label = m.group(1).trim();
int pos = m.group(2) == null ? -1 : Integer.parseInt(m.group(2));
String key = m.group(3);
String command = m.group(4).trim();
//System.out.println("'"+label+"' '"+key+"' '"+command+"'");
if (!label.startsWith(".")) {
currentSubmenu = null;
} else {
label = label.substring(1).trim();
}
return makeItem(label, command, currentSubmenu, pos, key);
}
public static final String CUSTOM_COMMANDS_SUBMENU = "More..";
private static final Pattern PATTERN_COMPACT = Pattern.compile(
"(\\|)|(?:(?:([0-9]+)([smhd]?)|/?/?([^\\[{,\\s]+))(?:\\{(\\d+)\\})?(?:\\[([^,\\s]+)\\])?)");
public static List<CommandMenuItem> addCustomCommands(String line, String parent) {
List<CommandMenuItem> result = new LinkedList<>();
if (!line.startsWith(".")) {
parent = null;
} else {
line = line.substring(1);
}
Matcher matcher = PATTERN_COMPACT.matcher(line);
boolean sep = false;
while (matcher.find()) {
String match = matcher.group();
if (match.equals("|")) {
sep = true;
} else {
String submenu = parent;
CommandMenuItem item;
int pos = matcher.group(5) == null ? - 1 : Integer.parseInt(matcher.group(5));
String key = matcher.group(6);
if (match.startsWith("//")) {
submenu = CUSTOM_COMMANDS_SUBMENU;
}
if (matcher.group(2) != null) {
String number = matcher.group(2);
String factor = matcher.group(3);
item = createTimeoutItem(number, factor, submenu, pos, key);
} else {
String command = matcher.group(4);
item = createItem(command, submenu, pos, key);
}
if (sep) {
result.add(makeItem(null, null, submenu, -1, null));
}
result.add(item);
}
}
return result;
}
private static CommandMenuItem createItem(String command, String subMenu, int pos, String key) {
String label = Helper.replaceUnderscoreWithSpace(command);
return makeItem(label, "/"+command+" $1-", subMenu, pos, key);
}
private static CommandMenuItem createTimeoutItem(String number, String factor, String subMenu, int pos, String key) {
int time = Integer.parseInt(number);
String label;
if (!factor.isEmpty()) {
time *= getFactor(factor);
label = number + factor;
} else {
label = timeFormat(time);
}
String command = "/timeout $1 "+time+" $2-";
return makeItem(label, command, subMenu, pos, key);
}
private static int getFactor(String factorString) {
switch (factorString) {
case "s": return 1;
case "m": return 60;
case "h": return 60*60;
case "d": return 60*60*24;
default: return 1;
}
}
private static String timeFormat(int seconds) {
if (seconds < 60) {
return seconds+"s";
}
if (seconds < 60*60) {
int minutes = seconds / 60;
return String.format("%dm", (int) minutes);
}
if (seconds < 60*60*24*2+1) {
return String.format("%dh", seconds / (60*60));
}
return String.format("%dd", seconds / (60*60*24));
}
private static CommandMenuItem makeItem(String label, String command, String submenu, int pos, String key) {
if (command == null) {
// For separators
return new CommandMenuItem(null, null, submenu, pos, key);
}
CustomCommand parsedCommand = CustomCommand.parse(command.trim());
return new CommandMenuItem(label, parsedCommand, submenu, pos, key);
}
}