001    package net.minecraft.client.gui;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.SideOnly;
005    import java.net.URI;
006    import java.util.ArrayList;
007    import java.util.Iterator;
008    import java.util.List;
009    import net.minecraft.network.packet.Packet203AutoComplete;
010    import org.lwjgl.input.Keyboard;
011    import org.lwjgl.input.Mouse;
012    
013    @SideOnly(Side.CLIENT)
014    public class GuiChat extends GuiScreen
015    {
016        private String field_73898_b = "";
017    
018        /**
019         * keeps position of which chat message you will select when you press up, (does not increase for duplicated
020         * messages sent immediately after each other)
021         */
022        private int sentHistoryCursor = -1;
023        private boolean field_73897_d = false;
024        private boolean field_73905_m = false;
025        private int field_73903_n = 0;
026        private List field_73904_o = new ArrayList();
027    
028        /** used to pass around the URI to various dialogues and to the host os */
029        private URI clickedURI = null;
030    
031        /** Chat entry field */
032        protected GuiTextField inputField;
033    
034        /**
035         * is the text that appears when you press the chat key and the input box appears pre-filled
036         */
037        private String defaultInputFieldText = "";
038    
039        public GuiChat() {}
040    
041        public GuiChat(String par1Str)
042        {
043            this.defaultInputFieldText = par1Str;
044        }
045    
046        /**
047         * Adds the buttons (and other controls) to the screen in question.
048         */
049        public void initGui()
050        {
051            Keyboard.enableRepeatEvents(true);
052            this.sentHistoryCursor = this.mc.ingameGUI.getChatGUI().getSentMessages().size();
053            this.inputField = new GuiTextField(this.fontRenderer, 4, this.height - 12, this.width - 4, 12);
054            this.inputField.setMaxStringLength(100);
055            this.inputField.setEnableBackgroundDrawing(false);
056            this.inputField.setFocused(true);
057            this.inputField.setText(this.defaultInputFieldText);
058            this.inputField.setCanLoseFocus(false);
059        }
060    
061        /**
062         * Called when the screen is unloaded. Used to disable keyboard repeat events
063         */
064        public void onGuiClosed()
065        {
066            Keyboard.enableRepeatEvents(false);
067            this.mc.ingameGUI.getChatGUI().resetScroll();
068        }
069    
070        /**
071         * Called from the main game loop to update the screen.
072         */
073        public void updateScreen()
074        {
075            this.inputField.updateCursorCounter();
076        }
077    
078        /**
079         * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
080         */
081        protected void keyTyped(char par1, int par2)
082        {
083            this.field_73905_m = false;
084    
085            if (par2 == 15)
086            {
087                this.completePlayerName();
088            }
089            else
090            {
091                this.field_73897_d = false;
092            }
093    
094            if (par2 == 1)
095            {
096                this.mc.displayGuiScreen((GuiScreen)null);
097            }
098            else if (par2 == 28)
099            {
100                String var3 = this.inputField.getText().trim();
101    
102                if (var3.length() > 0)
103                {
104                    this.mc.ingameGUI.getChatGUI().addToSentMessages(var3);
105    
106                    if (!this.mc.handleClientCommand(var3))
107                    {
108                        this.mc.thePlayer.sendChatMessage(var3);
109                    }
110                }
111    
112                this.mc.displayGuiScreen((GuiScreen)null);
113            }
114            else if (par2 == 200)
115            {
116                this.getSentHistory(-1);
117            }
118            else if (par2 == 208)
119            {
120                this.getSentHistory(1);
121            }
122            else if (par2 == 201)
123            {
124                this.mc.ingameGUI.getChatGUI().scroll(19);
125            }
126            else if (par2 == 209)
127            {
128                this.mc.ingameGUI.getChatGUI().scroll(-19);
129            }
130            else
131            {
132                this.inputField.textboxKeyTyped(par1, par2);
133            }
134        }
135    
136        /**
137         * Handles mouse input.
138         */
139        public void handleMouseInput()
140        {
141            super.handleMouseInput();
142            int var1 = Mouse.getEventDWheel();
143    
144            if (var1 != 0)
145            {
146                if (var1 > 1)
147                {
148                    var1 = 1;
149                }
150    
151                if (var1 < -1)
152                {
153                    var1 = -1;
154                }
155    
156                if (!isShiftKeyDown())
157                {
158                    var1 *= 7;
159                }
160    
161                this.mc.ingameGUI.getChatGUI().scroll(var1);
162            }
163        }
164    
165        /**
166         * Called when the mouse is clicked.
167         */
168        protected void mouseClicked(int par1, int par2, int par3)
169        {
170            if (par3 == 0 && this.mc.gameSettings.chatLinks)
171            {
172                ChatClickData var4 = this.mc.ingameGUI.getChatGUI().func_73766_a(Mouse.getX(), Mouse.getY());
173    
174                if (var4 != null)
175                {
176                    URI var5 = var4.getURI();
177    
178                    if (var5 != null)
179                    {
180                        if (this.mc.gameSettings.chatLinksPrompt)
181                        {
182                            this.clickedURI = var5;
183                            this.mc.displayGuiScreen(new GuiConfirmOpenLink(this, var4.getClickedUrl(), 0));
184                        }
185                        else
186                        {
187                            this.func_73896_a(var5);
188                        }
189    
190                        return;
191                    }
192                }
193            }
194    
195            this.inputField.mouseClicked(par1, par2, par3);
196            super.mouseClicked(par1, par2, par3);
197        }
198    
199        public void confirmClicked(boolean par1, int par2)
200        {
201            if (par2 == 0)
202            {
203                if (par1)
204                {
205                    this.func_73896_a(this.clickedURI);
206                }
207    
208                this.clickedURI = null;
209                this.mc.displayGuiScreen(this);
210            }
211        }
212    
213        private void func_73896_a(URI par1URI)
214        {
215            try
216            {
217                Class var2 = Class.forName("java.awt.Desktop");
218                Object var3 = var2.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]);
219                var2.getMethod("browse", new Class[] {URI.class}).invoke(var3, new Object[] {par1URI});
220            }
221            catch (Throwable var4)
222            {
223                var4.printStackTrace();
224            }
225        }
226    
227        /**
228         * Autocompletes player name
229         */
230        public void completePlayerName()
231        {
232            String var3;
233    
234            if (this.field_73897_d)
235            {
236                this.inputField.deleteFromCursor(this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition());
237    
238                if (this.field_73903_n >= this.field_73904_o.size())
239                {
240                    this.field_73903_n = 0;
241                }
242            }
243            else
244            {
245                int var1 = this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false);
246                this.field_73904_o.clear();
247                this.field_73903_n = 0;
248                String var2 = this.inputField.getText().substring(var1).toLowerCase();
249                var3 = this.inputField.getText().substring(0, this.inputField.getCursorPosition());
250                this.func_73893_a(var3, var2);
251    
252                if (this.field_73904_o.isEmpty())
253                {
254                    return;
255                }
256    
257                this.field_73897_d = true;
258                this.inputField.deleteFromCursor(var1 - this.inputField.getCursorPosition());
259            }
260    
261            if (this.field_73904_o.size() > 1)
262            {
263                StringBuilder var4 = new StringBuilder();
264    
265                for (Iterator var5 = this.field_73904_o.iterator(); var5.hasNext(); var4.append(var3))
266                {
267                    var3 = (String)var5.next();
268    
269                    if (var4.length() > 0)
270                    {
271                        var4.append(", ");
272                    }
273                }
274    
275                this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(var4.toString(), 1);
276            }
277    
278            this.inputField.writeText((String)this.field_73904_o.get(this.field_73903_n++));
279        }
280    
281        private void func_73893_a(String par1Str, String par2Str)
282        {
283            if (par1Str.length() >= 1)
284            {
285                this.mc.thePlayer.sendQueue.addToSendQueue(new Packet203AutoComplete(par1Str));
286                this.field_73905_m = true;
287            }
288        }
289    
290        /**
291         * input is relative and is applied directly to the sentHistoryCursor so -1 is the previous message, 1 is the next
292         * message from the current cursor position
293         */
294        public void getSentHistory(int par1)
295        {
296            int var2 = this.sentHistoryCursor + par1;
297            int var3 = this.mc.ingameGUI.getChatGUI().getSentMessages().size();
298    
299            if (var2 < 0)
300            {
301                var2 = 0;
302            }
303    
304            if (var2 > var3)
305            {
306                var2 = var3;
307            }
308    
309            if (var2 != this.sentHistoryCursor)
310            {
311                if (var2 == var3)
312                {
313                    this.sentHistoryCursor = var3;
314                    this.inputField.setText(this.field_73898_b);
315                }
316                else
317                {
318                    if (this.sentHistoryCursor == var3)
319                    {
320                        this.field_73898_b = this.inputField.getText();
321                    }
322    
323                    this.inputField.setText((String)this.mc.ingameGUI.getChatGUI().getSentMessages().get(var2));
324                    this.sentHistoryCursor = var2;
325                }
326            }
327        }
328    
329        /**
330         * Draws the screen and all the components in it.
331         */
332        public void drawScreen(int par1, int par2, float par3)
333        {
334            drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE);
335            this.inputField.drawTextBox();
336            super.drawScreen(par1, par2, par3);
337        }
338    
339        public void func_73894_a(String[] par1ArrayOfStr)
340        {
341            if (this.field_73905_m)
342            {
343                this.field_73904_o.clear();
344                String[] var2 = par1ArrayOfStr;
345                int var3 = par1ArrayOfStr.length;
346    
347                for (int var4 = 0; var4 < var3; ++var4)
348                {
349                    String var5 = var2[var4];
350    
351                    if (var5.length() > 0)
352                    {
353                        this.field_73904_o.add(var5);
354                    }
355                }
356    
357                if (this.field_73904_o.size() > 0)
358                {
359                    this.field_73897_d = true;
360                    this.completePlayerName();
361                }
362            }
363        }
364    
365        /**
366         * Returns true if this GUI should pause the game when it is displayed in single-player
367         */
368        public boolean doesGuiPauseGame()
369        {
370            return false;
371        }
372    }