package mods.railcraft.client.gui;
import java.util.BitSet;
import java.util.EnumMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mods.railcraft.api.signals.SignalAspect;
import mods.railcraft.common.blocks.signals.TileBoxAnalogController;
import mods.railcraft.common.core.RailcraftConstants;
import mods.railcraft.common.plugins.forge.LocalizationPlugin;
import mods.railcraft.common.util.misc.Game;
import mods.railcraft.common.util.network.PacketDispatcher;
import mods.railcraft.common.util.network.PacketGuiReturn;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.opengl.GL11;
public class GuiBoxAnalogController extends GuiBasic {
private final TileBoxAnalogController tile;
private final static Pattern patternRange = Pattern.compile("(\\d+)-(\\d+)|(\\d+)");
//When doing Pattern.matcher, these are the groups: ^ 1 ^ 2 ^ 3
private final EnumMap<SignalAspect, BitSet> aspects = new EnumMap<SignalAspect, BitSet>(SignalAspect.class);
private final EnumMap<SignalAspect, GuiTextField> textbox = new EnumMap<SignalAspect, GuiTextField>(SignalAspect.class);
public GuiBoxAnalogController(TileBoxAnalogController tile) {
super(tile.getName(), RailcraftConstants.GUI_TEXTURE_FOLDER + "gui_basic_large.png", 176, 113);
this.tile = tile;
for (Map.Entry<SignalAspect, BitSet> entry : tile.aspects.entrySet()) {
aspects.put(entry.getKey(), (BitSet) entry.getValue().clone());
}
}
@Override
public void mouseClicked(int i, int j, int k) {
super.mouseClicked(i, j, k);
for (GuiTextField t : textbox.values()) {
t.mouseClicked(i, j, k);
}
}
@Override
public void keyTyped(char c, int i) {
super.keyTyped(c, i);
//Disallow any PRINTABLE characters that are not digits, commas, or dashes
if (c < ' ' || (c >= '0' && c <= '9') || c == '-' || c == ',' || c > '~')
for (GuiTextField t : textbox.values()) {
t.textboxKeyTyped(c, i);
}
}
private String rangeToString(BitSet b) {
String s = "";
int start = -1;
for (int i = 0; i < 16; i++) {
if (b.get(i)) {
if (start == -1) {
s += i;
start = i;
}
} else if (start != -1) {
if (i - 1 == start)
s += ",";
else
s += "-" + (i - 1) + ",";
start = -1;
}
}
if (start != -1 && start != 15) {
s += "-15";
start = 15;
}
if (s.isEmpty() || start == 15)
return s;
else
return s.substring(0, s.length() - 1); //Remove trailing comma
}
private void parseRegex(String regex, BitSet bits) {
bits.clear();
Matcher m = patternRange.matcher(regex);
while (m.find()) {
if (m.groupCount() >= 3 && m.group(3) != null) {
int i = Integer.parseInt(m.group(3));
if (i >= 0 && i <= 15)
bits.set(i);
} else {
int start = Integer.parseInt(m.group(1));
int end = Integer.parseInt(m.group(2));
if (start >= 0 && end >= 0 && start <= 15 && end <= 15 && start <= end)
for (int i = start; i <= end; i++) {
bits.set(i);
}
}
}
}
@Override
public void initGui() {
if (tile == null)
return;
int w = (width - xSize) / 2;
int h = (height - ySize) / 2;
for (Map.Entry<SignalAspect, BitSet> entry : aspects.entrySet()) {
GuiTextField textField = new GuiTextField(fontRendererObj, w + 72, h + getYPosFromIndex(entry.getKey().ordinal()), 95, 10);
textField.setMaxStringLength(37);
textField.setText(rangeToString(entry.getValue()));
textbox.put(entry.getKey(), textField);
}
}
@Override
public void drawScreen(int x, int y, float f) {
super.drawScreen(x, y, f);
GL11.glDisable(GL11.GL_LIGHTING);
for (GuiTextField t : textbox.values()) {
t.drawTextBox();
}
}
@Override
protected void drawExtras(int x, int y, float f) {
for (SignalAspect aspect : SignalAspect.VALUES) {
drawAlignedString(fontRendererObj, LocalizationPlugin.translate(aspect.getLocalizationTag()), 10, getYPosFromIndex(aspect.ordinal()) + 1, 50);
}
}
@Override
public void updateScreen() {
for (GuiTextField t : textbox.values()) {
t.updateCursorCounter();
}
super.updateScreen();
}
@Override
public void onGuiClosed() {
if (Game.isNotHost(tile.getWorld())) {
for (Map.Entry<SignalAspect, BitSet> entry : aspects.entrySet()) {
parseRegex(textbox.get(entry.getKey()).getText(), entry.getValue());
}
tile.aspects = aspects;
PacketGuiReturn pkt = new PacketGuiReturn(tile);
PacketDispatcher.sendToServer(pkt);
}
}
private static void drawAlignedString(FontRenderer fr, String s, int x, int y, int width) {
fr.drawString(s, x + (width - fr.getStringWidth(s)) / 2, y, 0x404040);
}
private static int getYPosFromIndex(int i) {
return 22 + i * 14;
}
}