package net.minecraft.client.gui;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.minecraft.client.gui.stream.GuiTwitchUserMode;
import net.minecraft.event.ClickEvent;
import net.minecraft.event.HoverEvent;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.play.client.C14PacketTabComplete;
import net.minecraft.stats.Achievement;
import net.minecraft.stats.StatBase;
import net.minecraft.stats.StatList;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import tv.twitch.chat.ChatUserInfo;
@SideOnly(Side.CLIENT)
public class GuiChat extends GuiScreen implements GuiYesNoCallback
{
private static final Set supportedProtocols = Sets.newHashSet(new String[] {"http", "https"});
private static final Logger logger = LogManager.getLogger();
private String historyBuffer = "";
/**
* keeps position of which chat message you will select when you press up, (does not increase for duplicated
* messages sent immediately after each other)
*/
private int sentHistoryCursor = -1;
private boolean playerNamesFound;
private boolean waitingOnAutocomplete;
private int autocompleteIndex;
private List foundPlayerNames = new ArrayList();
/** used to pass around the URI to various dialogues and to the host os */
private URI clickedURI;
/** Chat entry field */
protected GuiTextField inputField;
/** is the text that appears when you press the chat key and the input box appears pre-filled */
private String defaultInputFieldText = "";
private static final String __OBFID = "CL_00000682";
public GuiChat() {}
public GuiChat(String p_i1024_1_)
{
this.defaultInputFieldText = p_i1024_1_;
}
/**
* Adds the buttons (and other controls) to the screen in question.
*/
public void initGui()
{
Keyboard.enableRepeatEvents(true);
this.sentHistoryCursor = this.mc.ingameGUI.getChatGUI().getSentMessages().size();
this.inputField = new GuiTextField(this.fontRendererObj, 4, this.height - 12, this.width - 4, 12);
this.inputField.setMaxStringLength(100);
this.inputField.setEnableBackgroundDrawing(false);
this.inputField.setFocused(true);
this.inputField.setText(this.defaultInputFieldText);
this.inputField.setCanLoseFocus(false);
}
/**
* Called when the screen is unloaded. Used to disable keyboard repeat events
*/
public void onGuiClosed()
{
Keyboard.enableRepeatEvents(false);
this.mc.ingameGUI.getChatGUI().resetScroll();
}
/**
* Called from the main game loop to update the screen.
*/
public void updateScreen()
{
this.inputField.updateCursorCounter();
}
/**
* Fired when a key is typed (except F11 who toggle full screen). This is the equivalent of
* KeyListener.keyTyped(KeyEvent e). Args : character (character on the key), keyCode (lwjgl Keyboard key code)
*/
protected void keyTyped(char typedChar, int keyCode)
{
this.waitingOnAutocomplete = false;
if (keyCode == 15)
{
this.autocompletePlayerNames();
}
else
{
this.playerNamesFound = false;
}
if (keyCode == 1)
{
this.mc.displayGuiScreen((GuiScreen)null);
}
else if (keyCode != 28 && keyCode != 156)
{
if (keyCode == 200)
{
this.getSentHistory(-1);
}
else if (keyCode == 208)
{
this.getSentHistory(1);
}
else if (keyCode == 201)
{
this.mc.ingameGUI.getChatGUI().scroll(this.mc.ingameGUI.getChatGUI().getLineCount() - 1);
}
else if (keyCode == 209)
{
this.mc.ingameGUI.getChatGUI().scroll(-this.mc.ingameGUI.getChatGUI().getLineCount() + 1);
}
else
{
this.inputField.textboxKeyTyped(typedChar, keyCode);
}
}
else
{
String s = this.inputField.getText().trim();
if (s.length() > 0)
{
this.submitChatMessage(s);
}
this.mc.displayGuiScreen((GuiScreen)null);
}
}
public void submitChatMessage(String p_146403_1_)
{
this.mc.ingameGUI.getChatGUI().addToSentMessages(p_146403_1_);
if (net.minecraftforge.client.ClientCommandHandler.instance.executeCommand(mc.thePlayer, p_146403_1_) != 0) return;
this.mc.thePlayer.sendChatMessage(p_146403_1_);
}
/**
* Handles mouse input.
*/
public void handleMouseInput()
{
super.handleMouseInput();
int i = Mouse.getEventDWheel();
if (i != 0)
{
if (i > 1)
{
i = 1;
}
if (i < -1)
{
i = -1;
}
if (!isShiftKeyDown())
{
i *= 7;
}
this.mc.ingameGUI.getChatGUI().scroll(i);
}
}
/**
* Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton
*/
protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
{
if (mouseButton == 0 && this.mc.gameSettings.chatLinks)
{
IChatComponent ichatcomponent = this.mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
if (ichatcomponent != null)
{
ClickEvent clickevent = ichatcomponent.getChatStyle().getChatClickEvent();
if (clickevent != null)
{
if (isShiftKeyDown())
{
this.inputField.writeText(ichatcomponent.getUnformattedTextForChat());
}
else
{
URI uri;
if (clickevent.getAction() == ClickEvent.Action.OPEN_URL)
{
try
{
uri = new URI(clickevent.getValue());
if (!supportedProtocols.contains(uri.getScheme().toLowerCase()))
{
throw new URISyntaxException(clickevent.getValue(), "Unsupported protocol: " + uri.getScheme().toLowerCase());
}
if (this.mc.gameSettings.chatLinksPrompt)
{
this.clickedURI = uri;
this.mc.displayGuiScreen(new GuiConfirmOpenLink(this, clickevent.getValue(), 0, false));
}
else
{
this.openLink(uri);
}
}
catch (URISyntaxException urisyntaxexception)
{
logger.error("Can\'t open url for " + clickevent, urisyntaxexception);
}
}
else if (clickevent.getAction() == ClickEvent.Action.OPEN_FILE)
{
uri = (new File(clickevent.getValue())).toURI();
this.openLink(uri);
}
else if (clickevent.getAction() == ClickEvent.Action.SUGGEST_COMMAND)
{
this.inputField.setText(clickevent.getValue());
}
else if (clickevent.getAction() == ClickEvent.Action.RUN_COMMAND)
{
this.submitChatMessage(clickevent.getValue());
}
else if (clickevent.getAction() == ClickEvent.Action.TWITCH_USER_INFO)
{
ChatUserInfo chatuserinfo = this.mc.getTwitchStream().func_152926_a(clickevent.getValue());
if (chatuserinfo != null)
{
this.mc.displayGuiScreen(new GuiTwitchUserMode(this.mc.getTwitchStream(), chatuserinfo));
}
else
{
logger.error("Tried to handle twitch user but couldn\'t find them!");
}
}
else
{
logger.error("Don\'t know how to handle " + clickevent);
}
}
return;
}
}
}
this.inputField.mouseClicked(mouseX, mouseY, mouseButton);
super.mouseClicked(mouseX, mouseY, mouseButton);
}
public void confirmClicked(boolean result, int id)
{
if (id == 0)
{
if (result)
{
this.openLink(this.clickedURI);
}
this.clickedURI = null;
this.mc.displayGuiScreen(this);
}
}
private void openLink(URI p_146407_1_)
{
try
{
Class oclass = Class.forName("java.awt.Desktop");
Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]);
oclass.getMethod("browse", new Class[] {URI.class}).invoke(object, new Object[] {p_146407_1_});
}
catch (Throwable throwable)
{
logger.error("Couldn\'t open link", throwable);
}
}
public void autocompletePlayerNames()
{
String s1;
if (this.playerNamesFound)
{
this.inputField.deleteFromCursor(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition());
if (this.autocompleteIndex >= this.foundPlayerNames.size())
{
this.autocompleteIndex = 0;
}
}
else
{
int i = this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false);
this.foundPlayerNames.clear();
this.autocompleteIndex = 0;
String s = this.inputField.getText().substring(i).toLowerCase();
s1 = this.inputField.getText().substring(0, this.inputField.getCursorPosition());
this.sendAutocompleteRequest(s1, s);
if (this.foundPlayerNames.isEmpty())
{
return;
}
this.playerNamesFound = true;
this.inputField.deleteFromCursor(i - this.inputField.getCursorPosition());
}
if (this.foundPlayerNames.size() > 1)
{
StringBuilder stringbuilder = new StringBuilder();
for (Iterator iterator = this.foundPlayerNames.iterator(); iterator.hasNext(); stringbuilder.append(s1))
{
s1 = (String)iterator.next();
if (stringbuilder.length() > 0)
{
stringbuilder.append(", ");
}
}
this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText(stringbuilder.toString()), 1);
}
this.inputField.writeText(EnumChatFormatting.getTextWithoutFormattingCodes((String)this.foundPlayerNames.get(this.autocompleteIndex++)));
}
private void sendAutocompleteRequest(String p_146405_1_, String p_146405_2_)
{
if (p_146405_1_.length() >= 1)
{
net.minecraftforge.client.ClientCommandHandler.instance.autoComplete(p_146405_1_, p_146405_2_);
this.mc.thePlayer.sendQueue.addToSendQueue(new C14PacketTabComplete(p_146405_1_));
this.waitingOnAutocomplete = true;
}
}
/**
* input is relative and is applied directly to the sentHistoryCursor so -1 is the previous message, 1 is the next
* message from the current cursor position
*/
public void getSentHistory(int p_146402_1_)
{
int j = this.sentHistoryCursor + p_146402_1_;
int k = this.mc.ingameGUI.getChatGUI().getSentMessages().size();
if (j < 0)
{
j = 0;
}
if (j > k)
{
j = k;
}
if (j != this.sentHistoryCursor)
{
if (j == k)
{
this.sentHistoryCursor = k;
this.inputField.setText(this.historyBuffer);
}
else
{
if (this.sentHistoryCursor == k)
{
this.historyBuffer = this.inputField.getText();
}
this.inputField.setText((String)this.mc.ingameGUI.getChatGUI().getSentMessages().get(j));
this.sentHistoryCursor = j;
}
}
}
/**
* Draws the screen and all the components in it. Args : mouseX, mouseY, renderPartialTicks
*/
public void drawScreen(int mouseX, int mouseY, float partialTicks)
{
drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE);
this.inputField.drawTextBox();
IChatComponent ichatcomponent = this.mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY());
if (ichatcomponent != null && ichatcomponent.getChatStyle().getChatHoverEvent() != null)
{
HoverEvent hoverevent = ichatcomponent.getChatStyle().getChatHoverEvent();
if (hoverevent.getAction() == HoverEvent.Action.SHOW_ITEM)
{
ItemStack itemstack = null;
try
{
NBTBase nbtbase = JsonToNBT.func_150315_a(hoverevent.getValue().getUnformattedText());
if (nbtbase != null && nbtbase instanceof NBTTagCompound)
{
itemstack = ItemStack.loadItemStackFromNBT((NBTTagCompound)nbtbase);
}
}
catch (NBTException nbtexception)
{
;
}
if (itemstack != null)
{
this.renderToolTip(itemstack, mouseX, mouseY);
}
else
{
this.drawCreativeTabHoveringText(EnumChatFormatting.RED + "Invalid Item!", mouseX, mouseY);
}
}
else if (hoverevent.getAction() == HoverEvent.Action.SHOW_TEXT)
{
this.drawHoveringText(Splitter.on("\n").splitToList(hoverevent.getValue().getFormattedText()), mouseX, mouseY);
}
else if (hoverevent.getAction() == HoverEvent.Action.SHOW_ACHIEVEMENT)
{
StatBase statbase = StatList.getOneShotStat(hoverevent.getValue().getUnformattedText());
if (statbase != null)
{
IChatComponent ichatcomponent1 = statbase.getStatName();
ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("stats.tooltip.type." + (statbase.isAchievement() ? "achievement" : "statistic"), new Object[0]);
chatcomponenttranslation.getChatStyle().setItalic(Boolean.valueOf(true));
String s = statbase instanceof Achievement ? ((Achievement)statbase).getDescription() : null;
ArrayList arraylist = Lists.newArrayList(new String[] {ichatcomponent1.getFormattedText(), chatcomponenttranslation.getFormattedText()});
if (s != null)
{
arraylist.addAll(this.fontRendererObj.listFormattedStringToWidth(s, 150));
}
this.drawHoveringText(arraylist, mouseX, mouseY);
}
else
{
this.drawCreativeTabHoveringText(EnumChatFormatting.RED + "Invalid statistic/achievement!", mouseX, mouseY);
}
}
GL11.glDisable(GL11.GL_LIGHTING);
}
super.drawScreen(mouseX, mouseY, partialTicks);
}
public void onAutocompleteResponse(String[] p_146406_1_)
{
if (this.waitingOnAutocomplete)
{
this.playerNamesFound = false;
this.foundPlayerNames.clear();
String[] astring1 = p_146406_1_;
int i = p_146406_1_.length;
String[] complete = net.minecraftforge.client.ClientCommandHandler.instance.latestAutoComplete;
if (complete != null)
{
astring1 = com.google.common.collect.ObjectArrays.concat(complete, astring1, String.class);
i = astring1.length;
}
for (int j = 0; j < i; ++j)
{
String s = astring1[j];
if (s.length() > 0)
{
this.foundPlayerNames.add(s);
}
}
String s1 = this.inputField.getText().substring(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false));
String s2 = StringUtils.getCommonPrefix(p_146406_1_);
if (s2.length() > 0 && !s1.equalsIgnoreCase(s2))
{
this.inputField.deleteFromCursor(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition());
this.inputField.writeText(s2);
}
else if (this.foundPlayerNames.size() > 0)
{
this.playerNamesFound = true;
this.autocompletePlayerNames();
}
}
}
/**
* Returns true if this GUI should pause the game when it is displayed in single-player
*/
public boolean doesGuiPauseGame()
{
return false;
}
}