    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}