001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import java.io.ByteArrayOutputStream;
006    import java.io.DataOutputStream;
007    import org.lwjgl.input.Keyboard;
008    import org.lwjgl.opengl.GL11;
009    
010    @SideOnly(Side.CLIENT)
011    public class GuiScreenBook extends GuiScreen
012    {
013        /** The player editing the book */
014        private final EntityPlayer editingPlayer;
015        private final ItemStack itemstackBook;
016    
017        /** Whether the book is signed or can still be edited */
018        private final boolean bookIsUnsigned;
019        private boolean bookModified;
020        private boolean editingTitle;
021    
022        /** Update ticks since the gui was opened */
023        private int updateCount;
024        private int bookImageWidth = 192;
025        private int bookImageHeight = 192;
026        private int bookTotalPages = 1;
027        private int currPage;
028        private NBTTagList bookPages;
029        private String bookTitle = "";
030        private GuiButtonNextPage buttonNextPage;
031        private GuiButtonNextPage buttonPreviousPage;
032        private GuiButton buttonDone;
033    
034        /** The GuiButton to sign this book. */
035        private GuiButton buttonSign;
036        private GuiButton buttonFinalize;
037        private GuiButton buttonCancel;
038    
039        public GuiScreenBook(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack, boolean par3)
040        {
041            this.editingPlayer = par1EntityPlayer;
042            this.itemstackBook = par2ItemStack;
043            this.bookIsUnsigned = par3;
044    
045            if (par2ItemStack.hasTagCompound())
046            {
047                NBTTagCompound var4 = par2ItemStack.getTagCompound();
048                this.bookPages = var4.getTagList("pages");
049    
050                if (this.bookPages != null)
051                {
052                    this.bookPages = (NBTTagList)this.bookPages.copy();
053                    this.bookTotalPages = this.bookPages.tagCount();
054    
055                    if (this.bookTotalPages < 1)
056                    {
057                        this.bookTotalPages = 1;
058                    }
059                }
060            }
061    
062            if (this.bookPages == null && par3)
063            {
064                this.bookPages = new NBTTagList("pages");
065                this.bookPages.appendTag(new NBTTagString("1", ""));
066                this.bookTotalPages = 1;
067            }
068        }
069    
070        /**
071         * Called from the main game loop to update the screen.
072         */
073        public void updateScreen()
074        {
075            super.updateScreen();
076            ++this.updateCount;
077        }
078    
079        /**
080         * Adds the buttons (and other controls) to the screen in question.
081         */
082        public void initGui()
083        {
084            this.controlList.clear();
085            Keyboard.enableRepeatEvents(true);
086    
087            if (this.bookIsUnsigned)
088            {
089                this.controlList.add(this.buttonSign = new GuiButton(3, this.width / 2 - 100, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("book.signButton")));
090                this.controlList.add(this.buttonDone = new GuiButton(0, this.width / 2 + 2, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("gui.done")));
091                this.controlList.add(this.buttonFinalize = new GuiButton(5, this.width / 2 - 100, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("book.finalizeButton")));
092                this.controlList.add(this.buttonCancel = new GuiButton(4, this.width / 2 + 2, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("gui.cancel")));
093            }
094            else
095            {
096                this.controlList.add(this.buttonDone = new GuiButton(0, this.width / 2 - 100, 4 + this.bookImageHeight, 200, 20, StatCollector.translateToLocal("gui.done")));
097            }
098    
099            int var1 = (this.width - this.bookImageWidth) / 2;
100            byte var2 = 2;
101            this.controlList.add(this.buttonNextPage = new GuiButtonNextPage(1, var1 + 120, var2 + 154, true));
102            this.controlList.add(this.buttonPreviousPage = new GuiButtonNextPage(2, var1 + 38, var2 + 154, false));
103            this.updateButtons();
104        }
105    
106        /**
107         * Called when the screen is unloaded. Used to disable keyboard repeat events
108         */
109        public void onGuiClosed()
110        {
111            Keyboard.enableRepeatEvents(false);
112        }
113    
114        private void updateButtons()
115        {
116            this.buttonNextPage.drawButton = !this.editingTitle && (this.currPage < this.bookTotalPages - 1 || this.bookIsUnsigned);
117            this.buttonPreviousPage.drawButton = !this.editingTitle && this.currPage > 0;
118            this.buttonDone.drawButton = !this.bookIsUnsigned || !this.editingTitle;
119    
120            if (this.bookIsUnsigned)
121            {
122                this.buttonSign.drawButton = !this.editingTitle;
123                this.buttonCancel.drawButton = this.editingTitle;
124                this.buttonFinalize.drawButton = this.editingTitle;
125                this.buttonFinalize.enabled = this.bookTitle.trim().length() > 0;
126            }
127        }
128    
129        private void sendBookToServer(boolean par1)
130        {
131            if (this.bookIsUnsigned && this.bookModified)
132            {
133                if (this.bookPages != null)
134                {
135                    while (this.bookPages.tagCount() > 1)
136                    {
137                        NBTTagString var2 = (NBTTagString)this.bookPages.tagAt(this.bookPages.tagCount() - 1);
138    
139                        if (var2.data != null && var2.data.length() != 0)
140                        {
141                            break;
142                        }
143    
144                        this.bookPages.removeTag(this.bookPages.tagCount() - 1);
145                    }
146    
147                    if (this.itemstackBook.hasTagCompound())
148                    {
149                        NBTTagCompound var7 = this.itemstackBook.getTagCompound();
150                        var7.setTag("pages", this.bookPages);
151                    }
152                    else
153                    {
154                        this.itemstackBook.setTagInfo("pages", this.bookPages);
155                    }
156    
157                    String var8 = "MC|BEdit";
158    
159                    if (par1)
160                    {
161                        var8 = "MC|BSign";
162                        this.itemstackBook.setTagInfo("author", new NBTTagString("author", this.editingPlayer.username));
163                        this.itemstackBook.setTagInfo("title", new NBTTagString("title", this.bookTitle.trim()));
164                        this.itemstackBook.itemID = Item.writtenBook.shiftedIndex;
165                    }
166    
167                    ByteArrayOutputStream var3 = new ByteArrayOutputStream();
168                    DataOutputStream var4 = new DataOutputStream(var3);
169    
170                    try
171                    {
172                        Packet.writeItemStack(this.itemstackBook, var4);
173                        this.mc.getSendQueue().addToSendQueue(new Packet250CustomPayload(var8, var3.toByteArray()));
174                    }
175                    catch (Exception var6)
176                    {
177                        var6.printStackTrace();
178                    }
179                }
180            }
181        }
182    
183        /**
184         * Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
185         */
186        protected void actionPerformed(GuiButton par1GuiButton)
187        {
188            if (par1GuiButton.enabled)
189            {
190                if (par1GuiButton.id == 0)
191                {
192                    this.mc.displayGuiScreen((GuiScreen)null);
193                    this.sendBookToServer(false);
194                }
195                else if (par1GuiButton.id == 3 && this.bookIsUnsigned)
196                {
197                    this.editingTitle = true;
198                }
199                else if (par1GuiButton.id == 1)
200                {
201                    if (this.currPage < this.bookTotalPages - 1)
202                    {
203                        ++this.currPage;
204                    }
205                    else if (this.bookIsUnsigned)
206                    {
207                        this.addNewPage();
208    
209                        if (this.currPage < this.bookTotalPages - 1)
210                        {
211                            ++this.currPage;
212                        }
213                    }
214                }
215                else if (par1GuiButton.id == 2)
216                {
217                    if (this.currPage > 0)
218                    {
219                        --this.currPage;
220                    }
221                }
222                else if (par1GuiButton.id == 5 && this.editingTitle)
223                {
224                    this.sendBookToServer(true);
225                    this.mc.displayGuiScreen((GuiScreen)null);
226                }
227                else if (par1GuiButton.id == 4 && this.editingTitle)
228                {
229                    this.editingTitle = false;
230                }
231    
232                this.updateButtons();
233            }
234        }
235    
236        private void addNewPage()
237        {
238            if (this.bookPages != null && this.bookPages.tagCount() < 50)
239            {
240                this.bookPages.appendTag(new NBTTagString("" + (this.bookTotalPages + 1), ""));
241                ++this.bookTotalPages;
242                this.bookModified = true;
243            }
244        }
245    
246        /**
247         * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e).
248         */
249        protected void keyTyped(char par1, int par2)
250        {
251            super.keyTyped(par1, par2);
252    
253            if (this.bookIsUnsigned)
254            {
255                if (this.editingTitle)
256                {
257                    this.func_74162_c(par1, par2);
258                }
259                else
260                {
261                    this.keyTypedInBook(par1, par2);
262                }
263            }
264        }
265    
266        /**
267         * Processes keystrokes when editing the text of a book
268         */
269        private void keyTypedInBook(char par1, int par2)
270        {
271            switch (par1)
272            {
273                case 22:
274                    this.func_74160_b(GuiScreen.getClipboardString());
275                    return;
276                default:
277                    switch (par2)
278                    {
279                        case 14:
280                            String var3 = this.func_74158_i();
281    
282                            if (var3.length() > 0)
283                            {
284                                this.func_74159_a(var3.substring(0, var3.length() - 1));
285                            }
286    
287                            return;
288                        case 28:
289                            this.func_74160_b("\n");
290                            return;
291                        default:
292                            if (ChatAllowedCharacters.isAllowedCharacter(par1))
293                            {
294                                this.func_74160_b(Character.toString(par1));
295                            }
296                    }
297            }
298        }
299    
300        private void func_74162_c(char par1, int par2)
301        {
302            switch (par2)
303            {
304                case 14:
305                    if (this.bookTitle.length() > 0)
306                    {
307                        this.bookTitle = this.bookTitle.substring(0, this.bookTitle.length() - 1);
308                        this.updateButtons();
309                    }
310    
311                    return;
312                case 28:
313                    if (this.bookTitle.length() > 0)
314                    {
315                        this.sendBookToServer(true);
316                        this.mc.displayGuiScreen((GuiScreen)null);
317                    }
318    
319                    return;
320                default:
321                    if (this.bookTitle.length() < 16 && ChatAllowedCharacters.isAllowedCharacter(par1))
322                    {
323                        this.bookTitle = this.bookTitle + Character.toString(par1);
324                        this.updateButtons();
325                        this.bookModified = true;
326                    }
327            }
328        }
329    
330        private String func_74158_i()
331        {
332            if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount())
333            {
334                NBTTagString var1 = (NBTTagString)this.bookPages.tagAt(this.currPage);
335                return var1.toString();
336            }
337            else
338            {
339                return "";
340            }
341        }
342    
343        private void func_74159_a(String par1Str)
344        {
345            if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount())
346            {
347                NBTTagString var2 = (NBTTagString)this.bookPages.tagAt(this.currPage);
348                var2.data = par1Str;
349                this.bookModified = true;
350            }
351        }
352    
353        private void func_74160_b(String par1Str)
354        {
355            String var2 = this.func_74158_i();
356            String var3 = var2 + par1Str;
357            int var4 = this.fontRenderer.splitStringWidth(var3 + "\u00a70_", 118);
358    
359            if (var4 <= 118 && var3.length() < 256)
360            {
361                this.func_74159_a(var3);
362            }
363        }
364    
365        /**
366         * Draws the screen and all the components in it.
367         */
368        public void drawScreen(int par1, int par2, float par3)
369        {
370            int var4 = this.mc.renderEngine.getTexture("/gui/book.png");
371            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
372            this.mc.renderEngine.bindTexture(var4);
373            int var5 = (this.width - this.bookImageWidth) / 2;
374            byte var6 = 2;
375            this.drawTexturedModalRect(var5, var6, 0, 0, this.bookImageWidth, this.bookImageHeight);
376            String var7;
377            String var8;
378            int var9;
379    
380            if (this.editingTitle)
381            {
382                var7 = this.bookTitle;
383    
384                if (this.bookIsUnsigned)
385                {
386                    if (this.updateCount / 6 % 2 == 0)
387                    {
388                        var7 = var7 + "\u00a70_";
389                    }
390                    else
391                    {
392                        var7 = var7 + "\u00a77_";
393                    }
394                }
395    
396                var8 = StatCollector.translateToLocal("book.editTitle");
397                var9 = this.fontRenderer.getStringWidth(var8);
398                this.fontRenderer.drawString(var8, var5 + 36 + (116 - var9) / 2, var6 + 16 + 16, 0);
399                int var10 = this.fontRenderer.getStringWidth(var7);
400                this.fontRenderer.drawString(var7, var5 + 36 + (116 - var10) / 2, var6 + 48, 0);
401                String var11 = String.format(StatCollector.translateToLocal("book.byAuthor"), new Object[] {this.editingPlayer.username});
402                int var12 = this.fontRenderer.getStringWidth(var11);
403                this.fontRenderer.drawString("\u00a78" + var11, var5 + 36 + (116 - var12) / 2, var6 + 48 + 10, 0);
404                String var13 = StatCollector.translateToLocal("book.finalizeWarning");
405                this.fontRenderer.drawSplitString(var13, var5 + 36, var6 + 80, 116, 0);
406            }
407            else
408            {
409                var7 = String.format(StatCollector.translateToLocal("book.pageIndicator"), new Object[] {Integer.valueOf(this.currPage + 1), Integer.valueOf(this.bookTotalPages)});
410                var8 = "";
411    
412                if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount())
413                {
414                    NBTTagString var14 = (NBTTagString)this.bookPages.tagAt(this.currPage);
415                    var8 = var14.toString();
416                }
417    
418                if (this.bookIsUnsigned)
419                {
420                    if (this.fontRenderer.getBidiFlag())
421                    {
422                        var8 = var8 + "_";
423                    }
424                    else if (this.updateCount / 6 % 2 == 0)
425                    {
426                        var8 = var8 + "\u00a70_";
427                    }
428                    else
429                    {
430                        var8 = var8 + "\u00a77_";
431                    }
432                }
433    
434                var9 = this.fontRenderer.getStringWidth(var7);
435                this.fontRenderer.drawString(var7, var5 - var9 + this.bookImageWidth - 44, var6 + 16, 0);
436                this.fontRenderer.drawSplitString(var8, var5 + 36, var6 + 16 + 16, 116, 0);
437            }
438    
439            super.drawScreen(par1, par2, par3);
440        }
441    }