/**
   * Draws the Title of the current chapter, current index entry or just "Actually Additions" if
   * neither is present
   */
  public static void drawTitle(GuiBooklet booklet) {
    // Upper title
    booklet.drawTexturedModalRect(
        booklet.guiLeft + booklet.xSize / 2 - 142 / 2, booklet.guiTop - 12, 0, 240, 142, 12);
    // Lower title
    booklet.drawTexturedModalRect(
        booklet.guiLeft + booklet.xSize / 2 - 142 / 2,
        booklet.guiTop + booklet.ySize,
        0,
        243,
        142,
        13);

    String strg =
        booklet.currentChapter == null
            ? (booklet.currentIndexEntry == null
                ? StringUtil.localize("itemGroup." + ModUtil.MOD_ID_LOWER)
                : booklet.currentIndexEntry.getLocalizedName())
            : booklet.currentChapter.getLocalizedName();
    booklet.drawCenteredString(
        booklet.getFontRenderer(),
        strg,
        booklet.guiLeft + booklet.xSize / 2,
        booklet.guiTop - 9,
        StringUtil.DECIMAL_COLOR_WHITE);
  }
  /**
   * Opens an index entry in the booklet.
   *
   * @param resetTextField will clear the text in the searchField and reset the search entry's data
   */
  @SuppressWarnings("unchecked")
  public static void openIndexEntry(
      GuiBooklet booklet, BookletEntry entry, int page, boolean resetTextField) {
    booklet.searchField.setVisible(entry instanceof BookletEntryAllSearch);
    booklet.searchField.setFocused(entry instanceof BookletEntryAllSearch);
    if (resetTextField) {
      booklet.searchField.setText("");
      if (entry instanceof BookletEntryAllSearch) {
        entry.chapters =
            (ArrayList<BookletChapter>) ((BookletEntryAllSearch) entry).allChapters.clone();
      }
    }

    booklet.currentPage = null;
    booklet.currentChapter = null;

    booklet.currentIndexEntry = entry;
    booklet.indexPageAmount =
        entry == null ? 1 : entry.chapters.size() / booklet.chapterButtons.length + 1;
    booklet.pageOpenInIndex =
        entry == null
            ? 1
            : (booklet.indexPageAmount <= page || page <= 0 ? booklet.indexPageAmount : page);

    booklet.buttonPreviousScreen.visible = entry != null;
    booklet.buttonForward.visible = booklet.pageOpenInIndex < booklet.indexPageAmount;
    booklet.buttonBackward.visible = booklet.pageOpenInIndex > 1;

    for (int i = 0; i < booklet.chapterButtons.length; i++) {
      IndexButton button = (IndexButton) booklet.chapterButtons[i];
      if (entry == null) {
        boolean entryExists = InitBooklet.entries.size() > i;
        button.visible = entryExists;
        if (entryExists) {
          button.displayString = InitBooklet.entries.get(i).getNameWithColor();
          button.chap = null;
        }
      } else {
        boolean entryExists =
            entry.chapters.size()
                > i
                    + (booklet.chapterButtons.length * booklet.pageOpenInIndex
                        - booklet.chapterButtons.length);
        button.visible = entryExists;
        if (entryExists) {
          BookletChapter chap =
              entry.chapters.get(
                  i
                      + (booklet.chapterButtons.length * booklet.pageOpenInIndex
                          - booklet.chapterButtons.length));
          button.displayString = chap.getNameWithColor();
          button.chap = chap;
        }
      }
    }
  }
  /**
   * Pre-renders the booklet page, including -the number of a page and its content (text, crafting
   * recipe etc.) -the number of a page in a chapter -the amount of words and chars in the index
   * (Just for teh lulz)
   */
  public static void renderPre(
      GuiBooklet booklet, int mouseX, int mouseY, int ticksElapsed, boolean mousePressed) {
    if (booklet.currentIndexEntry != null) {
      // Renders Booklet Page Number and Content
      if (booklet.currentChapter != null && booklet.currentPage != null) {
        booklet.drawCenteredString(
            booklet.getFontRenderer(),
            booklet.currentPage.getID() + "/" + booklet.currentChapter.pages.length,
            booklet.guiLeft + booklet.xSize / 2,
            booklet.guiTop + 172,
            StringUtil.DECIMAL_COLOR_WHITE);
        booklet.currentPage.renderPre(booklet, mouseX, mouseY, ticksElapsed, mousePressed);
      }
      // Renders Chapter Page Number
      else {
        booklet.drawCenteredString(
            booklet.getFontRenderer(),
            booklet.pageOpenInIndex + "/" + booklet.indexPageAmount,
            booklet.guiLeft + booklet.xSize / 2,
            booklet.guiTop + 172,
            StringUtil.DECIMAL_COLOR_WHITE);
      }
    }
    // Renders the amount of words and chars the book has
    else {
      String wordCountString =
          StringUtil.localizeFormatted(
              "booklet." + ModUtil.MOD_ID_LOWER + ".amountOfWords", InitBooklet.wordCount);
      booklet
          .getFontRenderer()
          .drawString(
              EnumChatFormatting.ITALIC + wordCountString,
              booklet.guiLeft
                  + booklet.xSize
                  - booklet.getFontRenderer().getStringWidth(wordCountString)
                  - 15,
              booklet.guiTop + booklet.ySize - 18 - booklet.getFontRenderer().FONT_HEIGHT,
              0);

      String charCountString =
          StringUtil.localizeFormatted(
              "booklet." + ModUtil.MOD_ID_LOWER + ".amountOfChars", InitBooklet.charCount);
      booklet
          .getFontRenderer()
          .drawString(
              EnumChatFormatting.ITALIC + charCountString,
              booklet.guiLeft
                  + booklet.xSize
                  - booklet.getFontRenderer().getStringWidth(charCountString)
                  - 15,
              booklet.guiTop + booklet.ySize - 18,
              0);
    }
  }
  /**
   * Draws an Achievement Info if the page has items that trigger achievements
   *
   * @param pre If the hover info texts or the icon should be drawn
   */
  public static void drawAchievementInfo(GuiBooklet booklet, boolean pre, int mouseX, int mouseY) {
    if (booklet.currentChapter == null) {
      return;
    }

    ArrayList<String> infoList = null;
    for (BookletPage page : booklet.currentChapter.pages) {
      if (page != null && page.getItemStacksForPage() != null) {
        for (ItemStack stack : page.getItemStacksForPage()) {
          for (Achievement achievement : InitAchievements.achievementList) {
            if (stack != null
                && achievement.theItemStack != null
                && achievement.theItemStack.isItemEqual(stack)) {
              if (pre) {
                booklet.mc.getTextureManager().bindTexture(GuiBooklet.resLoc);
                booklet.drawTexturedModalRect(
                    booklet.guiLeft + booklet.xSize + 1, booklet.guiTop - 18, 166, 154, 22, 21);
                return;
              } else {
                if (mouseX >= booklet.guiLeft + booklet.xSize + 1
                    && mouseX < booklet.guiLeft + booklet.xSize + 1 + 22
                    && mouseY >= booklet.guiTop - 18
                    && mouseY < booklet.guiTop - 18 + 21) {
                  if (infoList == null) {
                    infoList = new ArrayList<String>();
                    infoList.add(EnumChatFormatting.GOLD + "Achievements related to this chapter:");
                  }
                  infoList.add("-" + StringUtil.localize(achievement.statId));
                  infoList.add(EnumChatFormatting.GRAY + "(" + achievement.getDescription() + ")");
                }
              }
            }
          }
        }
      }
    }

    if (infoList != null) {
      booklet.drawHoveringText(infoList, mouseX, mouseY);
    }
  }
  /**
   * Opens a chapter in the booklet. Can only be done when the chapter is not null and an index
   * entry is opened in the booklet
   */
  public static void openChapter(GuiBooklet booklet, BookletChapter chapter, BookletPage page) {
    if (chapter == null || booklet.currentIndexEntry == null) {
      return;
    }

    booklet.searchField.setVisible(false);
    booklet.searchField.setFocused(false);
    booklet.searchField.setText("");

    booklet.currentChapter = chapter;
    booklet.currentPage =
        page != null && doesChapterHavePage(chapter, page) ? page : chapter.pages[0];

    booklet.buttonForward.visible = getNextPage(chapter, booklet.currentPage) != null;
    booklet.buttonBackward.visible = getPrevPage(chapter, booklet.currentPage) != null;
    booklet.buttonPreviousScreen.visible = true;

    for (GuiButton chapterButton : booklet.chapterButtons) {
      chapterButton.visible = false;
    }
  }
  /** Called when the "previous page"-button is pressed */
  public static void handlePreviousPage(GuiBooklet booklet) {
    if (booklet.currentIndexEntry != null) {
      if (booklet.currentPage != null) {
        BookletPage page = getPrevPage(booklet.currentChapter, booklet.currentPage);
        if (page != null) {
          booklet.currentPage = page;
        }

        booklet.buttonForward.visible =
            getNextPage(booklet.currentChapter, booklet.currentPage) != null;
        booklet.buttonBackward.visible =
            getPrevPage(booklet.currentChapter, booklet.currentPage) != null;
      } else {
        openIndexEntry(
            booklet,
            booklet.currentIndexEntry,
            booklet.pageOpenInIndex - 1,
            !(booklet.currentIndexEntry instanceof BookletEntryAllSearch));
      }
    }
  }
  /** Draws all of the hovering texts for the buttons that need explanation in the booklet */
  @SuppressWarnings("unchecked")
  public static void doHoverTexts(GuiBooklet booklet, int mouseX, int mouseY) {
    // Achievements Hover Text
    if (booklet.buttonAchievements.func_146115_a()) {
      booklet.drawHoveringText(
          Collections.singletonList(EnumChatFormatting.GOLD + "Show Achievements"), mouseX, mouseY);
    }
    // Config Hover Text
    else if (booklet.buttonConfig.func_146115_a()) {
      ArrayList list = new ArrayList();
      list.add(EnumChatFormatting.GOLD + "Show Configuration GUI");
      list.addAll(
          booklet
              .getFontRenderer()
              .listFormattedStringToWidth(
                  "It is highly recommended that you restart your game after changing anything as that prevents possible bugs occuring!",
                  GuiBooklet.TOOLTIP_SPLIT_LENGTH));
      booklet.drawHoveringText(list, mouseX, mouseY);

    }
    // Twitter Hover Text
    else if (booklet.buttonTwitter.func_146115_a()) {
      booklet.drawHoveringText(
          Collections.singletonList(
              EnumChatFormatting.GOLD + "Open @ActAddMod on Twitter in Browser"),
          mouseX,
          mouseY);
    }
    // Forum Hover Text
    else if (booklet.buttonForum.func_146115_a()) {
      booklet.drawHoveringText(
          Collections.singletonList(
              EnumChatFormatting.GOLD + "Open Minecraft Forum Post in Browser"),
          mouseX,
          mouseY);
    }
    // Update Checker Hover Text
    else if (booklet.buttonUpdate.func_146115_a()) {
      ArrayList list = new ArrayList();
      if (UpdateChecker.checkFailed) {
        list.add(
            IChatComponent.Serializer.func_150699_a(
                    StringUtil.localize("info." + ModUtil.MOD_ID_LOWER + ".update.failed"))
                .getFormattedText());
      } else if (UpdateChecker.needsUpdateNotify) {
        list.add(
            IChatComponent.Serializer.func_150699_a(
                    StringUtil.localize("info." + ModUtil.MOD_ID_LOWER + ".update.generic"))
                .getFormattedText());
        list.add(
            IChatComponent.Serializer.func_150699_a(
                    StringUtil.localizeFormatted(
                        "info." + ModUtil.MOD_ID_LOWER + ".update.versionCompare",
                        ModUtil.VERSION,
                        UpdateChecker.updateVersion))
                .getFormattedText());
        list.add(StringUtil.localize("info." + ModUtil.MOD_ID_LOWER + ".update.buttonOptions"));
      }
      booklet.drawHoveringText(list, mouseX, mouseY);
    } else {
      for (GuiButton button : booklet.bookmarkButtons) {
        if (button instanceof BookmarkButton && button.func_146115_a()) {
          ((BookmarkButton) button).drawHover(mouseX, mouseY);
        }
      }
    }
  }