content: /*
   * The MIT License (MIT)
   *
   * Copyright (c) 2011-2021 Broad Institute, Aiden Lab, Rice University, Baylor College of Medicine
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   *  FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
   *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   *  THE SOFTWARE.
   */
  
  package juicebox.windowui;
  
  import de.erichseifert.vectorgraphics2d.PDFGraphics2D;
  import de.erichseifert.vectorgraphics2d.ProcessingPipeline;
  import de.erichseifert.vectorgraphics2d.SVGGraphics2D;
  import juicebox.HiC;
  import juicebox.HiCGlobals;
  import juicebox.MainWindow;
  
  import javax.swing.*;
  import java.awt.*;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  
  
  public class SaveImageDialog extends JFileChooser {
  
      private static final long serialVersionUID = 9000014;
      private JTextField width;
      private JTextField height;
  
      public SaveImageDialog(String saveImagePath, final HiC hic, final MainWindow mainWindow, final JPanel hiCPanel,
                             final String extension) {
          super();
          if (saveImagePath != null) {
              setSelectedFile(new File(saveImagePath));
          } else {
              String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
              setSelectedFile(new File(timeStamp + ".HiCImage" + extension));
  
          }
          if (HiCGlobals.guiIsCurrentlyActive) {
              int actionDialog = showSaveDialog(mainWindow);
              if (actionDialog == JFileChooser.APPROVE_OPTION) {
                  File selectedFile = getSelectedFile();
                  final File outputFile;
                  if (selectedFile.getPath().endsWith(".svg") || selectedFile.getPath().endsWith(".SVG")
                          || selectedFile.getPath().endsWith(".pdf") || selectedFile.getPath().endsWith(".PDF")) {
                      outputFile = selectedFile;
                  } else {
                      outputFile = new File(selectedFile + extension);
                  }
                  //saveImagePath = file.getPath();
                  if (outputFile.exists()) {
                      actionDialog = JOptionPane.showConfirmDialog(MainWindow.getInstance(), "Replace existing file?");
                      if (actionDialog == JOptionPane.NO_OPTION || actionDialog == JOptionPane.CANCEL_OPTION)
                          return;
                  }
  
                  mainWindow.executeLongRunningTask(new Runnable() {
                      @Override
                      public void run() {
                          try {
                              int w = Integer.parseInt(width.getText());
                              int h = Integer.parseInt(height.getText());
                              if (HiCGlobals.printVerboseComments) System.out.println("Exporting another figure");
                              if (outputFile.getPath().endsWith(".svg") || outputFile.getPath().endsWith(".SVG")) {
                                  exportAsSVG(outputFile, mainWindow, hic, hiCPanel, w, h);
                              } else {
                                  exportAsPDF(outputFile, mainWindow, hic, hiCPanel, w, h);
                              }
                          } catch (NumberFormatException error) {
                              JOptionPane.showMessageDialog(mainWindow, "Width and Height must be integers", "Error",
                                      JOptionPane.ERROR_MESSAGE);
                          }
                      }
                  }, "Exporting Figure", "Exporting...");
              }
          }
      }
  
      protected JDialog createDialog(Component parent) {
          JDialog myDialog = super.createDialog(parent);
          JLabel wLabel = new JLabel("Width");
          JLabel hLabel = new JLabel("Height");
          width = new JTextField("" + MainWindow.getInstance().getWidth());
          width.setColumns(6);
          height = new JTextField("" + MainWindow.getInstance().getHeight());
          height.setColumns(6);
          JPanel panel = new JPanel();
          panel.add(wLabel);
          panel.add(width);
          panel.add(hLabel);
          panel.add(height);
          myDialog.add(panel, BorderLayout.NORTH);
          return myDialog;
      }
  
      private void exportAsPDF(File file, MainWindow mainWindow, HiC hic, final JPanel hiCPanel,
                               final int w, final int h) {
          try {
              PDFGraphics2D g = new PDFGraphics2D(0, 0, w, h);
              plotDataOnGraphics(g, mainWindow, w, h, hic, hiCPanel);
              writeGraphicsToFile(g, file);
          } catch (Exception e) {
              System.err.println("Export PDF failed " + e);
          }
      }
  
      private void exportAsSVG(File file, MainWindow mainWindow, HiC hic, final JPanel hiCPanel,
                               final int w, final int h) {
          try {
              SVGGraphics2D g = new SVGGraphics2D(0, 0, w, h);
              plotDataOnGraphics(g, mainWindow, w, h, hic, hiCPanel);
              writeGraphicsToFile(g, file);
          } catch (Exception e) {
              System.err.println("Export SVG failed " + e);
          }
      }
  
      private void writeGraphicsToFile(ProcessingPipeline g, File file) throws IOException {
          try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
              fileOutputStream.write(g.getBytes());
          }
      }
  
      private void plotDataOnGraphics(Graphics g, final MainWindow mainWindow, final int w, final int h, final HiC hic,
                                      final JPanel hiCPanel) {
          // Print the panel on created graphics.
          if (w == mainWindow.getWidth() && h == mainWindow.getHeight()) {
              hiCPanel.printAll(g);
          } else {
              JDialog waitDialog = new JDialog();
              JPanel panel1 = new JPanel();
              panel1.add(new JLabel("  Creating and saving " + w + " by " + h + " image  "));
              //panel1.setPreferredSize(new Dimension(250,50));
              waitDialog.add(panel1);
              waitDialog.setTitle("Please wait...");
              waitDialog.pack();
              waitDialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
  
              waitDialog.setLocation(100, 100);
              waitDialog.setVisible(true);
              mainWindow.setVisible(false);
  
              Dimension minSize = mainWindow.getMinimumSize();
              Dimension prefSize = mainWindow.getPreferredSize();
  
              hic.centerBP(0, 0);
              mainWindow.setMinimumSize(new Dimension(w, h));
              mainWindow.setPreferredSize(new Dimension(w, h));
              mainWindow.pack();
  
              mainWindow.setState(Frame.ICONIFIED);
              mainWindow.setState(Frame.NORMAL);
              mainWindow.setVisible(true);
              mainWindow.setVisible(false);
  
              final Runnable painter = new Runnable() {
                  public void run() {
                      hiCPanel.paintImmediately(0, 0, w, h);
                  }
              };
  
              Thread thread = new Thread(painter) {
                  public void run() {
                      try {
                          SwingUtilities.invokeAndWait(painter);
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
              };
  
              thread.start();
              hiCPanel.printAll(g);
              mainWindow.setPreferredSize(prefSize);
              mainWindow.setMinimumSize(minSize);
              mainWindow.setSize(new Dimension(w, h));
              waitDialog.setVisible(false);
              waitDialog.dispose();
              mainWindow.setVisible(true);
          }
      }
  }