package slimeknights.tconstruct.tools.common.client;
import com.google.common.collect.Lists;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.Point;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import slimeknights.mantle.client.gui.GuiElement;
import slimeknights.mantle.client.gui.GuiElementScalable;
import slimeknights.mantle.client.gui.GuiModule;
import slimeknights.tconstruct.common.TinkerNetwork;
import slimeknights.tconstruct.library.TinkerRegistry;
import slimeknights.tconstruct.library.TinkerRegistryClient;
import slimeknights.tconstruct.library.Util;
import slimeknights.tconstruct.library.client.Icons;
import slimeknights.tconstruct.library.client.ToolBuildGuiInfo;
import slimeknights.tconstruct.library.modifiers.IModifier;
import slimeknights.tconstruct.library.modifiers.ModifierNBT;
import slimeknights.tconstruct.library.tinkering.IModifyable;
import slimeknights.tconstruct.library.tinkering.IToolStationDisplay;
import slimeknights.tconstruct.library.tinkering.PartMaterialType;
import slimeknights.tconstruct.library.tinkering.TinkersItem;
import slimeknights.tconstruct.library.tools.IToolPart;
import slimeknights.tconstruct.library.tools.ToolCore;
import slimeknights.tconstruct.library.utils.TagUtil;
import slimeknights.tconstruct.tools.common.client.module.GuiButtonsToolStation;
import slimeknights.tconstruct.tools.common.client.module.GuiInfoPanel;
import slimeknights.tconstruct.tools.common.inventory.ContainerTinkerStation;
import slimeknights.tconstruct.tools.common.inventory.ContainerToolStation;
import slimeknights.tconstruct.tools.common.inventory.SlotToolStationIn;
import slimeknights.tconstruct.tools.common.network.ToolStationSelectionPacket;
import slimeknights.tconstruct.tools.common.network.ToolStationTextPacket;
import slimeknights.tconstruct.tools.common.tileentity.TileToolStation;
@SideOnly(Side.CLIENT)
public class GuiToolStation extends GuiTinkerStation {
private static final ResourceLocation BACKGROUND = Util.getResource("textures/gui/toolstation.png");
private static final GuiElement TextFieldActive = new GuiElement(0, 210, 102, 12, 256, 256);
private static final GuiElement ItemCover = new GuiElement(176, 18, 80, 64);
private static final GuiElement SlotBackground = new GuiElement(176, 0, 18, 18);
private static final GuiElement SlotBorder = new GuiElement(194, 0, 18, 18);
private static final GuiElement SlotSpaceTop = new GuiElement(0, 174 + 2, 18, 2);
private static final GuiElement SlotSpaceBottom = new GuiElement(0, 174, 18, 2);
private static final GuiElement PanelSpaceL = new GuiElement(0, 174, 5, 4);
private static final GuiElement PanelSpaceR = new GuiElement(9, 174, 9, 4);
private static final GuiElement BeamLeft = new GuiElement(0, 180, 2, 7);
private static final GuiElement BeamRight = new GuiElement(131, 180, 2, 7);
private static final GuiElementScalable BeamCenter = new GuiElementScalable(2, 180, 129, 7);
public static final int Column_Count = 5;
private static final int Table_slot_count = 6;
protected GuiElement buttonDecorationTop = SlotSpaceTop;
protected GuiElement buttonDecorationBot = SlotSpaceBottom;
protected GuiElement panelDecorationL = PanelSpaceL;
protected GuiElement panelDecorationR = PanelSpaceR;
protected GuiElement beamL = new GuiElement(0, 0, 0, 0);
protected GuiElement beamR = new GuiElement(0, 0, 0, 0);
protected GuiElementScalable beamC = new GuiElementScalable(0, 0, 0, 0);
protected GuiButtonsToolStation buttons;
protected int activeSlots; // how many of the available slots are active
public GuiTextField textField;
protected GuiInfoPanel toolInfo;
protected GuiInfoPanel traitInfo;
public ToolBuildGuiInfo currentInfo = GuiButtonRepair.info;
public GuiToolStation(InventoryPlayer playerInv, World world, BlockPos pos, TileToolStation tile) {
super(world, pos, (ContainerTinkerStation) tile.createContainer(playerInv, world, pos));
buttons = new GuiButtonsToolStation(this, inventorySlots);
this.addModule(buttons);
toolInfo = new GuiInfoPanel(this, inventorySlots);
this.addModule(toolInfo);
traitInfo = new GuiInfoPanel(this, inventorySlots);
this.addModule(traitInfo);
toolInfo.yOffset = 5;
traitInfo.yOffset = toolInfo.ySize + 9;
this.ySize = 174;
wood();
}
@Override
public void initGui() {
super.initGui();
Keyboard.enableRepeatEvents(true);
// workaround to line up the tabs on switching even though the GUI is a tad higher
this.guiTop += 4;
this.cornerY += 4;
textField = new GuiTextField(0, fontRendererObj, cornerX + 70, cornerY + 7, 92, 12);
//textField.setFocused(true);
//textField.setCanLoseFocus(false);
textField.setEnableBackgroundDrawing(false);
textField.setMaxStringLength(40);
buttons.xOffset = -2;
buttons.yOffset = beamC.h + buttonDecorationTop.h;
toolInfo.xOffset = 2;
toolInfo.yOffset = beamC.h + panelDecorationL.h;
traitInfo.xOffset = toolInfo.xOffset;
traitInfo.yOffset = toolInfo.yOffset + toolInfo.ySize + 4;
for(GuiModule module : modules) {
module.guiTop += 4;
}
updateGUI();
}
@Override
public void onGuiClosed() {
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
public Set<ToolCore> getBuildableItems() {
return TinkerRegistry.getToolStationCrafting();
}
public void onToolSelection(ToolBuildGuiInfo info) {
activeSlots = Math.min(info.positions.size(), Table_slot_count);
currentInfo = info;
ToolCore tool = null;
if(info.tool != null && info.tool.getItem() instanceof ToolCore) {
tool = (ToolCore) info.tool.getItem();
}
((ContainerToolStation) inventorySlots).setToolSelection(tool, activeSlots);
// update the server (and others)
TinkerNetwork.sendToServer(new ToolStationSelectionPacket(tool, activeSlots));
updateGUI();
}
public void onToolSelectionPacket(ToolStationSelectionPacket packet) {
ToolBuildGuiInfo info = TinkerRegistryClient.getToolBuildInfoForTool(packet.tool);
if(info == null) {
info = GuiButtonRepair.info;
}
activeSlots = packet.activeSlots;
currentInfo = info;
buttons.setSelectedButtonByTool(currentInfo.tool);
updateGUI();
}
public void updateGUI() {
int i;
for(i = 0; i < activeSlots; i++) {
Point point = currentInfo.positions.get(i);
Slot slot = inventorySlots.getSlot(i);
slot.xPos = point.getX();
slot.yPos = point.getY();
}
// remaining slots
int stillFilled = 0;
for(; i < Table_slot_count; i++) {
Slot slot = inventorySlots.getSlot(i);
if(slot.getHasStack()) {
slot.xPos = 87 + 20 * stillFilled;
slot.yPos = 62;
stillFilled++;
}
else {
// todo: slot.disable
slot.xPos = 0;
slot.yPos = 0;
}
}
updateDisplay();
}
@Override
public void updateDisplay() {
// tool info of existing or tool to build
ContainerToolStation container = (ContainerToolStation) inventorySlots;
ItemStack toolStack = container.getResult();
if(toolStack == null) {
toolStack = inventorySlots.getSlot(0).getStack();
}
// current tool to build or repair/modify
if(toolStack != null && toolStack.getItem() instanceof IModifyable) {
if(toolStack.getItem() instanceof IToolStationDisplay) {
IToolStationDisplay tool = (IToolStationDisplay) toolStack.getItem();
toolInfo.setCaption(tool.getLocalizedToolName());
toolInfo.setText(tool.getInformation(toolStack));
}
else {
toolInfo.setCaption(toolStack.getDisplayName());
toolInfo.setText();
}
traitInfo.setCaption(I18n.translateToLocal("gui.toolstation.traits"));
List<String> mods = Lists.newLinkedList();
List<String> tips = Lists.newLinkedList();
NBTTagList tagList = TagUtil.getModifiersTagList(toolStack);
for(int i = 0; i < tagList.tagCount(); i++) {
NBTTagCompound tag = tagList.getCompoundTagAt(i);
ModifierNBT data = ModifierNBT.readTag(tag);
// get matching modifier
IModifier modifier = TinkerRegistry.getModifier(data.identifier);
if(modifier == null || modifier.isHidden()) {
continue;
}
mods.add(data.getColorString() + modifier.getTooltip(tag, true));
tips.add(data.getColorString() + modifier.getLocalizedDesc());
}
if(mods.isEmpty()) {
mods.add(I18n.translateToLocal("gui.toolstation.noTraits"));
}
traitInfo.setText(mods, tips);
}
// repair info
else if(currentInfo.tool == null) {
toolInfo.setCaption(I18n.translateToLocal("gui.toolstation.repair"));
toolInfo.setText();
traitInfo.setCaption(null);
String c = TextFormatting.DARK_GRAY.toString();
String[] art = new String[]{
c + "",
c + "",
c + " .",
c + " /( _________",
c + " | >:=========`",
c + " )( ",
c + " \"\""
};
traitInfo.setText(art);
}
// tool build info
else {
ToolCore tool = (ToolCore) currentInfo.tool.getItem();
toolInfo.setCaption(tool.getLocalizedToolName());
toolInfo.setText(tool.getLocalizedDescription());
// Components
List<String> text = Lists.newLinkedList();
List<PartMaterialType> pms = tool.getRequiredComponents();
for(int i = 0; i < pms.size(); i++) {
PartMaterialType pmt = pms.get(i);
StringBuilder sb = new StringBuilder();
ItemStack slotStack = container.getSlot(i).getStack();
if(!pmt.isValid(slotStack)) {
sb.append(TextFormatting.RED);
// is an item in the slot?
if(slotStack != null && slotStack.getItem() instanceof IToolPart) {
if(pmt.isValidItem((IToolPart) slotStack.getItem())) {
// the item has an invalid material
warning(Util.translate("gui.error.wrong_material_part"));
}
}
}
sb.append(" * ");
for(IToolPart part : pmt.getPossibleParts()) {
if(part instanceof Item) {
sb.append(((Item) part).getItemStackDisplayName(new ItemStack((Item) part)));
sb.append("/");
}
}
sb.deleteCharAt(sb.length() - 1); // removes last '/'
text.add(sb.toString());
}
traitInfo.setCaption(I18n.translateToLocal("gui.toolstation.components"));
traitInfo.setText(text.toArray(new String[text.size()]));
}
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton);
textField.mouseClicked(mouseX, mouseY, mouseButton);
}
@Override
protected void keyTyped(char typedChar, int keyCode) throws IOException {
if(!textField.isFocused()) {
super.keyTyped(typedChar, keyCode);
}
else {
if(keyCode == 1) {
this.mc.player.closeScreen();
}
textField.textboxKeyTyped(typedChar, keyCode);
TinkerNetwork.sendToServer(new ToolStationTextPacket(textField.getText()));
((ContainerToolStation) container).setToolName(textField.getText());
}
}
@Override
public void updateScreen() {
super.updateScreen();
textField.updateCursorCounter();
}
@Override
public void drawSlot(Slot slotIn) {
// don't draw dormant slots with no item
if(slotIn instanceof SlotToolStationIn && ((SlotToolStationIn) slotIn).isDormant() && !slotIn.getHasStack()) {
return;
}
super.drawSlot(slotIn);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
drawBackground(BACKGROUND);
if(textField.isFocused()) {
TextFieldActive.draw(cornerX + 68, cornerY + 6);
}
// draw textfield
textField.drawTextBox();
//int xOff = 3;
//int yOff = 6;
int x = 0;
int y = 0;
// draw the item background
final float scale = 3.7f;
final float xOff = 10f;
final float yOff = 22f;
GlStateManager.translate(xOff, yOff, 0);
GlStateManager.scale(scale, scale, 1.0f);
{
int logoX = (int) (this.cornerX / scale);
int logoY = (int) (this.cornerY / scale);
if(currentInfo != null) {
if(currentInfo.tool != null) {
itemRender.renderItemIntoGUI(currentInfo.tool, logoX, logoY);
}
else if(currentInfo == GuiButtonRepair.info) {
this.mc.getTextureManager().bindTexture(Icons.ICON);
Icons.ICON_Anvil.draw(logoX, logoY);
}
}
}
GlStateManager.scale(1f / scale, 1f / scale, 1.0f);
GlStateManager.translate(-xOff, -yOff, 0);
// rebind gui texture since itemstack drawing sets it to something else
this.mc.getTextureManager().bindTexture(BACKGROUND);
// reset state after item drawing
GlStateManager.enableBlend();
GlStateManager.enableAlpha();
RenderHelper.disableStandardItemLighting();
GlStateManager.disableDepth();
// draw the halftransparent "cover" over the item
GlStateManager.color(1.0f, 1.0f, 1.0f, 0.82f);
ItemCover.draw(this.cornerX + 7, this.cornerY + 18);
// the slot backgrounds
GlStateManager.color(1.0f, 1.0f, 1.0f, 0.28f);
for(int i = 0; i < activeSlots; i++) {
Slot slot = inventorySlots.getSlot(i);
SlotBackground.draw(x + this.cornerX + slot.xPos - 1, y + this.cornerY + slot.yPos - 1);
}
// full opaque. Draw the borders of the slots
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
for(int i = 0; i < Table_slot_count; i++) {
Slot slot = inventorySlots.getSlot(i);
if(slot instanceof SlotToolStationIn && (!((SlotToolStationIn) slot).isDormant() || slot.getHasStack())) {
SlotBorder.draw(
x + this.cornerX + slot.xPos - 1, y + this.cornerY + slot.yPos - 1);
}
}
this.mc.getTextureManager().bindTexture(Icons.ICON);
// slot logos
if(currentInfo == GuiButtonRepair.info) {
drawRepairSlotIcons();
}
else if(currentInfo.tool != null && currentInfo.tool.getItem() instanceof TinkersItem) {
for(int i = 0; i < activeSlots; i++) {
Slot slot = inventorySlots.getSlot(i);
if(!(slot instanceof SlotToolStationIn)) {
continue;
}
ItemStack stack = ((SlotToolStationIn) slot).icon;
if(stack == null) {
continue;
}
itemRender.renderItemIntoGUI(stack,
x + this.cornerX + slot.xPos,
y + this.cornerY + slot.yPos);
}
}
this.mc.getTextureManager().bindTexture(BACKGROUND);
x = buttons.guiLeft - beamL.w;
y = cornerY;
// draw the beams at the top
x += beamL.draw(x, y);
x += beamC.drawScaledX(x, y, buttons.xSize);
beamR.draw(x, y);
x = toolInfo.guiLeft - beamL.w;
x += beamL.draw(x, y);
x += beamC.drawScaledX(x, y, toolInfo.xSize);
beamR.draw(x, y);
// draw the decoration for the buttons
for(Object o : buttons.buttonList) {
GuiButton button = (GuiButton) o;
buttonDecorationTop.draw(button.xPosition, button.yPosition - buttonDecorationTop.h);
// don't draw the bottom for the buttons in the last row
if(button.id < buttons.buttonList.size() - Column_Count) {
buttonDecorationBot.draw(button.xPosition, button.yPosition + button.height);
}
}
// draw the decorations for the panels
panelDecorationL.draw(toolInfo.guiLeft + 5, toolInfo.guiTop - panelDecorationL.h);
panelDecorationR.draw(toolInfo.guiRight() - 5 - panelDecorationR.w, toolInfo.guiTop - panelDecorationR.h);
panelDecorationL.draw(traitInfo.guiLeft + 5, traitInfo.guiTop - panelDecorationL.h);
panelDecorationR.draw(traitInfo.guiRight() - 5 - panelDecorationR.w, traitInfo.guiTop - panelDecorationR.h);
GlStateManager.enableDepth();
// continue as usual and hope that the drawing state is not completely wrecked
super.drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY);
}
protected void drawRepairSlotIcons() {
for(int i = 0; i < activeSlots; i++) {
drawRepairSlotIcon(i);
}
}
protected void drawRepairSlotIcon(int i) {
GuiElement icon = null;
Slot slot = inventorySlots.getSlot(i);
// only empty solts get the logo since something else than the displayed thing might be in there.
// which would look weird.
if(slot.getHasStack()) {
return;
}
if(i == 0) {
icon = Icons.ICON_Pickaxe;
}
else if(i == 1) {
icon = Icons.ICON_Dust;
}
else if(i == 2) {
icon = Icons.ICON_Lapis;
}
else if(i == 3) {
icon = Icons.ICON_Ingot;
}
else if(i == 4) {
icon = Icons.ICON_Gem;
}
else if(i == 5) {
icon = Icons.ICON_Quartz;
}
if(icon != null) {
drawIconEmpty(slot, icon);
}
}
protected void wood() {
toolInfo.wood();
traitInfo.wood();
buttonDecorationTop = SlotSpaceTop.shift(SlotSpaceTop.w, 0);
buttonDecorationBot = SlotSpaceBottom.shift(SlotSpaceBottom.w, 0);
panelDecorationL = PanelSpaceL.shift(18, 0);
panelDecorationR = PanelSpaceR.shift(18, 0);
buttons.wood();
beamL = BeamLeft;
beamR = BeamRight;
beamC = BeamCenter;
}
protected void metal() {
toolInfo.metal();
traitInfo.metal();
buttonDecorationTop = SlotSpaceTop.shift(SlotSpaceTop.w * 2, 0);
buttonDecorationBot = SlotSpaceBottom.shift(SlotSpaceBottom.w * 2, 0);
panelDecorationL = PanelSpaceL.shift(18 * 2, 0);
panelDecorationR = PanelSpaceR.shift(18 * 2, 0);
buttons.metal();
beamL = BeamLeft.shift(0, BeamLeft.h);
beamR = BeamRight.shift(0, BeamRight.h);
beamC = BeamCenter.shift(0, BeamCenter.h);
}
@Override
public void error(String message) {
toolInfo.setCaption(I18n.translateToLocal("gui.error"));
toolInfo.setText(message);
traitInfo.setCaption(null);
traitInfo.setText();
}
@Override
public void warning(String message) {
toolInfo.setCaption(I18n.translateToLocal("gui.warning"));
toolInfo.setText(message);
traitInfo.setCaption(null);
traitInfo.setText();
}
}