package pneumaticCraft.client.gui;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.I18n;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;
import pneumaticCraft.PneumaticCraft;
import pneumaticCraft.api.client.IGuiAnimatedStat;
import pneumaticCraft.api.tileentity.IHeatExchanger;
import pneumaticCraft.client.gui.widget.GuiAnimatedStat;
import pneumaticCraft.client.gui.widget.IGuiWidget;
import pneumaticCraft.client.gui.widget.IWidgetListener;
import pneumaticCraft.client.gui.widget.WidgetLabel;
import pneumaticCraft.client.gui.widget.WidgetTextField;
import pneumaticCraft.common.block.Blockss;
import pneumaticCraft.common.network.NetworkHandler;
import pneumaticCraft.common.network.PacketGuiButton;
import pneumaticCraft.common.tileentity.IMinWorkingPressure;
import pneumaticCraft.common.tileentity.IRedstoneControl;
import pneumaticCraft.common.tileentity.IRedstoneControlled;
import pneumaticCraft.common.tileentity.TileEntityBase;
import pneumaticCraft.common.tileentity.TileEntityPneumaticBase;
import pneumaticCraft.common.util.PneumaticCraftUtils;
import pneumaticCraft.lib.ModIds;
import pneumaticCraft.lib.Textures;
import codechicken.nei.VisiblityData;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.TaggedInventoryArea;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Optional;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
@Optional.Interface(iface = "codechicken.nei.api.INEIGuiHandler", modid = ModIds.NEI)
public class GuiPneumaticContainerBase<Tile extends TileEntityBase> extends GuiContainer implements INEIGuiHandler,
IWidgetListener{
public final Tile te;
private final ResourceLocation guiTexture;
/**
* Any GuiAnimatedStat added to this list will be tracked for mouseclicks, tooltip renders, rendering,updating (resolution and expansion).
*/
protected final List<IGuiWidget> widgets = new ArrayList<IGuiWidget>();
private IGuiAnimatedStat lastLeftStat, lastRightStat;
private GuiAnimatedStat pressureStat;
protected GuiAnimatedStat problemTab;
private GuiAnimatedStat redstoneTab;
protected GuiButtonSpecial redstoneButton;
public GuiPneumaticContainerBase(Container par1Container, Tile te, String guiTexture){
super(par1Container);
this.te = te;
this.guiTexture = guiTexture != null ? new ResourceLocation(guiTexture) : null;
}
protected GuiAnimatedStat addAnimatedStat(String title, ItemStack icon, int color, boolean leftSided){
int xStart = (width - xSize) / 2;
int yStart = (height - ySize) / 2;
GuiAnimatedStat stat = new GuiAnimatedStat(this, title, icon, xStart + (leftSided ? 0 : xSize), leftSided && lastLeftStat != null || !leftSided && lastRightStat != null ? 3 : yStart + 5, color, leftSided ? lastLeftStat : lastRightStat, leftSided);
addWidget(stat);
if(leftSided) {
lastLeftStat = stat;
} else {
lastRightStat = stat;
}
return stat;
}
protected GuiAnimatedStat addAnimatedStat(String title, String icon, int color, boolean leftSided){
int xStart = (width - xSize) / 2;
int yStart = (height - ySize) / 2;
GuiAnimatedStat stat = new GuiAnimatedStat(this, title, icon, xStart + (leftSided ? 0 : xSize), leftSided && lastLeftStat != null || !leftSided && lastRightStat != null ? 3 : yStart + 5, color, leftSided ? lastLeftStat : lastRightStat, leftSided);
addWidget(stat);
if(leftSided) {
lastLeftStat = stat;
} else {
lastRightStat = stat;
}
return stat;
}
protected void addWidget(IGuiWidget widget){
widgets.add(widget);
widget.setListener(this);
}
protected void addWidgets(Iterable<IGuiWidget> widgets){
for(IGuiWidget widget : widgets) {
addWidget(widget);
}
}
protected void addLabel(String text, int x, int y){
addWidget(new WidgetLabel(x, y, text));
}
protected void removeWidget(IGuiWidget widget){
widgets.remove(widget);
}
@Override
public void initGui(){
super.initGui();
lastLeftStat = lastRightStat = null;
if(shouldAddPressureTab() && te instanceof TileEntityPneumaticBase) {
pressureStat = this.addAnimatedStat("gui.tab.pressure", new ItemStack(Blockss.pressureTube), 0xFF00AA00, false);
}
if(shouldAddProblemTab()) {
problemTab = addAnimatedStat("gui.tab.problems", Textures.GUI_PROBLEMS_TEXTURE, 0xFFFF0000, false);
}
if(shouldAddRedstoneTab() && te instanceof IRedstoneControl) {
redstoneTab = addAnimatedStat("gui.tab.redstoneBehaviour", new ItemStack(Items.redstone), 0xFFCC0000, true);
List<String> curInfo = new ArrayList<String>();
curInfo.add(I18n.format(getRedstoneString()));
for(int i = 0; i < 3; i++)
curInfo.add(" ");// create some space for the button
redstoneTab.setTextWithoutCuttingString(curInfo);
Rectangle buttonRect = redstoneTab.getButtonScaledRectangle(-170, 24, 170, 20);
redstoneButton = new GuiButtonSpecial(0, buttonRect.x, buttonRect.y, buttonRect.width, buttonRect.height, "-");//getButtonFromRectangle(0, buttonRect, "-");
redstoneTab.addWidget(redstoneButton);
}
if(te instanceof IInventory) {
if(shouldAddInfoTab()) {
String info = "gui.tab.info." + ((IInventory)te).getInventoryName();
String translatedInfo = I18n.format(info);
if(!translatedInfo.equals(info)) {
addInfoTab(translatedInfo);
}
}
if(te instanceof IHeatExchanger) {
addAnimatedStat("gui.tab.info.heat.title", new ItemStack(Blocks.fire), 0xFFFF5500, false).setText("gui.tab.info.heat");
}
if(shouldAddUpgradeTab()) {
String upgrades = "gui.tab.upgrades." + ((IInventory)te).getInventoryName();
String translatedUpgrades = I18n.format(upgrades);
List<String> upgradeText = new ArrayList<String>();
if(te instanceof TileEntityPneumaticBase) {
upgradeText.add("gui.tab.upgrades.volume");
upgradeText.add("gui.tab.upgrades.security");
}
if(te instanceof IHeatExchanger) {
upgradeText.add("gui.tab.upgrades.volumeCapacity");
}
if(!translatedUpgrades.equals(upgrades)) upgradeText.add(upgrades);
if(upgradeText.size() > 0) addAnimatedStat("gui.tab.upgrades", Textures.GUI_UPGRADES_LOCATION, 0xFF0000FF, true).setText(upgradeText);
}
}
}
protected void addInfoTab(String info){
if(!Loader.isModLoaded(ModIds.IGWMOD)) info += " \\n \\n" + I18n.format("gui.tab.info.assistIGW");
addAnimatedStat("gui.tab.info", Textures.GUI_INFO_LOCATION, 0xFF8888FF, true).setText(info);
}
protected boolean shouldAddRedstoneTab(){
return true;
}
protected boolean shouldAddPressureTab(){
return true;
}
protected boolean shouldAddUpgradeTab(){
return true;
}
protected boolean shouldAddInfoTab(){
return true;
}
protected boolean shouldAddProblemTab(){
return true;
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int i, int j){
if(shouldDrawBackground()) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
bindGuiTexture();
int xStart = (width - xSize) / 2;
int yStart = (height - ySize) / 2;
drawTexturedModalRect(xStart, yStart, 0, 0, xSize, ySize);
}
GL11.glColor4d(1, 1, 1, 1);
GL11.glDisable(GL11.GL_LIGHTING);
for(IGuiWidget widget : widgets) {
widget.render(i, j, partialTicks);
}
for(IGuiWidget widget : widgets) {
widget.postRender(i, j, partialTicks);
}
if(pressureStat != null) {
TileEntityPneumaticBase pneu = (TileEntityPneumaticBase)te;
Point gaugeLocation = getGaugeLocation();
if(gaugeLocation != null) GuiUtils.drawPressureGauge(fontRendererObj, -1, pneu.CRITICAL_PRESSURE, pneu.DANGER_PRESSURE, te instanceof IMinWorkingPressure ? ((IMinWorkingPressure)te).getMinWorkingPressure() : -1, pneu.getPressure(ForgeDirection.UNKNOWN), gaugeLocation.x, gaugeLocation.y, zLevel);
}
}
protected boolean shouldDrawBackground(){
return true;
}
protected void bindGuiTexture(){
if(guiTexture != null) {
mc.getTextureManager().bindTexture(guiTexture);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
}
protected Point getGaugeLocation(){
int xStart = (width - xSize) / 2;
int yStart = (height - ySize) / 2;
return new Point(xStart + xSize * 3 / 4, yStart + ySize * 1 / 4 + 4);
}
@Override
protected void drawGuiContainerForegroundLayer(int x, int y){
if(getInvNameOffset() != null && te instanceof IInventory) {
IInventory inv = (IInventory)te;
String containerName = inv.hasCustomInventoryName() ? inv.getInventoryName() : StatCollector.translateToLocal(inv.getInventoryName() + ".name");
fontRendererObj.drawString(containerName, xSize / 2 - fontRendererObj.getStringWidth(containerName) / 2 + getInvNameOffset().x, 6 + getInvNameOffset().y, 4210752);
}
if(getInvTextOffset() != null) fontRendererObj.drawString(StatCollector.translateToLocal("container.inventory"), 8 + getInvTextOffset().x, ySize - 94 + getInvTextOffset().y, 4210752);
}
protected Point getInvNameOffset(){
return new Point(0, 0);
}
protected Point getInvTextOffset(){
return new Point(0, 0);
}
@Override
public void drawScreen(int x, int y, float partialTick){
super.drawScreen(x, y, partialTick);
List<String> tooltip = new ArrayList<String>();
for(Object obj : buttonList) {
if(obj instanceof GuiButtonSpecial) {
GuiButtonSpecial button = (GuiButtonSpecial)obj;
if(button.xPosition < x && button.xPosition + button.getWidth() > x && button.yPosition < y && button.yPosition + button.getHeight() > y) {
button.getTooltip(tooltip);
}
}
}
GL11.glColor4d(1, 1, 1, 1);
GL11.glDisable(GL11.GL_LIGHTING);
for(IGuiWidget widget : widgets) {
if(widget.getBounds().contains(x, y)) widget.addTooltip(x, y, tooltip, PneumaticCraft.proxy.isSneakingInGui());
}
if(tooltip.size() > 0) {
drawHoveringString(tooltip, x, y, fontRendererObj);
tooltip.clear();
}
/* TODO boolean shift = PneumaticCraft.proxy.isSneakingInGui();
for(IGuiWidget widget : widgets) {
if(widget.getBounds().contains(x, y)) widget.addTooltip(tooltip, shift);
}
if(!tooltip.isEmpty()) {
List<String> localizedTooltip = new ArrayList<String>();
for(String line : tooltip) {
String localizedLine = I18n.format(line);
String[] lines = WordUtils.wrap(localizedLine, 50).split(System.getProperty("line.separator"));
for(String locLine : lines) {
localizedTooltip.add(locLine);
}
}
drawHoveringText(localizedTooltip, x, y, fontRendererObj);
}*/
}
@Override
public void updateScreen(){
super.updateScreen();
for(IGuiWidget widget : widgets)
widget.update();
if(pressureStat != null) {
List<String> curInfo = new ArrayList<String>();
addPressureStatInfo(curInfo);
pressureStat.setText(curInfo);
}
if(problemTab != null) {
List<String> curInfo = new ArrayList<String>();
addProblems(curInfo);
if(curInfo.size() == 0) {
curInfo.add("gui.tab.problems.noProblems");
}
problemTab.setText(curInfo);
}
if(redstoneTab != null) {
redstoneButton.displayString = I18n.format(getRedstoneButtonText(((IRedstoneControl)te).getRedstoneMode()));
}
}
@Override
protected void actionPerformed(GuiButton button){
sendPacketToServer(button.id);
}
public String getRedstoneButtonText(int mode){
switch(mode){
case 0:
return "gui.tab.redstoneBehaviour.button.anySignal";
case 1:
return "gui.tab.redstoneBehaviour.button.highSignal";
case 2:
return "gui.tab.redstoneBehaviour.button.lowSignal";
}
return "<ERROR>";
}
public String getRedstoneString(){
return te instanceof IRedstoneControlled ? "gui.tab.redstoneBehaviour.enableOn" : "gui.tab.redstoneBehaviour.emitRedstoneWhen";
}
protected void addPressureStatInfo(List<String> pressureStatText){
TileEntityPneumaticBase pneumaticTile = (TileEntityPneumaticBase)te;
pressureStatText.add("\u00a77Current Pressure:");
pressureStatText.add("\u00a70" + PneumaticCraftUtils.roundNumberTo(pneumaticTile.getPressure(ForgeDirection.UNKNOWN), 1) + " bar.");
pressureStatText.add("\u00a77Current Air:");
pressureStatText.add("\u00a70" + (double)Math.round(pneumaticTile.currentAir + pneumaticTile.volume) + " mL.");
pressureStatText.add("\u00a77Volume:");
pressureStatText.add("\u00a70" + (double)Math.round(pneumaticTile.DEFAULT_VOLUME) + " mL.");
float volumeLeft = pneumaticTile.volume - pneumaticTile.DEFAULT_VOLUME;
if(volumeLeft > 0) {
pressureStatText.add("\u00a70" + (double)Math.round(volumeLeft) + " mL. (Volume Upgrades)");
pressureStatText.add("\u00a70--------+");
pressureStatText.add("\u00a70" + (double)Math.round(pneumaticTile.volume) + " mL.");
}
}
protected void addProblems(List<String> curInfo){
if(te instanceof IRedstoneControlled && !te.redstoneAllows()) {
IRedstoneControlled redstoneControlled = (IRedstoneControlled)te;
curInfo.add("gui.tab.problems.redstoneDisallows");
if(redstoneControlled.getRedstoneMode() == 1) {
curInfo.add("gui.tab.problems.provideRedstone");
} else {
curInfo.add("gui.tab.problems.removeRedstone");
}
}
if(te instanceof IMinWorkingPressure) {
IMinWorkingPressure minWork = (IMinWorkingPressure)te;
if(((TileEntityPneumaticBase)te).getPressure(ForgeDirection.UNKNOWN) < minWork.getMinWorkingPressure()) {
curInfo.add("gui.tab.problems.notEnoughPressure");
curInfo.add(I18n.format("gui.tab.problems.applyPressure", minWork.getMinWorkingPressure()));
}
}
}
@Override
protected void mouseClicked(int par1, int par2, int par3){
super.mouseClicked(par1, par2, par3);
for(IGuiWidget widget : widgets) {
if(widget.getBounds().contains(par1, par2)) widget.onMouseClicked(par1, par2, par3);
else widget.onMouseClickedOutsideBounds(par1, par2, par3);
}
}
@Override
public void actionPerformed(IGuiWidget widget){
if(widget instanceof IGuiAnimatedStat) {
boolean leftSided = ((IGuiAnimatedStat)widget).isLeftSided();
for(IGuiWidget w : widgets) {
if(w instanceof IGuiAnimatedStat) {
IGuiAnimatedStat stat = (IGuiAnimatedStat)w;
if(widget != stat && stat.isLeftSided() == leftSided) {//when the stat is on the same side, close it.
stat.closeWindow();
}
}
}
}
sendPacketToServer(widget.getID());
}
protected void sendPacketToServer(int id){
NetworkHandler.sendToServer(new PacketGuiButton(id));
}
@Override
public void handleMouseInput(){
super.handleMouseInput();
for(IGuiWidget widget : widgets) {
widget.handleMouseInput();
}
}
@Override
protected void keyTyped(char key, int keyCode){
for(IGuiWidget widget : widgets) {
if(widget.onKey(key, keyCode)) return;
}
super.keyTyped(key, keyCode);
}
@Override
public void setWorldAndResolution(Minecraft par1Minecraft, int par2, int par3){
widgets.clear();
super.setWorldAndResolution(par1Minecraft, par2, par3);
}
public void drawHoveringString(List<String> text, int x, int y, FontRenderer fontRenderer){
drawHoveringText(text, x, y, fontRenderer);
}
public static void drawTexture(String texture, int x, int y){
Minecraft.getMinecraft().getTextureManager().bindTexture(GuiUtils.getResourceLocation(texture));
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(x, y + 16, 0, 0.0, 1.0);
tessellator.addVertexWithUV(x + 16, y + 16, 0, 1.0, 1.0);
tessellator.addVertexWithUV(x + 16, y, 0, 1.0, 0.0);
tessellator.addVertexWithUV(x, y, 0, 0.0, 0.0);
tessellator.draw();
// this.drawTexturedModalRect(x, y, 0, 0, 16, 16);
}
public GuiButtonSpecial getButtonFromRectangle(int buttonID, Rectangle buttonSize, String buttonText){
return new GuiButtonSpecial(buttonID, buttonSize.x, buttonSize.y, buttonSize.width, buttonSize.height, buttonText);
}
public GuiButtonSpecial getInvisibleButtonFromRectangle(int buttonID, Rectangle buttonSize){
return new GuiButtonSpecial(buttonID, buttonSize.x, buttonSize.y, buttonSize.width, buttonSize.height, "");
}
public WidgetTextField getTextFieldFromRectangle(Rectangle textFieldSize){
return new WidgetTextField(fontRendererObj, textFieldSize.x, textFieldSize.y, textFieldSize.width, textFieldSize.height);
}
public int getGuiLeft(){
return guiLeft;
}
public int getGuiTop(){
return guiTop;
}
//-----------NEI support
@Override
@Optional.Method(modid = ModIds.NEI)
public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility){
for(IGuiWidget w : widgets) {
if(w instanceof IGuiAnimatedStat) {
IGuiAnimatedStat stat = (IGuiAnimatedStat)w;
if(stat.isLeftSided()) {
if(stat.getWidth() > 20) {
currentVisibility.showUtilityButtons = false;
currentVisibility.showStateButtons = false;
}
} else {
if(stat.getAffectedY() < 10) {
currentVisibility.showWidgets = false;
}
}
}
}
return currentVisibility;
}
@Override
public Iterable<Integer> getItemSpawnSlots(GuiContainer gui, ItemStack item){
return new ArrayList<Integer>();
}
/**
* @return A list of TaggedInventoryAreas that will be used with the savestates.
*/
@Override
@Optional.Method(modid = ModIds.NEI)
public List<TaggedInventoryArea> getInventoryAreas(GuiContainer gui){
return null;
}
/**
* Handles clicks while an itemstack has been dragged from the item panel. Use this to set configurable slots and the like.
* Changes made to the stackSize of the dragged stack will be kept
* @param gui The current gui instance
* @param mousex The x position of the mouse
* @param mousey The y position of the mouse
* @param draggedStack The stack being dragged from the item panel
* @param button The button presed
* @return True if the drag n drop was handled. False to resume processing through other routes. The held stack will be deleted if draggedStack.stackSize == 0
*/
@Override
public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button){
return false;
}
/**
* Used to prevent the item panel from drawing on top of other gui elements.
* @param x The x coordinate of the rectangle bounding the slot
* @param y The y coordinate of the rectangle bounding the slot
* @param w The w coordinate of the rectangle bounding the slot
* @param h The h coordinate of the rectangle bounding the slot
* @return true if the item panel slot within the specified rectangle should not be rendered.
*/
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h){
for(IGuiWidget widget : widgets) {
if(widget instanceof IGuiAnimatedStat) {
IGuiAnimatedStat stat = (IGuiAnimatedStat)widget;
if(stat.getBounds().intersects(new Rectangle(x, y, w, h))) return true;
}
}
return false;
}
@Override
public void onKeyTyped(IGuiWidget widget){
}
protected void refreshScreen(){
ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft(), Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight);
int i = scaledresolution.getScaledWidth();
int j = scaledresolution.getScaledHeight();
setWorldAndResolution(Minecraft.getMinecraft(), i, j);
for(IGuiWidget widget : widgets) {
if(widget instanceof GuiAnimatedStat) {
widget.update();
}
}
}
}