/*
   * Update game state
   */
  @Override
  protected void updateImpl(GameContainer container, StateBasedGame game, int delta)
      throws SlickException {
    // TTF font
    if (ResourceHolderSlick.ttfFont != null) ResourceHolderSlick.ttfFont.loadGlyphs();

    // Update key input states
    GameKeySlick.gamekey[0].update(container.getInput());

    // Cursor movement
    if (GameKeySlick.gamekey[0].isMenuRepeatKey(GameKeySlick.BUTTON_UP)) {
      cursor--;
      if (cursor < 0) cursor = 27;
      ResourceHolderSlick.soundManager.play("cursor");
    }
    if (GameKeySlick.gamekey[0].isMenuRepeatKey(GameKeySlick.BUTTON_DOWN)) {
      cursor++;
      if (cursor > 27) cursor = 0;
      ResourceHolderSlick.soundManager.play("cursor");
    }

    // Configuration changes
    int change = 0;
    if (GameKeySlick.gamekey[0].isMenuRepeatKey(GameKeySlick.BUTTON_LEFT)) change = -1;
    if (GameKeySlick.gamekey[0].isMenuRepeatKey(GameKeySlick.BUTTON_RIGHT)) change = 1;

    if (change != 0) {
      ResourceHolderSlick.soundManager.play("change");

      switch (cursor) {
        case 0:
          se = !se;
          break;
        case 1:
          bgm = !bgm;
          break;
        case 2:
          bgmpreload = !bgmpreload;
          break;
        case 3:
          sevolume += change;
          if (sevolume < 0) sevolume = 128;
          if (sevolume > 128) sevolume = 0;
          break;
        case 4:
          bgmvolume += change;
          if (bgmvolume < 0) bgmvolume = 128;
          if (bgmvolume > 128) bgmvolume = 0;
          break;
        case 5:
          showbg = !showbg;
          break;
        case 6:
          heavyeffect = !heavyeffect;
          break;
        case 7:
          showlineeffect = !showlineeffect;
          break;
        case 8:
          lineeffectspeed += change;
          if (lineeffectspeed < 0) lineeffectspeed = 9;
          if (lineeffectspeed > 9) lineeffectspeed = 0;
          break;
        case 9:
          showmeter = !showmeter;
          break;
        case 10:
          darknextarea = !darknextarea;
          break;
        case 11:
          nextshadow = !nextshadow;
          break;
        case 12:
          nexttype += change;
          if (nexttype < 0) nexttype = 2;
          if (nexttype > 2) nexttype = 0;
          break;
        case 13:
          outlineghost = !outlineghost;
          break;
        case 14:
          fieldbgbright += change;
          if (fieldbgbright < 0) fieldbgbright = 255;
          if (fieldbgbright > 255) fieldbgbright = 0;
          break;
        case 15:
          showfieldbggrid = !showfieldbggrid;
          break;
        case 16:
          showInput = !showInput;
          break;
        case 17:
          fullscreen = !fullscreen;
          break;
        case 18:
          showfps = !showfps;
          break;
        case 19:
          maxfps += change;
          if (maxfps < 0) maxfps = 99;
          if (maxfps > 99) maxfps = 0;
          break;
        case 20:
          enableframestep = !enableframestep;
          break;
        case 21:
          alternateFPSPerfectMode = !alternateFPSPerfectMode;
          break;
        case 22:
          alternateFPSPerfectYield = !alternateFPSPerfectYield;
          break;
        case 23:
          bgmstreaming = !bgmstreaming;
          break;
        case 24:
          vsync = !vsync;
          break;
        case 25:
          alternateFPSTiming = !alternateFPSTiming;
          break;
        case 26:
          alternateFPSDynamicAdjust = !alternateFPSDynamicAdjust;
          break;
        case 27:
          screenSizeType += change;
          if (screenSizeType < 0) screenSizeType = SCREENSIZE_TABLE.length - 1;
          if (screenSizeType > SCREENSIZE_TABLE.length - 1) screenSizeType = 0;
          break;
      }
    }

    // Confirm button
    if (GameKeySlick.gamekey[0].isPushKey(GameKeySlick.BUTTON_A)) {
      ResourceHolderSlick.soundManager.play("decide");
      saveConfig(NullpoMinoSlick.propConfig);
      NullpoMinoSlick.saveConfig();
      NullpoMinoSlick.setGeneralConfig();
      if (showlineeffect) ResourceHolderSlick.loadLineClearEffectImages();
      if (showbg) ResourceHolderSlick.loadBackgroundImages();
      game.enterState(StateConfigMainMenu.ID);
    }

    // Cancel button
    if (GameKeySlick.gamekey[0].isPushKey(GameKeySlick.BUTTON_B)) {
      loadConfig(NullpoMinoSlick.propConfig);
      game.enterState(StateConfigMainMenu.ID);
    }
  }
  /*
   * Draw the screen
   */
  @Override
  protected void renderImpl(GameContainer container, StateBasedGame game, Graphics g)
      throws SlickException {
    // Background
    g.drawImage(ResourceHolderSlick.imgMenu, 0, 0);

    // Basic Options
    if (cursor < 17) {
      NormalFontSlick.printFontGrid(
          1, 1, "GENERAL OPTIONS: BASIC (1/3)", NormalFontSlick.COLOR_ORANGE);
      NormalFontSlick.printFontGrid(1, 3 + cursor, "b", NormalFontSlick.COLOR_RED);

      NormalFontSlick.printFontGrid(2, 3, "SE:" + GeneralUtil.getOorX(se), (cursor == 0));
      NormalFontSlick.printFontGrid(2, 4, "BGM:" + GeneralUtil.getOorX(bgm), (cursor == 1));
      NormalFontSlick.printFontGrid(
          2, 5, "BGM PRELOAD:" + GeneralUtil.getOorX(bgmpreload), (cursor == 2));
      NormalFontSlick.printFontGrid(
          2, 6, "SE VOLUME:" + sevolume + "(" + (sevolume * 100 / 128) + "%)", (cursor == 3));
      NormalFontSlick.printFontGrid(
          2, 7, "BGM VOLUME:" + bgmvolume + "(" + (bgmvolume * 100 / 128) + "%)", (cursor == 4));
      NormalFontSlick.printFontGrid(
          2, 8, "SHOW BACKGROUND:" + GeneralUtil.getOorX(showbg), (cursor == 5));
      NormalFontSlick.printFontGrid(
          2, 9, "USE BACKGROUND FADE:" + GeneralUtil.getOorX(heavyeffect), (cursor == 6));
      NormalFontSlick.printFontGrid(
          2, 10, "SHOW LINE EFFECT:" + GeneralUtil.getOorX(showlineeffect), (cursor == 7));
      NormalFontSlick.printFontGrid(
          2, 11, "LINE EFFECT SPEED:" + "X " + (lineeffectspeed + 1), (cursor == 8));
      NormalFontSlick.printFontGrid(
          2, 12, "SHOW METER:" + GeneralUtil.getOorX(showmeter), (cursor == 9));
      NormalFontSlick.printFontGrid(
          2, 13, "DARK NEXT AREA:" + GeneralUtil.getOorX(darknextarea), (cursor == 10));
      NormalFontSlick.printFontGrid(
          2, 14, "SHOW NEXT ABOVE SHADOW:" + GeneralUtil.getOorX(nextshadow), (cursor == 11));
      NormalFontSlick.printFontGrid(
          2, 15, "NEXT DISPLAY TYPE:" + NEXTTYPE_OPTIONS[nexttype], (cursor == 12));
      NormalFontSlick.printFontGrid(
          2, 16, "OUTLINE GHOST PIECE:" + GeneralUtil.getOorX(outlineghost), (cursor == 13));
      NormalFontSlick.printFontGrid(
          2,
          17,
          "FIELD BG BRIGHT:" + fieldbgbright + "(" + (fieldbgbright * 100 / 255) + "%)",
          (cursor == 14));
      NormalFontSlick.printFontGrid(
          2, 18, "SHOW FIELD BG GRID:" + GeneralUtil.getOorX(showfieldbggrid), (cursor == 15));
      NormalFontSlick.printFontGrid(
          2, 19, "SHOW CONTROLLER INPUT:" + GeneralUtil.getOorX(showInput), (cursor == 16));
    }
    // Advanced Options
    else if (cursor < 23) {
      NormalFontSlick.printFontGrid(
          1, 1, "GENERAL OPTIONS: ADVANCED (2/3)", NormalFontSlick.COLOR_ORANGE);
      NormalFontSlick.printFontGrid(1, 3 + (cursor - 17), "b", NormalFontSlick.COLOR_RED);

      NormalFontSlick.printFontGrid(
          2, 3, "FULLSCREEN:" + GeneralUtil.getOorX(fullscreen), (cursor == 17));
      NormalFontSlick.printFontGrid(
          2, 4, "SHOW FPS:" + GeneralUtil.getOorX(showfps), (cursor == 18));
      NormalFontSlick.printFontGrid(2, 5, "MAX FPS:" + maxfps, (cursor == 19));
      NormalFontSlick.printFontGrid(
          2, 6, "FRAME STEP:" + GeneralUtil.getOorX(enableframestep), (cursor == 20));
      NormalFontSlick.printFontGrid(
          2, 7, "FPS PERFECT MODE:" + GeneralUtil.getOorX(alternateFPSPerfectMode), (cursor == 21));
      NormalFontSlick.printFontGrid(
          2,
          8,
          "FPS PERFECT YIELD:" + GeneralUtil.getOorX(alternateFPSPerfectYield),
          (cursor == 22));
    }
    // Slick Options
    else {
      NormalFontSlick.printFontGrid(
          1, 1, "GENERAL OPTIONS: SLICK (3/3)", NormalFontSlick.COLOR_ORANGE);
      NormalFontSlick.printFontGrid(1, 3 + (cursor - 23), "b", NormalFontSlick.COLOR_RED);

      NormalFontSlick.printFontGrid(
          2, 3, "BGM STREAMING:" + GeneralUtil.getOorX(bgmstreaming), (cursor == 23));
      NormalFontSlick.printFontGrid(2, 4, "VSYNC:" + GeneralUtil.getOorX(vsync), (cursor == 24));
      NormalFontSlick.printFontGrid(
          2, 5, "FPS SLEEP TIMING:" + (alternateFPSTiming ? "UPDATE" : "RENDER"), (cursor == 25));
      NormalFontSlick.printFontGrid(
          2,
          6,
          "FPS DYNAMIC ADJUST:" + GeneralUtil.getOorX(alternateFPSDynamicAdjust),
          (cursor == 26));
      NormalFontSlick.printFontGrid(
          2,
          7,
          "SCREEN SIZE:"
              + SCREENSIZE_TABLE[screenSizeType][0]
              + "e"
              + SCREENSIZE_TABLE[screenSizeType][1],
          (cursor == 27));
    }

    if ((cursor >= 0) && (cursor < UI_TEXT.length))
      NormalFontSlick.printTTFFont(16, 432, NullpoMinoSlick.getUIText(UI_TEXT[cursor]));
  }