/******************************************************************************
* Copyright 1996-2014 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
******************************************************************************/

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import javax.swing.*;

/** The CDFLeapSecondsInfo tool program which can be run either from the CDFTools 
    driver or as an application, will show the information about the leap
    seconds that is used by the CDF distribution.
 */ 

public class CDFLeapSecondsInfo extends JFrame 
			 implements ActionListener, ItemListener, Runnable {

    static final long serialVersionUID = 1L;
    static int macLib = 0;
    static String cdfbase = null;
    static String libcdfPath = null;

    JFrame parentFrame;
/** dialog for user interface. */
    JDialog dialog;

    JPanel panelx = new JPanel(new BorderLayout(), true);
/** The panel for selectable buttons which goes to dialog's north portion. */
    JPanel panel1 = new JPanel(new GridBagLayout(), true);
/** The panel for run/help/quit buttons. */
    JPanel panel21 = new JPanel(new GridLayout(1, 3, 50, 20), true);
/** The panel containing panel21 goes to dialog's center portion. */
    JPanel panel2 = new JPanel(new BorderLayout(), true);
/** The panel for text area which goes to dialog's south portion. */
    JPanel panel3 = new JPanel(new BorderLayout(), true);

/** "Dump" checkbox. */
    JCheckBox dpc = new JCheckBox("Nodump",true);
/** "About" checkbox. */
    JCheckBox abc = new JCheckBox("About");

/** "Run CDFLeapSecondsInfo" button. */
    JButton entrb = new JButton(" Enter ");
/** "Help" button. */
    JButton helpb = new JButton(" Help ");
/** "Quit" button. */
    JButton quitb = new JButton(" Quit ");

/** Text area for information. */
    JTextArea info = new JTextArea(30, 60);

/** Scroll pane for the text area. */
    JScrollPane scroller;

/** command string. */
    String command = "cdfleapsecondsinfo ";
    String commandX;
    String[] cmds = new String[3];
    String strdp = "-nodump";

/** The file separator. */
    String separator = System.getProperty("file.separator");
/** A platform-dependent Runtime object. */
    Runtime runtime = Runtime.getRuntime();
/** A separate process to run the command. */ 
    Process process = null;
    int hlp = 0;
    int abx = 0;

/** Menu bar. */
    JMenuBar menuBar = new JMenuBar();
/** A menu: File. */
    JMenu menuFile = new JMenu("File");
/** A menu: Help. */
    JMenu menuHelp = new JMenu("Help");
/** A File menu item: Exit. */
    JMenuItem menuFileExit = new JMenuItem("Exit");
/** A Help menu item: Help. */
    JMenuItem menuHelpHelp = new JMenuItem("Help");

    Dimension hpad5 = new Dimension(5,1);
    Dimension hpad10 = new Dimension(10,1);
    Dimension hpad20 = new Dimension(20,1);
    Dimension hpad25 = new Dimension(25,1);
    Dimension hpad30 = new Dimension(30,1);
    Dimension hpad40 = new Dimension(40,1);
    Dimension hpad50 = new Dimension(50,1);
    Dimension vpad5 = new Dimension(1,5);
    Dimension vpad10 = new Dimension(1,10);
    Dimension vpad20 = new Dimension(1,20);
    Dimension vpad25 = new Dimension(1,25);
    Dimension vpad30 = new Dimension(1,30);
    Dimension vpad40 = new Dimension(1,40);
    Dimension vpad50 = new Dimension(1,50);

    Font  defaultFont = new Font("Dialog", Font.PLAIN, 12);
    Font  boldFont = new Font("Dialog", Font.BOLD, 12);
    Font  bigFont = new Font("Dialog", Font.PLAIN, 18);
    Font  bigboldFont = new Font("Dialog", Font.BOLD, 18);
    static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    static int INITIAL_WIDTH = 550;
    static int INITIAL_HEIGHT = 350;

/** The default dialog modal (is set to false). */
    static boolean defaultModal = false;
/** The current dialog modal. */
    boolean modal;
    int frommain = 0;

    CDFLeapSecondsInfo() {
	this(null, null, defaultModal);
    }

    CDFLeapSecondsInfo(JFrame parentFrame) {
        this(parentFrame, null, defaultModal);
    }

    CDFLeapSecondsInfo(JFrame parentFrame, String cdfbase) {
        this(parentFrame, cdfbase, defaultModal);
    }

    CDFLeapSecondsInfo(JFrame parentFrame, String cdfbase, boolean modal) {
        if (cdfbase == null) {
          cdfbase = System.getProperty("CDF_BASE");
          if (cdfbase == null)
            cdfbase = CDFToolsUtil.getenv("CDF_BASE");
        }
        if (cdfbase != null)
          command = cdfbase + separator + "bin" + separator + "cdfleapsecondsinfo ";
        else
          command = "cdfleapsecondsinfo ";
        dialog = new JDialog(this, modal);
	this.parentFrame = parentFrame;
        this.modal = modal;
    }

/** Set up the GUI stuff for user selection.
 */

    private void buildGUI() {

        WindowListener l = new WindowAdapter() {
           public void windowClosing(WindowEvent e) {
              if (frommain == 0) {
                if (modal) dialog.dispose();
                else dialog.setVisible(false);
		if (parentFrame != null) parentFrame.setVisible(true);
              } else {
		if (macLib == 1) new File(libcdfPath).delete();
		System.exit(1);
	      }
	   }
        };
        dialog.addWindowListener(l);
        dialog.setTitle("Parameters for CDFLeapSecondsInfo");
        dialog.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
        dialog.setLocation(screenSize.width/2 - INITIAL_WIDTH/2,
                          screenSize.height/2 - INITIAL_HEIGHT/2);
        dialog.getContentPane().setLayout(new BorderLayout());

        // set the menu bar
        dialog.setJMenuBar(menuBar);

        // add the file menu
        menuBar.add(menuFile);

        // add the menu items to file
        menuFile.add(menuFileExit);
        menuFileExit.addActionListener(this);

        // add the help menu
        menuBar.add(menuHelp);

        // add the menu items to help
        menuHelp.add(menuHelpHelp);
        menuHelpHelp.addActionListener(this);

        // Panel 1
	makeJButton(panel1, Box.createRigidArea(vpad10), 0, 0, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad50), 0, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, dpc, 1, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad50), 2, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad50), 3, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad50), 4, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel1, abc, 5, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad50), 6, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(vpad20), 0, 2, 1, 1, 1.0, 1.0);

	dpc.addItemListener(this);
        dpc.setToolTipText("Display the contents of the leap seconds table");
        abc.addItemListener(this);
        abc.setToolTipText("Display the current version");
//	dialog.getContentPane().add(panel1,BorderLayout.NORTH);
	panelx.add(panel1,BorderLayout.NORTH);
	

        // Panel 2
	
        panel21.add(entrb);
        panel21.add(helpb);
        panel21.add(quitb);
        panel2.add(panel21, BorderLayout.NORTH);
        panel2.add(Box.createRigidArea(vpad20),BorderLayout.SOUTH);
//	dialog.getContentPane().add(panel2,BorderLayout.CENTER);
	panelx.add(panel2,BorderLayout.CENTER);

        // Listen for events on buttons
        entrb.addActionListener(this);
        entrb.setToolTipText("Run CDFLeapSecondsInfo");
        helpb.addActionListener(this);
        helpb.setToolTipText("Get the complete help information");
        quitb.addActionListener(this);
        quitb.setToolTipText("Exit CDFLeapSecondsInfo");

	// Text Area
	info.setEditable(false);
        scroller = new JScrollPane() {
                static final long serialVersionUID = 1L;

                public Dimension getPreferredSize() {
                   return new Dimension(300, 200);
                }
                public float getAlignmentX() {
                   return LEFT_ALIGNMENT;
                }
        };

	scroller.getViewport().add(info);
//        panel3.add(scroller, BorderLayout.CENTER);
        info.setVisible(true);
//        dialog.getContentPane().add(panel3, BorderLayout.SOUTH);
        panelx.add(panel3, BorderLayout.SOUTH);

        dialog.getContentPane().add(panelx, BorderLayout.NORTH);
        dialog.getContentPane().add(scroller, BorderLayout.CENTER);


    }

/** Implement the run method for Runabout interface.
 */ 

    public void run() {
	buildGUI();
//	dialog.pack();
	dialog.setVisible(true);
	if (parentFrame != null) parentFrame.setVisible(false);

    }

/** Reenter from the main toolkit driver. Reset the dialog to visible. 
 */ 

    public void reEnter() {
	dialog.setVisible(true);
	if (parentFrame != null) parentFrame.setVisible(false);
	info.setText("");
    }


/** Action for buttons or menu items selection
 */

    public void actionPerformed(ActionEvent evt) {
	Object obj = evt.getSource();
        if (obj == quitb || obj == menuFileExit) { // for "Quit" button
              if (frommain == 0) { 
                if (modal) dialog.dispose();
                else dialog.setVisible(false);
		if (parentFrame != null) parentFrame.setVisible(true);
              } else {
		if (macLib == 1) new File(libcdfPath).delete();
		System.exit(1);
	      }
	} else if (obj == entrb) { // for "Enter" button
		if (dpc.isSelected()) strdp = "-nodump";
		else strdp = "-dump";
		commandX = command + strdp;
                String OS = System.getProperty("os.name").toLowerCase();
                if (OS.indexOf("windows") != -1) {
                    cmds[0] = commandX;
                } else if (OS.indexOf("vms") != -1) {
                    cmds[0] = commandX;
                } else {
                    cmds[0] = "/bin/sh";
                    cmds[1] = "-c";
                    cmds[2] = commandX;
                }
                runit(cmds);
                // runit(commandX);
	} else { // for "Help" button
		hlp = 1;
                commandX = command + " -java "; 
                String OS = System.getProperty("os.name").toLowerCase();
                if (OS.indexOf("windows") != -1) {
                    cmds[0] = commandX;
                } else if (OS.indexOf("vms") != -1) {
                    cmds[0] = commandX;
                } else {
                    cmds[0] = "/bin/sh";
                    cmds[1] = "-c";
                    cmds[2] = commandX;
                }
                runit(cmds);
                // runit(commandX);
	}
    }

/** Action for checkboxes selection
 */
    public void itemStateChanged(ItemEvent evt) {
	Object obj = evt.getSource();
	if (obj == abc) { // "About" checkbox
	  if (abc.isSelected()) {
		abx = 1;
		commandX = command + " -about";
                String OS = System.getProperty("os.name").toLowerCase();
                if (OS.indexOf("windows") != -1) {
                    cmds[0] = commandX;
                } else if (OS.indexOf("vms") != -1) {
                    cmds[0] = commandX;
                } else {
                    cmds[0] = "/bin/sh";
                    cmds[1] = "-c";
                    cmds[2] = commandX;
                }
                runit(cmds);
                // runit(commandX);
                abc.setSelected(false);
		abx = 0;
	  }
	} else if (obj == dpc) { // "Nodump" checkbox
		if (dpc.isSelected())
                   strdp = "-nodump";
                else
                   strdp = "-dump";
	}
    }

/** Set up gridbaglayout.
 */
    private void makeJButton(Container cont, Object arg,
            int x, int y, int w, int h, double weightx, double weighty) {
        GridBagLayout gbl = (GridBagLayout)cont.getLayout();
        GridBagConstraints c = new GridBagConstraints();
        Component comp;

        c.fill = GridBagConstraints.BOTH;
        c.gridx = x;
        c.gridy = y;
        c.gridwidth = w;
        c.gridheight = h;
        c.weightx = weightx;
        c.weighty = weighty;
        if (arg instanceof String) {
            comp = new JButton((String)arg);
        } else {
            comp = (Component)arg;
        }
        cont.add(comp);
        gbl.setConstraints(comp, c);
    }

/** Execute a command as a separate process for the user selection and returns 
    the results in the text area.
 */ 
    private void runit(String[] command) {
    // private void runit(String command) {
        try {
           String osName = System.getProperty("os.name");
           String cwd = System.getProperty("user.dir");
           libcdfPath = cwd + "/libcdf.dylib";
           if (osName.toLowerCase().indexOf("mac") != -1) {
               File libcdf = new File(libcdfPath);
               if (libcdf.exists()) {
                   macLib = 0;
               } else {
                 if (Files.isWritable(Paths.get(cwd))) {
                   try {
                     cdfbase = System.getProperty("CDF_BASE");
                     if (cdfbase == null)
                         cdfbase = CDFToolsUtil.getenv("CDF_BASE");
                     Files.copy(Paths.get(cdfbase+"/lib/libcdf.dylib"),
                                Paths.get(libcdfPath),
                                StandardCopyOption.REPLACE_EXISTING);
                     macLib = 1;
                   } catch (Exception ex) {
                     System.out.println ("**** Error for copying... "+ex);
                   }
                 }
               }
           }

	   if (command[1] != null) 
                  process = runtime.exec(command);
	   else
                  process = runtime.exec(command[0]);

	   info.setText("");
	   String line = null;
	   InputStreamReader inReader = new InputStreamReader(process.getInputStream(), "UTF-8");
	   BufferedReader inStream = new BufferedReader(inReader, 8192);

	   while ((line = inStream.readLine()) != null) {
                    info.append(line+"\n");
	   }
	   process.waitFor();
	   info.setCaretPosition(0);
	   if (process.exitValue() == 1) Toolkit.getDefaultToolkit().beep();
	   scroller.getViewport().setView(info);
	   scroller.revalidate();
	   scroller.repaint();
	   if (hlp == 1) hlp = 0;
        } catch (Exception e) {
	   info.setText("error executing: "+e);
	   Toolkit.getDefaultToolkit().beep();
        }
    }
/** This class can run as an application by its own.
 */
    static public void main(String[] args) {

        String cdfbase = System.getProperty("CDF_BASE");
        if (cdfbase == null)
          cdfbase = CDFToolsUtil.getenv("CDF_BASE");

        CDFLeapSecondsInfo thispgm = new CDFLeapSecondsInfo(null, cdfbase);
        thispgm.frommain = 1;
	thispgm.run();
    }

}
