private Table makeGameFileRow(final FileHandle gameSaveFile) {
    GameSave towerData;
    try {
      towerData = GameSaveFactory.readMetadata(gameSaveFile.read());
    } catch (Exception e) {
      Gdx.app.log(TAG, "Failed to parse file.", e);
      return null;
    }

    FileHandle imageFile =
        Gdx.files.external(TowerConsts.GAME_SAVE_DIRECTORY + gameSaveFile.name() + ".png");

    Actor imageActor = null;
    if (imageFile.exists()) {
      try {
        imageActor = new Image(loadTowerImage(imageFile), Scaling.fit, Align.top);
      } catch (Exception ignored) {
        imageActor = null;
      }
    }

    if (imageActor == null) {
      imageActor = FontManager.Default.makeLabel("No image.");
    }

    Table fileRow = new Table();
    fileRow.defaults().fillX().pad(Display.devicePixel(10)).space(Display.devicePixel(10));
    fileRow.row();
    fileRow.add(imageActor).width(Display.devicePixel(64)).height(Display.devicePixel(64)).center();
    fileRow.add(makeGameFileInfoBox(fileRow, gameSaveFile, towerData)).expandX().top();
    fileRow.row().fillX();
    fileRow.add(new HorizontalRule(Color.DARK_GRAY, 2)).colspan(2);

    return fileRow;
  }
 private Image makeLibGDXLogo(TextureAtlas atlas) {
   Image libGdxLogo = new Image(atlas.findRegion("powered-by-libgdx"));
   libGdxLogo.getColor().a = 0f;
   libGdxLogo.addAction(Actions.fadeIn(0.125f));
   libGdxLogo.setY(Display.devicePixel(5));
   libGdxLogo.setX(Display.devicePixel(5));
   libGdxLogo.addListener(
       new VibrateClickListener() {
         @Override
         public void onClick(InputEvent event, float x, float y) {
           Platform.getBrowserUtil().launchWebBrowser("http://libgdx.badlogicgames.com");
         }
       });
   return libGdxLogo;
 }
 private Image makeHappyDroidsLogo(TextureAtlas atlas) {
   Image happyDroidsLogo = new Image(atlas.findRegion("happy-droids-logo"));
   happyDroidsLogo.getColor().a = 0f;
   happyDroidsLogo.addAction(Actions.fadeIn(0.125f));
   happyDroidsLogo.setX(
       getStage().getWidth() - happyDroidsLogo.getWidth() - Display.devicePixel(5));
   happyDroidsLogo.setY(Display.devicePixel(5));
   happyDroidsLogo.addListener(
       new VibrateClickListener() {
         @Override
         public void onClick(InputEvent event, float x, float y) {
           Platform.getBrowserUtil().launchWebBrowser(TowerConsts.HAPPYDROIDS_URI);
         }
       });
   return happyDroidsLogo;
 }
public class MainMenuScene extends SplashScene {
  private static final String TAG = MainMenuScene.class.getSimpleName();
  public static final int BUTTON_WIDTH = Display.devicePixel(280);
  public static final int BUTTON_SPACING = Display.devicePixel(16);

  private boolean builtOutMenu;

  @Override
  public void create(Object... args) {
    super.create(args);

    Label versionLabel =
        FontManager.Default.makeLabel(
            String.format(
                "v%s (%s, %s)",
                TowerConsts.VERSION,
                TowerConsts.GIT_SHA.substring(0, 8),
                TowerGameService.getDeviceOSMarketName()));
    versionLabel.setColor(Color.LIGHT_GRAY);
    versionLabel.setX(getStage().getWidth() - versionLabel.getWidth() - 5);
    versionLabel.setY(getStage().getHeight() - versionLabel.getHeight() - 5);
    addActor(versionLabel);
  }

  @Override
  public void pause() {}

  @Override
  public void resume() {}

  @Override
  public void render(float deltaTime) {
    super.render(deltaTime);

    if (!builtOutMenu && preloadFinished()) {
      builtOutMenu = true;

      buildMenuComponents(textureAtlas("hud/menus.txt"));

      SecurePreferences preferences = TowerGameService.instance().getPreferences();

      if (Display.isInCompatibilityMode()) {
        if (!preferences.getBoolean("ANDROID_WARNED_ABOUT_DISPLAY_MODE", false)) {
          preferences.putBoolean("ANDROID_WARNED_ABOUT_DISPLAY_MODE", true);
          Platform.getDialogOpener()
              .showAlert(
                  "Compatibility Mode",
                  "Hello,\n\nWe're sorry but this game is designed for a device with a higher resolution screen.  "
                      + "It is impossible for us to restrict these devices from the market, so we have "
                      + "designed a compatability mode as a work around.\n\nYou can continue to play the game, "
                      + "but please understand your experience will be degraded.  Most commonly the text will be rather difficult to read.\n\n"
                      + "Thank you,\nDroid Towers Team");
        }
      }
      // new GridObjectDesigner(getStage()).show();
    }
  }

  private void buildMenuComponents(final TextureAtlas menuButtonAtlas) {
    if (progressPanel != null) {
      progressPanel.remove();
    }

    addActor(makeLibGDXLogo(menuButtonAtlas));
    addActor(makeHappyDroidsLogo(menuButtonAtlas));

    MainMenuButtonPanel menuButtonPanel = new MainMenuButtonPanel();
    menuButtonPanel.pack();
    menuButtonPanel.setY(droidTowersLogo.getY() - menuButtonPanel.getHeight());
    menuButtonPanel.setX(-droidTowersLogo.getImageWidth());
    addActor(menuButtonPanel);

    Tween.to(menuButtonPanel, WidgetAccessor.POSITION, CAMERA_PAN_DOWN_DURATION)
        .target(
            50 + (45 * (droidTowersLogo.getImageWidth() / droidTowersLogo.getWidth())),
            menuButtonPanel.getY())
        .ease(TweenEquations.easeInOutExpo)
        .start(TweenSystem.manager());
  }

  @Override
  public void dispose() {}

  private Image makeHappyDroidsLogo(TextureAtlas atlas) {
    Image happyDroidsLogo = new Image(atlas.findRegion("happy-droids-logo"));
    happyDroidsLogo.getColor().a = 0f;
    happyDroidsLogo.addAction(Actions.fadeIn(0.125f));
    happyDroidsLogo.setX(
        getStage().getWidth() - happyDroidsLogo.getWidth() - Display.devicePixel(5));
    happyDroidsLogo.setY(Display.devicePixel(5));
    happyDroidsLogo.addListener(
        new VibrateClickListener() {
          @Override
          public void onClick(InputEvent event, float x, float y) {
            Platform.getBrowserUtil().launchWebBrowser(TowerConsts.HAPPYDROIDS_URI);
          }
        });
    return happyDroidsLogo;
  }

  private Image makeLibGDXLogo(TextureAtlas atlas) {
    Image libGdxLogo = new Image(atlas.findRegion("powered-by-libgdx"));
    libGdxLogo.getColor().a = 0f;
    libGdxLogo.addAction(Actions.fadeIn(0.125f));
    libGdxLogo.setY(Display.devicePixel(5));
    libGdxLogo.setX(Display.devicePixel(5));
    libGdxLogo.addListener(
        new VibrateClickListener() {
          @Override
          public void onClick(InputEvent event, float x, float y) {
            Platform.getBrowserUtil().launchWebBrowser("http://libgdx.badlogicgames.com");
          }
        });
    return libGdxLogo;
  }
}
  private Table makeGameFileInfoBox(
      final Table fileRow, final FileHandle savedGameFile, GameSave towerData) {
    TextButton launchButton = FontManager.RobotoBold18.makeTextButton("Play");
    launchButton.addListener(
        new VibrateClickListener() {
          @Override
          public void onClick(InputEvent event, float x, float y) {
            dismiss();
            try {
              SceneManager.changeScene(
                  LoadTowerSplashScene.class, GameSaveFactory.readFile(savedGameFile));
            } catch (Exception e) {
              throw new RuntimeException(e);
            }
          }
        });

    TextButton deleteButton = FontManager.RobotoBold18.makeTextButton("Delete");
    deleteButton.addListener(
        new VibrateClickListener() {
          @Override
          public void onClick(InputEvent event, float x, float y) {
            new Dialog()
                .setTitle("Are you sure you want to delete this Tower?")
                .setMessage("If you delete this tower, it will disappear forever.\n\nAre you sure?")
                .addButton(
                    "Yes, delete it",
                    new OnClickCallback() {
                      @Override
                      public void onClick(Dialog dialog) {
                        savedGameFile.delete();

                        content.getCell(fileRow).ignore();
                        content.removeActor(fileRow);
                        content.invalidate();

                        dialog.dismiss();
                      }
                    })
                .addButton(
                    "Keep it!",
                    new OnClickCallback() {
                      @Override
                      public void onClick(Dialog dialog) {
                        dialog.dismiss();
                      }
                    })
                .show();
          }
        });

    Table metadata = new Table();
    metadata.defaults().top().left().fillX();
    addLabelRow(metadata, towerData.getTowerName(), FontManager.RobotoBold18, Color.WHITE);
    addLabelRow(
        metadata,
        "Population: " + getNumberInstance().format(towerData.getPlayer().getTotalPopulation()),
        FontManager.Default,
        Color.GRAY);
    Date lastPlayed = towerData.getMetadata().lastPlayed;
    if (lastPlayed != null) {
      PrettyTime prettyTime = new PrettyTime();
      addLabelRow(
          metadata,
          "Last played: " + prettyTime.format(lastPlayed),
          FontManager.Default,
          Color.GRAY);
    }

    Table box = new Table();
    box.defaults().fillX().space(Display.devicePixel(5));
    box.row().top().left().fillX();
    box.add(metadata).top().left().expandX();
    box.add(deleteButton).width(Display.devicePixel(80));
    box.add(launchButton).width(Display.devicePixel(80));

    return box;
  }