    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.func_77983_a("pages", this.bookPages);
    155                    }
    156
    157                    String var8 = "MC|BEdit";
    158
    159                    if (par1)
    160                    {
    161                        var8 = "MC|BSign";
    162                        this.itemstackBook.func_77983_a("author", new NBTTagString("author", this.editingPlayer.username));
    163                        this.itemstackBook.func_77983_a("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    }