/**
   * Opens a dialog asking the user to choose a file which is is used for saving to.
   *
   * @param parent the parent component the dialog is centered on
   * @param titleKey the key for the locale-specific string to use for the file dialog title
   * @param suggestedFile the suggested file for saving
   * @param the filter to use for what's shown.
   * @return the file or <code>null</code> when the user cancelled the dialog
   */
  public static File getSaveAsFile(
      Component parent, String titleKey, File suggestedFile, final FileFilter filter) {
    if (OSUtils.isAnyMac()) {
      FileDialog dialog =
          new FileDialog(GUIMediator.getAppFrame(), I18n.tr(titleKey), FileDialog.SAVE);
      dialog.setDirectory(suggestedFile.getParent());
      dialog.setFile(suggestedFile.getName());
      if (filter != null) {
        FilenameFilter f =
            new FilenameFilter() {
              public boolean accept(File dir, String name) {
                return filter.accept(new File(dir, name));
              }
            };
        dialog.setFilenameFilter(f);
      }

      dialog.setVisible(true);
      String dir = dialog.getDirectory();
      setLastInputDirectory(new File(dir));
      String file = dialog.getFile();
      if (dir != null && file != null) {

        if (suggestedFile != null) {
          String suggestedFileExtension = FileUtils.getFileExtension(suggestedFile);

          String newFileExtension = FileUtils.getFileExtension(file);

          if (newFileExtension == null && suggestedFileExtension != null) {
            file = file + "." + suggestedFileExtension;
          }
        }

        File f = new File(dir, file);
        if (filter != null && !filter.accept(f)) return null;
        else return f;
      } else {
        return null;
      }
    } else {
      JFileChooser chooser =
          getDirectoryChooser(titleKey, null, null, JFileChooser.FILES_ONLY, filter);
      chooser.setSelectedFile(suggestedFile);
      int ret = chooser.showSaveDialog(parent);
      File file = chooser.getSelectedFile();
      setLastInputDirectory(file);
      return ret != JFileChooser.APPROVE_OPTION ? null : file;
    }
  }
  private void handleCoreDownloader() {
    File possibleTorrentFile = null;

    possibleTorrentFile = downloader.getSaveFile();
    String fileExtension = FileUtils.getFileExtension(possibleTorrentFile);
    if ("torrent".equalsIgnoreCase(fileExtension)) {
      try {
        shareTorrentFile(possibleTorrentFile);
        downloadManager.downloadTorrent(possibleTorrentFile, null, false);
        downloadItems.remove(getDownloadItem(downloader));
      } catch (DownloadException e) {
        final File torrentFile = possibleTorrentFile;
        activityCallback.handleDownloadException(
            new DownloadAction() {
              @Override
              public void download(File saveDirectory, boolean overwrite) throws DownloadException {
                downloadManager.downloadTorrent(torrentFile, saveDirectory, overwrite);
                downloadItems.remove(getDownloadItem(downloader));
              }

              @Override
              public void downloadCanceled(DownloadException ignored) {
                // nothing to do
              }
            },
            e,
            false);
      }
    }
  }
  private void recursiveButtonSearch(Container container) {
    for (Component component : container.getComponents()) {
      if (component instanceof Container) {
        recursiveButtonSearch((Container) component);
      }
      if (component instanceof JButton) {
        JButton button = (JButton) component;
        String buttonText = button.getText();

        // Using end of button text to determine whether button shouild be disabled
        // then disable it.  This is because JEditorPane does not disable buttons
        // disabled in the form html
        if (buttonText.endsWith(":disabled")) {
          buttonText = buttonText.substring(0, buttonText.lastIndexOf(":disabled"));
          button.setText(buttonText);
          button.setEnabled(false);
        }

        String extension = FileUtils.getFileExtension(buttonText);
        if (!extension.isEmpty()) {
          Icon icon = iconManager.get().getIconForExtension(extension);
          button.setIcon(icon);
        }
      }
    }
  }
  public static void populateProperties(
      String fileName,
      long fileSize,
      long creationTime,
      Map<FilePropertyKey, Object> properties,
      LimeXMLDocument doc) {

    properties.put(FilePropertyKey.NAME, ""); // Make sure name defaults to empty.
    set(properties, FilePropertyKey.NAME, FileUtils.getFilenameNoExtension(fileName));
    set(properties, FilePropertyKey.DATE_CREATED, creationTime);
    set(properties, FilePropertyKey.FILE_SIZE, fileSize);

    String extension = FileUtils.getFileExtension(fileName);
    Category category = CategoryConverter.categoryForExtension(extension);

    if (doc != null) {
      for (FilePropertyKey filePropertyKey : FilePropertyKey.values()) {
        set(properties, doc, category, filePropertyKey);
      }

      Long bitrate, length;
      Integer quality;
      switch (category) {
        case AUDIO:
          bitrate = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.AUDIO_BITRATE));
          length = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.AUDIO_SECONDS));
          quality = toAudioQualityScore(extension, fileSize, bitrate, length);
          set(properties, FilePropertyKey.QUALITY, quality);
          break;
        case VIDEO:
          bitrate = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_BITRATE));
          length = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_LENGTH));
          Long height = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_HEIGHT));
          Long width = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_WIDTH));
          quality = toVideoQualityScore(extension, fileSize, bitrate, length, height, width);
          set(properties, FilePropertyKey.QUALITY, quality);
          break;
      }
    }
  }