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