001package net.minecraft.client.gui;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.net.URI;
006import java.util.ArrayList;
007import java.util.Iterator;
008import java.util.List;
009import net.minecraft.network.packet.Packet203AutoComplete;
010import org.lwjgl.input.Keyboard;
011import org.lwjgl.input.Mouse;
012
013@SideOnly(Side.CLIENT)
014public 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 s = this.inputField.getText().trim();
101
102            if (s.length() > 0)
103            {
104                this.mc.ingameGUI.getChatGUI().addToSentMessages(s);
105
106                if (!this.mc.handleClientCommand(s))
107                {
108                    this.mc.thePlayer.sendChatMessage(s);
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(this.mc.ingameGUI.getChatGUI().func_96127_i() - 1);
125        }
126        else if (par2 == 209)
127        {
128            this.mc.ingameGUI.getChatGUI().scroll(-this.mc.ingameGUI.getChatGUI().func_96127_i() + 1);
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 i = Mouse.getEventDWheel();
143
144        if (i != 0)
145        {
146            if (i > 1)
147            {
148                i = 1;
149            }
150
151            if (i < -1)
152            {
153                i = -1;
154            }
155
156            if (!isShiftKeyDown())
157            {
158                i *= 7;
159            }
160
161            this.mc.ingameGUI.getChatGUI().scroll(i);
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 chatclickdata = this.mc.ingameGUI.getChatGUI().func_73766_a(Mouse.getX(), Mouse.getY());
173
174            if (chatclickdata != null)
175            {
176                URI uri = chatclickdata.getURI();
177
178                if (uri != null)
179                {
180                    if (this.mc.gameSettings.chatLinksPrompt)
181                    {
182                        this.clickedURI = uri;
183                        this.mc.displayGuiScreen(new GuiConfirmOpenLink(this, chatclickdata.getClickedUrl(), 0));
184                    }
185                    else
186                    {
187                        this.func_73896_a(uri);
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 oclass = Class.forName("java.awt.Desktop");
218            Object object = oclass.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]);
219            oclass.getMethod("browse", new Class[] {URI.class}).invoke(object, new Object[] {par1URI});
220        }
221        catch (Throwable throwable)
222        {
223            throwable.printStackTrace();
224        }
225    }
226
227    /**
228     * Autocompletes player name
229     */
230    public void completePlayerName()
231    {
232        String s;
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 i = this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false);
246            this.field_73904_o.clear();
247            this.field_73903_n = 0;
248            String s1 = this.inputField.getText().substring(i).toLowerCase();
249            s = this.inputField.getText().substring(0, this.inputField.getCursorPosition());
250            this.func_73893_a(s, s1);
251
252            if (this.field_73904_o.isEmpty())
253            {
254                return;
255            }
256
257            this.field_73897_d = true;
258            this.inputField.deleteFromCursor(i - this.inputField.getCursorPosition());
259        }
260
261        if (this.field_73904_o.size() > 1)
262        {
263            StringBuilder stringbuilder = new StringBuilder();
264
265            for (Iterator iterator = this.field_73904_o.iterator(); iterator.hasNext(); stringbuilder.append(s))
266            {
267                s = (String)iterator.next();
268
269                if (stringbuilder.length() > 0)
270                {
271                    stringbuilder.append(", ");
272                }
273            }
274
275            this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(stringbuilder.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 j = this.sentHistoryCursor + par1;
297        int k = this.mc.ingameGUI.getChatGUI().getSentMessages().size();
298
299        if (j < 0)
300        {
301            j = 0;
302        }
303
304        if (j > k)
305        {
306            j = k;
307        }
308
309        if (j != this.sentHistoryCursor)
310        {
311            if (j == k)
312            {
313                this.sentHistoryCursor = k;
314                this.inputField.setText(this.field_73898_b);
315            }
316            else
317            {
318                if (this.sentHistoryCursor == k)
319                {
320                    this.field_73898_b = this.inputField.getText();
321                }
322
323                this.inputField.setText((String)this.mc.ingameGUI.getChatGUI().getSentMessages().get(j));
324                this.sentHistoryCursor = j;
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[] astring1 = par1ArrayOfStr;
345            int i = par1ArrayOfStr.length;
346
347            for (int j = 0; j < i; ++j)
348            {
349                String s = astring1[j];
350
351                if (s.length() > 0)
352                {
353                    this.field_73904_o.add(s);
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}