/**
   * Attempts to search the mod website for the mod and pull the recent versions of the mod.
   *
   * @param mod The Mod to search for on the website.
   * @param modInfoList The JList to populate/alter.
   */
  public void getRecentVersionsOfModAsync(Profile.Mod mod, JList modInfoList) {
    // Here we set a thread task to get the version numbers for the mod. This will look at the site
    // and search for the mod, then pull all versions from it.
    Runnable task = () -> Crawler.readVersionInfoOfMod(mod.nameWithoutVersion);
    Thread thread = new Thread(task);
    thread.start();

    // Our timer that checks every 200ms if the thread has finished.
    Timer timer = new Timer(200, null);
    timer.addActionListener(
        ev -> {
          if (thread.getState() != Thread.State.TERMINATED) timer.restart();
          else {
            timer.stop();
            DefaultListModel listModel = (DefaultListModel) modInfoList.getModel();
            // Get the modVersionInfo from the crawler. If not null, add to the list.
            String[][] modVersionInfo = Crawler.getModVersionInfo();
            if (modVersionInfo != null) {
              listModel.addElement("Recent Versions:");
              for (String[] info : modVersionInfo) {
                listModel.addElement("    v" + info[0] + " for " + info[1]);
              }
            } else {
              listModel.addElement("Couldn't find the mod on the website.");
            }
            modInfoList.setModel(listModel);
          }
        });
    timer.start();
  }
  /** Pulls the recently updated mods from the mod website. */
  public void downloadRecentModList() {
    Runnable task = () -> Crawler.processFilter("http://www.factoriomods.com/recently-updated", 1);
    Thread thread = new Thread(task);
    thread.start();
    final javax.swing.Timer timer = new javax.swing.Timer(100, null);
    timer.addActionListener(
        ev -> {
          if (thread.getState() != Thread.State.TERMINATED) timer.restart();
          else {
            System.out.println("Done with page");
            timer.stop();

            ArrayList<String[]> modInfoListFromBrowser = Crawler.getSpecificFilterModsInfo();
            DefaultTableModel model = new DefaultTableModel(new String[] {"", "", "", ""}, 0);
            for (String[] info : modInfoListFromBrowser) model.addRow(info);

            this.window.setModBrowserTableModel(model);
          }
        });

    timer.start();
  }
  /**
   * Downloads a version of a mod.
   *
   * @param modVersion The version text for the mod.
   * @param selectedIndex The selected index from the UI.
   */
  public void downloadVersionOfMod(String modVersion, int selectedIndex) {
    // Trim whitespace and check if we have a 'v0.1' or some match.
    if (modVersion.trim().matches("v\\d+.*")) {
      selectedIndex =
          selectedIndex
              - 4; // 4 is our magic number. We have 4 lines before this one so we subtract 4 to get
      // the adjusted index.
      String[][] info = Crawler.getModVersionInfo();
      String path =
          this.model.getFactorioModManagerPath()
              + this.model.getCurrentlySelectedProfile()
              + "/"
              + this.model.getCurrentlySelectedModName()
              + "_"
              + info[selectedIndex][Crawler.ModVersionInfo.VERSION.getValue()]
              + ".zip";

      // TODO Who knows, this doesn't work. Downloads empty file.
      // Create a new file and try to download into it.
      File file = new File(path);
      try {
        // URL url = new URL(info[selectedIndex][Crawler.ModVersionInfo.DOWNLOAD.getValue()]);
        // HttpURLConnection con = (HttpURLConnection)url.openConnection();
        // InputStream stream = con.getInputStream();
        // Files.copy(stream, Paths.get(path));
        org.apache.commons.io.FileUtils.copyURLToFile(
            new URL(info[selectedIndex][Crawler.ModVersionInfo.DOWNLOAD.getValue()]),
            file,
            2000,
            2000);
      } catch (IOException e) {
        e.printStackTrace();
      }

      System.out.println(
          "Index: " + info[selectedIndex][Crawler.ModVersionInfo.DOWNLOAD.getValue()]);
    }
  }