package mcjty.rftools.blocks.teleporter;
import mcjty.lib.base.StyleConfig;
import mcjty.lib.container.EmptyContainer;
import mcjty.lib.container.GenericGuiContainer;
import mcjty.lib.gui.events.ButtonEvent;
import mcjty.lib.gui.events.ChoiceEvent;
import mcjty.lib.gui.events.DefaultSelectionEvent;
import mcjty.lib.gui.layout.HorizontalAlignment;
import mcjty.lib.gui.layout.HorizontalLayout;
import mcjty.lib.gui.layout.VerticalLayout;
import mcjty.lib.gui.widgets.Button;
import mcjty.lib.gui.widgets.*;
import mcjty.lib.gui.widgets.Label;
import mcjty.lib.gui.widgets.Panel;
import mcjty.lib.network.Argument;
import mcjty.lib.network.PacketRequestIntegerFromServer;
import mcjty.lib.varia.Coordinate;
import mcjty.lib.varia.Logging;
import mcjty.rftools.RFTools;
import mcjty.rftools.blocks.storagemonitor.StorageScannerConfiguration;
import mcjty.rftools.network.RFToolsMessages;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.input.Keyboard;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class GuiDialingDevice extends GenericGuiContainer<DialingDeviceTileEntity> {
public static final int DIALER_WIDTH = 256;
public static final int DIALER_HEIGHT = 224;
private static final ResourceLocation guielements = new ResourceLocation(RFTools.MODID, "textures/gui/guielements.png");
private EnergyBar energyBar;
private WidgetList transmitterList;
private WidgetList receiverList;
private Button dialButton;
private Button dialOnceButton;
private Button interruptButton;
private ImageChoiceLabel favoriteButton;
private Button statusButton;
private Label statusLabel;
private boolean analyzerAvailable = false;
private boolean lastDialedTransmitter = false;
private boolean lastCheckedReceiver = false;
public static int fromServer_receiverStatus = -1;
public static int fromServer_dialResult = -1;
public static List<TeleportDestinationClientInfo> fromServer_receivers = null;
public static List<TransmitterInfo> fromServer_transmitters = null;
// A copy of the receivers we're currently showing.
private List<TeleportDestinationClientInfo> receivers = null;
private boolean receiversFiltered = false;
// A copy of the transmitters we're currently showing.
private List<TransmitterInfo> transmitters = null;
private int listDirty = 0;
public GuiDialingDevice(DialingDeviceTileEntity dialingDeviceTileEntity, EmptyContainer container) {
super(RFTools.instance, RFToolsMessages.INSTANCE, dialingDeviceTileEntity, container, RFTools.GUI_MANUAL_MAIN, "tpdialer");
dialingDeviceTileEntity.setCurrentRF(dialingDeviceTileEntity.getEnergyStored(ForgeDirection.DOWN));
xSize = DIALER_WIDTH;
ySize = DIALER_HEIGHT;
}
@Override
public void initGui() {
super.initGui();
int maxEnergyStored = tileEntity.getMaxEnergyStored(ForgeDirection.DOWN);
energyBar = new EnergyBar(mc, this).setFilledRectThickness(1).setHorizontal().setDesiredWidth(80).setDesiredHeight(12).setMaxValue(maxEnergyStored).setShowText(false);
energyBar.setValue(tileEntity.getCurrentRF());
Panel transmitterPanel = setupTransmitterPanel();
Panel receiverPanel = setupReceiverPanel();
dialButton = new Button(mc, this).setText("Dial").setTooltips("Start a connection between", "the selected transmitter", "and the selected receiver").
setDesiredHeight(14).setDesiredWidth(65).
addButtonEvent(new ButtonEvent() {
@Override
public void buttonClicked(Widget parent) {
dial(false);
}
});
dialOnceButton = new Button(mc, this).setText("Dial Once").setTooltips("Dial a connection for a", "single teleport").
setDesiredHeight(14).setDesiredWidth(65).
addButtonEvent(new ButtonEvent() {
@Override
public void buttonClicked(Widget parent) {
dial(true);
}
});
interruptButton = new Button(mc, this).setText("Interrupt").setTooltips("Interrupt a connection", "for the selected transmitter").
setDesiredHeight(14).setDesiredWidth(65).
addButtonEvent(new ButtonEvent() {
@Override
public void buttonClicked(Widget parent) {
interruptDial();
}
});
favoriteButton = new ImageChoiceLabel(mc, this).addChoiceEvent(new ChoiceEvent() {
@Override
public void choiceChanged(Widget parent, String newChoice) {
changeShowFavorite();
}
}).setDesiredWidth(10).setDesiredHeight(10);
favoriteButton.addChoice("No", "Unfavorited receiver", guielements, 131, 19);
favoriteButton.addChoice("Yes", "Favorited receiver", guielements, 115, 19);
favoriteButton.setCurrentChoice(tileEntity.isShowOnlyFavorites() ? 1 : 0);
Panel buttonPanel = new Panel(mc, this).setLayout(new HorizontalLayout()).addChild(dialButton).addChild(dialOnceButton).addChild(interruptButton).
addChild(favoriteButton).setDesiredHeight(16);
analyzerAvailable = DialingDeviceTileEntity.isDestinationAnalyzerAvailable(mc.theWorld, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
statusButton = new Button(mc, this).setText("Check").
setDesiredHeight(14).setDesiredWidth(65).
setEnabled(analyzerAvailable).
addButtonEvent(new ButtonEvent() {
@Override
public void buttonClicked(Widget parent) {
checkStatus();
}
});
if (analyzerAvailable) {
statusButton.setTooltips("Check the status of", "the selected receiver");
} else {
statusButton.setTooltips("Check the status of", "the selected receiver", "(needs an adjacent analyzer!)");
}
statusLabel = new Label(mc, this);
statusLabel.setDesiredWidth(170).setDesiredHeight(14).setFilledRectThickness(1);
Panel statusPanel = new Panel(mc, this).setLayout(new HorizontalLayout()).addChild(statusButton).addChild(statusLabel).setDesiredHeight(16);
Widget toplevel = new Panel(mc, this).setFilledRectThickness(2).setLayout(new VerticalLayout().setVerticalMargin(3).setSpacing(1)).
addChild(energyBar).addChild(transmitterPanel).
addChild(receiverPanel).addChild(buttonPanel).addChild(statusPanel);
toplevel.setBounds(new Rectangle(guiLeft, guiTop, DIALER_WIDTH, DIALER_HEIGHT));
window = new mcjty.lib.gui.Window(this, toplevel);
Keyboard.enableRepeatEvents(true);
listDirty = 0;
clearSelectedStatus();
requestReceivers();
requestTransmitters();
tileEntity.requestRfFromServer(RFToolsMessages.INSTANCE);
}
private Panel setupReceiverPanel() {
receiverList = new WidgetList(mc, this).setRowheight(14).setDesiredHeight(100).setPropagateEventsToChildren(true).addSelectionEvent(new DefaultSelectionEvent() {
@Override
public void select(Widget parent, int index) {
clearSelectedStatus();
}
@Override
public void doubleClick(Widget parent, int index) {
hilightSelectedReceiver(index);
}
});
Slider receiverSlider = new Slider(mc, this).setDesiredWidth(11).setDesiredHeight(100).setVertical().setScrollable(receiverList);
return new Panel(mc, this).setLayout(new HorizontalLayout().setSpacing(1).setHorizontalMargin(3)).addChild(receiverList).addChild(receiverSlider).setDesiredHeight(106)
.setFilledBackground(0xff9e9e9e);
}
private Panel setupTransmitterPanel() {
transmitterList = new WidgetList(mc, this).setRowheight(18).setDesiredHeight(58).addSelectionEvent(new DefaultSelectionEvent() {
@Override
public void select(Widget parent, int index) {
clearSelectedStatus();
selectReceiverFromTransmitter();
}
@Override
public void doubleClick(Widget parent, int index) {
hilightSelectedTransmitter(index);
}
});
Slider transmitterSlider = new Slider(mc, this).setDesiredWidth(11).setDesiredHeight(58).setVertical().setScrollable(transmitterList);
return new Panel(mc, this).setLayout(new HorizontalLayout().setSpacing(1).setHorizontalMargin(3)).addChild(transmitterList).addChild(transmitterSlider).setDesiredHeight(64)
.setFilledBackground(0xff9e9e9e);
}
private void clearSelectedStatus() {
lastDialedTransmitter = false;
lastCheckedReceiver = false;
}
private void hilightSelectedTransmitter(int index) {
TransmitterInfo transmitterInfo = getSelectedTransmitter(index);
if (transmitterInfo == null) {
return;
}
Coordinate c = transmitterInfo.getCoordinate();
RFTools.instance.clientInfo.hilightBlock(c, System.currentTimeMillis() + 1000 * StorageScannerConfiguration.hilightTime);
mc.getMinecraft().thePlayer.closeScreen();
}
private void hilightSelectedReceiver(int index) {
TeleportDestination destination = getSelectedReceiver(index);
if (destination == null) {
return;
}
Coordinate c = destination.getCoordinate();
double distance = Vec3.createVectorHelper(c.getX(), c.getY(), c.getZ()).distanceTo(mc.thePlayer.getPosition(1.0f));
if (destination.getDimension() != mc.theWorld.provider.dimensionId || distance > 150) {
Logging.warn(mc.thePlayer, "Receiver is too far to hilight!");
mc.getMinecraft().thePlayer.closeScreen();
return;
}
RFTools.instance.clientInfo.hilightBlock(c, System.currentTimeMillis()+1000* StorageScannerConfiguration.hilightTime);
Logging.message(mc.thePlayer, "The receiver is now highlighted");
mc.getMinecraft().thePlayer.closeScreen();
}
private void setStatusError(String message) {
statusLabel.setText(message);
statusLabel.setColor(0xffffffff);
statusLabel.setFilledBackground(0xffff0000, 0xff880000);
}
private void setStatusMessage(String message) {
statusLabel.setText(message);
statusLabel.setColor(0xff000000);
statusLabel.setFilledBackground(0xff00ff00, 0xff008800);
}
private void checkStatus() {
int receiverSelected = receiverList.getSelected();
TeleportDestination destination = getSelectedReceiver(receiverSelected);
if (destination == null) {
return;
}
Coordinate c = destination.getCoordinate();
RFToolsMessages.INSTANCE.sendToServer(new PacketRequestIntegerFromServer(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord,
DialingDeviceTileEntity.CMD_CHECKSTATUS,
DialingDeviceTileEntity.CLIENTCMD_STATUS, new Argument("c", c), new Argument("dim", destination.getDimension())));
lastCheckedReceiver = true;
listDirty = 0;
}
private void showStatus(int dialResult) {
if ((dialResult & DialingDeviceTileEntity.DIAL_DIALER_POWER_LOW_MASK) != 0) {
setStatusError("Dialing device power low!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_RECEIVER_POWER_LOW_MASK) != 0) {
setStatusError("Matter receiver power low!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_DIMENSION_POWER_LOW_MASK) != 0) {
setStatusError("Destination dimension power low!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_TRANSMITTER_NOACCESS) != 0) {
setStatusError("No access to transmitter!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_RECEIVER_NOACCESS) != 0) {
setStatusError("No access to receiver!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_INVALID_DESTINATION_MASK) != 0) {
setStatusError("Invalid destination!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_INVALID_SOURCE_MASK) != 0) {
setStatusError("Invalid source!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_RECEIVER_BLOCKED_MASK) != 0) {
setStatusError("Receiver blocked!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_TRANSMITTER_BLOCKED_MASK) != 0) {
setStatusError("Transmitter blocked!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_INVALID_TRANSMITTER) != 0) {
setStatusError("Invalid transmitter!!");
return;
}
if ((dialResult & DialingDeviceTileEntity.DIAL_INTERRUPTED) != 0) {
setStatusMessage("Interrupted!");
return;
}
setStatusMessage("Dial ok!");
}
private void selectReceiverFromTransmitter() {
receiverList.setSelected(-1);
TeleportDestination destination = getSelectedTransmitterDestination();
if (destination == null) {
return;
}
int i = 0;
for (TeleportDestination receiver : receivers) {
if (receiver.getDimension() == destination.getDimension() && receiver.getCoordinate().equals(destination.getCoordinate())) {
receiverList.setSelected(i);
return;
}
i++;
}
}
private void dial(boolean once) {
int transmitterSelected = transmitterList.getSelected();
TransmitterInfo transmitterInfo = getSelectedTransmitter(transmitterSelected);
if (transmitterInfo == null) {
return;
}
int receiverSelected = receiverList.getSelected();
TeleportDestination destination = getSelectedReceiver(receiverSelected);
if (destination == null) {
return;
}
RFToolsMessages.INSTANCE.sendToServer(new PacketRequestIntegerFromServer(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord,
once ? DialingDeviceTileEntity.CMD_DIALONCE : DialingDeviceTileEntity.CMD_DIAL,
DialingDeviceTileEntity.CLIENTCMD_DIAL,
new Argument("player", mc.thePlayer.getDisplayName()),
new Argument("trans", transmitterInfo.getCoordinate()), new Argument("transDim", mc.theWorld.provider.dimensionId),
new Argument("c", destination.getCoordinate()), new Argument("dim", destination.getDimension())));
lastDialedTransmitter = true;
listDirty = 0;
}
private TeleportDestinationClientInfo getSelectedReceiver(int receiverSelected) {
if (receiverSelected == -1) {
return null;
}
if (receiverSelected >= receivers.size()) {
return null;
}
return receivers.get(receiverSelected);
}
private void interruptDial() {
int transmitterSelected = transmitterList.getSelected();
TransmitterInfo transmitterInfo = getSelectedTransmitter(transmitterSelected);
if (transmitterInfo == null) {
return;
}
RFToolsMessages.INSTANCE.sendToServer(new PacketRequestIntegerFromServer(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, DialingDeviceTileEntity.CMD_DIAL,
DialingDeviceTileEntity.CLIENTCMD_DIAL,
new Argument("player", mc.thePlayer.getDisplayName()),
new Argument("trans", transmitterInfo.getCoordinate()), new Argument("transDim", mc.theWorld.provider.dimensionId),
new Argument("c", (Coordinate) null), new Argument("dim", 0)));
lastDialedTransmitter = true;
listDirty = 0;
}
private void requestReceivers() {
RFToolsMessages.INSTANCE.sendToServer(new PacketGetReceivers(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord, mc.thePlayer.getDisplayName()));
}
private void requestTransmitters() {
RFToolsMessages.INSTANCE.sendToServer(new PacketGetTransmitters(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord));
}
private void changeShowFavorite() {
boolean fav = favoriteButton.getCurrentChoiceIndex() == 1;
sendServerCommand(RFToolsMessages.INSTANCE, DialingDeviceTileEntity.CMD_SHOWFAVORITE,
new Argument("favorite", fav));
listDirty = 0;
transmitterList.setSelected(-1);
receiverList.setSelected(-1);
}
private void changeFavorite() {
int receiverSelected = receiverList.getSelected();
TeleportDestinationClientInfo destination = getSelectedReceiver(receiverSelected);
if (destination == null) {
return;
}
boolean favorite = destination.isFavorite();
destination.setFavorite(!favorite);
sendServerCommand(RFToolsMessages.INSTANCE, DialingDeviceTileEntity.CMD_FAVORITE,
new Argument("player", mc.thePlayer.getDisplayName()),
new Argument("receiver", destination.getCoordinate()),
new Argument("dimension", destination.getDimension()),
new Argument("favorite", !favorite));
listDirty = 0;
}
private void populateReceivers() {
List<TeleportDestinationClientInfo> newReceivers = fromServer_receivers;
if (newReceivers == null) {
return;
}
boolean newReceiversFiltered = favoriteButton.getCurrentChoiceIndex() == 1;
if (newReceivers.equals(receivers) && newReceiversFiltered == receiversFiltered) {
return;
}
receiversFiltered = newReceiversFiltered;
if (receiversFiltered) {
receivers = new ArrayList<TeleportDestinationClientInfo>();
// We only show favorited receivers. Remove the rest.
for (TeleportDestinationClientInfo receiver : newReceivers) {
if (receiver.isFavorite()) {
receivers.add(receiver);
}
}
} else {
// Show all receivers.
receivers = new ArrayList<TeleportDestinationClientInfo>(newReceivers);
}
receiverList.removeChildren();
for (TeleportDestinationClientInfo destination : receivers) {
Coordinate coordinate = destination.getCoordinate();
String dimName = destination.getDimensionName();
if (dimName == null || dimName.trim().isEmpty()) {
dimName = "Id " + destination.getDimension();
}
boolean favorite = destination.isFavorite();
Panel panel = new Panel(mc, this).setLayout(new HorizontalLayout().setSpacing(1).setHorizontalMargin(3));
panel.addChild(new Label(mc, this).setColor(StyleConfig.colorTextInListNormal).setText(destination.getName()).setHorizontalAlignment(HorizontalAlignment.ALIGH_LEFT).setDesiredWidth(96).
setTooltips("The name of the", "destination receiver:", destination.getName() + " (" + coordinate.toString() + ")"));
panel.addChild(new Label(mc, this).setColor(StyleConfig.colorTextInListNormal).setText(dimName).setHorizontalAlignment(HorizontalAlignment.ALIGH_LEFT)
.setDynamic(true).setTooltips("The name of the", "destination dimension:", dimName)
.setDesiredWidth(110));
ImageChoiceLabel choiceLabel = new ImageChoiceLabel(mc, this).addChoiceEvent(new ChoiceEvent() {
@Override
public void choiceChanged(Widget parent, String newChoice) {
changeFavorite();
}
}).setDesiredWidth(10);
choiceLabel.addChoice("No", "Not favorited", guielements, 131, 19);
choiceLabel.addChoice("Yes", "Favorited", guielements, 115, 19);
choiceLabel.setCurrentChoice(favorite ? 1 : 0);
panel.addChild(choiceLabel);
receiverList.addChild(panel);
}
}
private TeleportDestination getSelectedTransmitterDestination() {
int transmitterSelected = transmitterList.getSelected();
TransmitterInfo transmitterInfo = getSelectedTransmitter(transmitterSelected);
if (transmitterInfo == null) {
return null;
}
TeleportDestination destination = transmitterInfo.getTeleportDestination();
if (destination.isValid()) {
return destination;
} else {
return null;
}
}
private void populateTransmitters() {
List<TransmitterInfo> newTransmitters = fromServer_transmitters;
if (newTransmitters == null) {
return;
}
if (newTransmitters.equals(transmitters)) {
return;
}
transmitters = new ArrayList<TransmitterInfo>(newTransmitters);
transmitterList.removeChildren();
for (TransmitterInfo transmitterInfo : transmitters) {
Coordinate coordinate = transmitterInfo.getCoordinate();
TeleportDestination destination = transmitterInfo.getTeleportDestination();
Panel panel = new Panel(mc, this).setLayout(new HorizontalLayout().setHorizontalMargin(3));
panel.addChild(new Label(mc, this).setColor(StyleConfig.colorTextInListNormal).setText(transmitterInfo.getName()).setHorizontalAlignment(HorizontalAlignment.ALIGH_LEFT).setDesiredWidth(102));
panel.addChild(new Label(mc, this).setColor(StyleConfig.colorTextInListNormal).setDynamic(true).setText(coordinate.toString()).setDesiredWidth(90));
panel.addChild(new ImageLabel(mc, this).setImage(guielements, destination.isValid() ? 80 : 96, 0).setDesiredWidth(16));
transmitterList.addChild(panel);
}
}
@Override
protected void drawGuiContainerBackgroundLayer(float v, int i, int i2) {
requestListsIfNeeded();
populateReceivers();
populateTransmitters();
if (lastDialedTransmitter) {
showStatus(fromServer_dialResult);
} else if (lastCheckedReceiver) {
showStatus(fromServer_receiverStatus);
} else {
statusLabel.setText("");
statusLabel.setColor(0xff000000);
statusLabel.setFilledBackground(-1);
}
enableButtons();
drawWindow();
int currentRF = tileEntity.getCurrentRF();
energyBar.setValue(currentRF);
tileEntity.requestRfFromServer(RFToolsMessages.INSTANCE);
}
private void requestListsIfNeeded() {
listDirty--;
if (listDirty <= 0) {
requestReceivers();
requestTransmitters();
listDirty = 20;
}
}
private String calculateDistance(int transmitterSelected, int receiverSelected) {
TransmitterInfo transmitterInfo = getSelectedTransmitter(transmitterSelected);
if (transmitterInfo == null) {
return "?";
}
TeleportDestination teleportDestination = getSelectedReceiver(receiverSelected);
if (teleportDestination == null) {
return "?";
}
return DialingDeviceTileEntity.calculateDistance(mc.theWorld, transmitterInfo, teleportDestination);
}
private TransmitterInfo getSelectedTransmitter(int transmitterSelected) {
if (transmitterSelected == -1) {
return null;
}
if (transmitterSelected >= transmitters.size()) {
return null;
}
return transmitters.get(transmitterSelected);
}
private void enableButtons() {
int transmitterSelected = transmitterList.getSelected();
if (transmitters == null || transmitterSelected >= transmitters.size()) {
transmitterSelected = -1;
transmitterList.setSelected(-1);
}
int receiverSelected = receiverList.getSelected();
if (receivers == null || receiverSelected >= receivers.size()) {
receiverSelected = -1;
receiverList.setSelected(-1);
}
if (transmitterSelected != -1 && receiverSelected != -1) {
dialButton.setEnabled(true);
dialOnceButton.setEnabled(true);
String distance = calculateDistance(transmitterSelected, receiverSelected);
dialButton.setTooltips("Start a connection between", "the selected transmitter", "and the selected receiver.", "Distance: " + distance);
dialOnceButton.setTooltips("Dial a connection for a", "single teleport.", "Distance: " + distance);
} else {
dialButton.setEnabled(false);
dialOnceButton.setEnabled(false);
dialButton.setTooltips("Start a connection between", "the selected transmitter", "and the selected receiver");
dialOnceButton.setTooltips("Dial a connection for a", "single teleport");
}
if (transmitterSelected != -1) {
TeleportDestination destination = getSelectedTransmitterDestination();
interruptButton.setEnabled(destination != null);
} else {
interruptButton.setEnabled(false);
}
if (receiverSelected != -1) {
statusButton.setEnabled(analyzerAvailable);
} else {
statusButton.setEnabled(false);
}
}
}