/******************************************************************************
* 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.*;
import java.awt.datatransfer.*;
import gsfc.nssdc.cdf.*;

/** CDFMerge is used to merge CDFs.  Two source CDFs and the output, merged file
    can be entered physically. Alternatively, the source and output files can
    be specified in a text file and use it to control what to merge and to where.
    If use the text file to control the process, more than two files can be
    specified and the last file is reserved as the output file.
 */

public class CDFMerge extends JFrame 
		      implements ActionListener, ItemListener, 
			         MouseListener, FocusListener, Runnable {

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

    JFrame parentDriver;
/** The dialog for user interface. */
    JDialog dialog;
    JPanel panelx = new JPanel(new BorderLayout(), true);

/** The FileChooser for the file selection. */
    JFileChooser fileChooser = new JFileChooser();

/** The panel for text fields and selectable buttons which goes to dialog's
    north portion. */
    JPanel panel1 = new JPanel(new GridBagLayout(), true);
/** The panel containing all checkboxes goes to dialog's center portion. */
    JPanel panel2 = new JPanel(new BorderLayout(), true);
//    JPanel panel2n = new JPanel(new GridBagLayout(), true);
    JPanel panel2c = new JPanel(new GridBagLayout(), true);
    JPanel panel2s = new JPanel(new GridBagLayout(), true);
/** The panel containing panel31 and text area goes to dialog's south portion. */
    JPanel panel3 = new JPanel(new BorderLayout(), true);
/** The panel containing enter/help/quit buttons. */
    JPanel panel31 = new JPanel(new GridLayout(1, 3, 50, 20), true);

/** "Log Progress" checkbox. */
    JCheckBox lpc = new JCheckBox("Log Progress", false);
    int lpcX = 0;
/** "DataOnly" checkbox. */
    JCheckBox doc = new JCheckBox("Merge Data Only", false);
    int docX = 0;

/** "Use text" checkbox. */
    JCheckBox noPrefix = new JCheckBox("No prefix", false);
    int noPrefixSelected = 0;

/** "About" checkbox. */
    JCheckBox abc = new JCheckBox("About");
    int abcX = 0;
/** "CDAweb" checkbox. */
    JCheckBox cwc = new JCheckBox("CDAweb");
/** "Augment_Label" checkbox. */
    JCheckBox cao = new JCheckBox("Augment_Label");

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

/** "Select" button for source/input CDFs. */
    JButton slt1 = new JButton("Select");
    JButton slt2 = new JButton("Select");
    JButton slt3 = new JButton("Select");

/** "Select" button for selecting the output CDF file. */
    JButton slt4 = new JButton("Select");
/** "Select" button for selecting the input text file. */
    JButton slt5 = new JButton("Select");
/** "Select" button for selecting the master file. */
    JButton slt6 = new JButton("Select");

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

/** Text field for entering optional prefixes. */
    JTextField prefixes = new JTextField("",30);

/** Text field for source/input CDFs. */
    JTextField cdf1 = new JTextField("", 40);
    JTextField cdf2 = new JTextField("", 40);
    JTextField cdf3 = new JTextField("", 40);

/** Text field for entering the mandatory destination file name. */
    JTextField outfile = new JTextField("", 40);
/** Text field for entering the alternative input text file name. */
    JTextField inputfile = new JTextField("", 40);
/** Text field for entering the master file name. */
    JTextField masterfile = new JTextField("", 40);

/** Labels for source/input CDFs. */
    JLabel CDF1 = new JLabel("Source 1 CDF: ");
    JLabel CDF2 = new JLabel("Source 2 CDF: ");
    JLabel CDF3 = new JLabel("Source 3 CDF (optional): ");

/** A label of "Destination CDF:" for the text field outfile. */
    JLabel DCDF = new JLabel("Output CDF: ");

/** A label of "Text Input:" for the text field outfile. */
    JLabel TINF = new JLabel("Input file name (optional): ");
    JLabel TINF1 = new JLabel("  (alternate way to merge 2 or more files)");

    JLabel MSTF = new JLabel("Master CDF/file (optional): ");

    JLabel PREFIX = new JLabel("Prefixes for source CDFs (e.g. p1,p2,p3) - optional: ");
    
/** Scroll pane for the text area. */
    JScrollPane scroller;
/** Hold valid extensions for the CDF files for the file chooser. */
    String[] cdfs = {"cdf", "CDF"};
/** A file filter for the file chooser. */
    SimpleFileFilter filter = new SimpleFileFilter(cdfs,
                                                " CDF files (*.cdf, *.CDF)");
/** The command string. */
    String command = "cdfmerge ";
    String commandX;
    String[] cmds = new String[3];

/** Environment variable for the current directory. */
    String currentdir = System.getProperty("user.dir");
/** The file separator. */
    String separator = System.getProperty("file.separator");
    String strlp = " ";
    String strdo = " ";
    String strcw = " ";
    String strut = " ";
    String strpf = " ";
    String stral = " ";
    String cdf1spec = " ";
    String cdf2spec = " ";
    String cdf3spec = " ";
    String destspec = " ";
    String txinspec = " ";
    String mastspec = " ";
    String Prefix = " ";

/** A platform-dependent Runtime object. */
    Runtime runtime = Runtime.getRuntime();

/** A separate process to run the command. */
    Process process = null;

    int hlp = 0;

/** The text field is currently getting the focus. */
    JTextField focused = null;
/** The text field previously was focused. */
    JTextField prevfocused = null;
/** Menu bar. */
    JMenuBar menuBar = new JMenuBar();
/** A menu: File. */
    JMenu menuFile = new JMenu("File");
/** A menu: Edit. */
    JMenu menuEdit = new JMenu("Edit");
/** A menu: Help. */
    JMenu menuHelp = new JMenu("Help");
/** An Edit menu item: Copy. */
    JMenuItem menuEditCopy = new JMenuItem("Copy");
/** An Edit menu item: Cut. */
    JMenuItem menuEditCut = new JMenuItem("Cut");
/** An Edit menu item: Paste. */
    JMenuItem menuEditPaste = new JMenuItem("Paste");
/** A File menu item: Exit. */
    JMenuItem menuFileExit = new JMenuItem("Exit");
/** A Help menu item: Help. */
    JMenuItem menuHelpHelp = new JMenuItem("Help");
    int istart = -1;
    int iend = -1;

    String osName = System.getProperty("os.name");

    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 hpad80 = new Dimension(80,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 vpad80 = new Dimension(1,80);

    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 = 650;
    static int INITIAL_HEIGHT = 600;
/** The default dialog modal (is set to false). */
    static boolean defaultModal = false;
/** The current dialog modal. */
    boolean modal;
    int frommain = 0;

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

    CDFMerge(JFrame parentDriver) {
        this(parentDriver, null, defaultModal);
    }

    CDFMerge(JFrame parentDriver, String cdfbase) {
        this(parentDriver, cdfbase, defaultModal);
    }

    CDFMerge(JFrame parentDriver, 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 + "cdfmerge ";
        else
          command = "cdfmerge ";

        dialog = new JDialog(this, modal);
        this.modal = modal;
	this.parentDriver = parentDriver;
    }

/** 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 (parentDriver != null) parentDriver.setVisible(true);
              } else {
		if (macLib == 1) new File(libcdfPath).delete();
		System.exit(1);
	      }
	   }
        };
        dialog.addWindowListener(l);
        dialog.setTitle("Enter   Parameters/qualifiers  for  CDFMerge");
        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 edit menu
        menuBar.add(menuEdit);

        // add the menu items to edit
        menuEdit.add(menuEditCopy);
        menuEdit.add(menuEditCut);
        menuEdit.add(menuEditPaste);
        menuEditCopy.addActionListener(this);
        menuEditCut.addActionListener(this);
        menuEditPaste.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(vpad5), 0, 0, 1,1,1.0,1.0);

        makeJButton(panel1, CDF1, 0, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel1, cdf1, 1, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad10), 2, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt1, 3, 1, 1, 1, 1.0, 1.0);

        makeJButton(panel1, CDF2, 0, 2, 1, 1, 1.0, 1.0);
        makeJButton(panel1, cdf2, 1, 2, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad10), 2, 2, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt2, 3, 2, 1, 1, 1.0, 1.0);

        makeJButton(panel1, CDF3, 0, 3, 1, 1, 1.0, 1.0);
        makeJButton(panel1, cdf3, 1, 3, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad10), 2, 2, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt3, 3, 3, 1, 1, 1.0, 1.0);

        makeJButton(panel1, DCDF, 0, 4, 1, 1, 1.0, 1.0);
        makeJButton(panel1, outfile, 1, 4, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(hpad10), 2, 4, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt4, 3, 4, 1, 1, 1.0, 1.0);

        makeJButton(panel1, TINF, 0, 5, 1, 1, 1.0, 1.0);
        makeJButton(panel1, inputfile, 1, 5, 1, 1, 1.0, 1.0);
        makeJButton(panel1, Box.createRigidArea(hpad10), 2, 5, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt5, 3, 5, 1, 1, 1.0, 1.0);

        makeJButton(panel1, TINF1, 0, 6, 1, 1, 1.0, 1.0);

        makeJButton(panel1, MSTF, 0, 7, 1, 1, 1.0, 1.0);
        makeJButton(panel1, masterfile, 1, 7, 1, 1, 1.0, 1.0);
        makeJButton(panel1, Box.createRigidArea(hpad10), 2, 7, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt6, 3, 7, 1, 1, 1.0, 1.0);

        makeJButton(panel1, Box.createRigidArea(vpad20), 0, 8, 1, 1, 1.0, 1.0);

        cdf1.addActionListener(this);
        cdf1.addFocusListener(this);
        cdf1.addMouseListener(this);
	cdf1.setToolTipText("Enter the first source CDF (without extension)");
        cdf2.addActionListener(this);
        cdf2.addFocusListener(this);
        cdf2.addMouseListener(this);
        cdf2.setToolTipText("Enter the second source CDF (without extension)");
        cdf3.addActionListener(this);
        cdf3.addFocusListener(this);
        cdf3.addMouseListener(this);
        cdf3.setToolTipText("Enter the optional third source CDF (without extension)");
        outfile.addActionListener(this);
        outfile.addFocusListener(this);
        outfile.addMouseListener(this);
        outfile.setToolTipText("Enter the output CDF (without extension) to be the merged file");
        inputfile.addActionListener(this);
        inputfile.addFocusListener(this);
        inputfile.addMouseListener(this);
        inputfile.setToolTipText("Enter the input text file as an alternative way for merging 2 or more files");
        masterfile.addActionListener(this);
        masterfile.addFocusListener(this);
        masterfile.addMouseListener(this);
        masterfile.setToolTipText("Enter the master CDF or master text file");

        slt1.addActionListener(this);
        slt1.setToolTipText("Use the file chooser to select the first source CDF");
        slt2.addActionListener(this);
        slt2.setToolTipText("Use the file chooser to select the second source CDF");
        slt3.addActionListener(this);
        slt3.setToolTipText("Use the file chooser to select the third source CDF");
        slt4.addActionListener(this);
        slt4.setToolTipText("Use the file chooser to select the output, merged CDF");
        slt5.addActionListener(this);
        slt5.setToolTipText("Use the file chooser to select the text input file, an alternative way for merging 2 or more files");
        slt6.addActionListener(this);
        slt6.setToolTipText("Use the file chooser to select the master CDF or master text file");

        CDF1.setFont(boldFont);
        cdf1.setFont(boldFont);
        CDF2.setFont(boldFont);
        cdf2.setFont(boldFont);
        CDF3.setFont(boldFont);
        cdf3.setFont(boldFont);
        DCDF.setFont(boldFont);
        outfile.setFont(boldFont);
        TINF.setFont(boldFont);
        inputfile.setFont(boldFont);
        MSTF.setFont(boldFont);
        masterfile.setFont(boldFont);

//	dialog.getContentPane().add(panel1,BorderLayout.NORTH);
	panelx.add(panel1,BorderLayout.NORTH);
	
        // Panel 2

        makeJButton(panel2c, Box.createRigidArea(vpad20), 0, 0, 1, 1, 1.0, 1.0);
        // makeJButton(panel2c, lpc, 0, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel2c, abc, 0, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel2c, noPrefix, 1, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel2c, doc, 2, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel2c, cwc, 0, 2, 1, 1, 1.0, 1.0);
        makeJButton(panel2c, cao, 1, 2, 1, 1, 1.0, 1.0);
        makeJButton(panel2c, Box.createRigidArea(vpad20), 0, 3, 1, 1, 1.0, 1.0);

        makeJButton(panel2s, PREFIX, 0, 0, 1, 1, 1.0, 1.0);
        makeJButton(panel2s, prefixes, 1, 0, 1, 1, 1.0, 1.0);
	makeJButton(panel2s, Box.createRigidArea(vpad20), 2, 0, 1, 1, 1.0, 1.0);
        makeJButton(panel2s, Box.createRigidArea(vpad20), 3, 0, 1, 1, 1.0, 1.0);
        makeJButton(panel2s, Box.createRigidArea(vpad20), 4, 0, 1, 1, 1.0, 1.0);
        makeJButton(panel2s, Box.createRigidArea(vpad20), 5, 0, 1, 1, 1.0, 1.0);
        makeJButton(panel2s, Box.createRigidArea(vpad20), 6, 0, 1, 1, 1.0, 1.0);
        makeJButton(panel2s, Box.createRigidArea(vpad20), 0, 1, 1, 1, 1.0, 1.0);

//        panel2.add(panel2n, BorderLayout.NORTH);
        panel2.add(panel2c, BorderLayout.CENTER);
        panel2.add(panel2s, BorderLayout.SOUTH);

	lpc.setToolTipText("Select to show processing log");
        lpc.addItemListener(this);
        doc.setToolTipText("Select to set the -dataonly flag");
        doc.addItemListener(this);
        abc.setToolTipText("Display the current version");
        abc.addItemListener(this);
        noPrefix.setToolTipText("Select not to add the default prefix in front of variable name and attribute name");
        noPrefix.addItemListener(this);
        cwc.setToolTipText("Select to use ISTP/CDAweb compliance");
        cwc.addItemListener(this);
        cao.setToolTipText("Select to set the -augment_label flag");
        cao.addItemListener(this);

        prefixes.addActionListener(this);
        prefixes.addFocusListener(this);
        prefixes.addMouseListener(this);
        prefixes.setToolTipText("Enter the prefixeses to be added to the beginning of attribute and variable names");
        prefixes.setFont(boldFont);

//        dialog.getContentPane().add(panel2,BorderLayout.CENTER);
        panelx.add(panel2,BorderLayout.CENTER);

        // Panel 3 (buttons and text area)

        panel31.add(entrb);
        panel31.add(helpb);
        panel31.add(quitb);
  	panel3.add(panel31, BorderLayout.NORTH);
	panel3.add(Box.createRigidArea(vpad30),BorderLayout.CENTER);

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

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

                public Dimension getPreferredSize() {
                   return new Dimension(80, 160);
                }
                public float getAlignmentX() {
                   return LEFT_ALIGNMENT;
                }
        };
        scroller.getViewport().add(info);
//        panel3.add(scroller, BorderLayout.SOUTH);
//	dialog.getContentPane().add(panel3, BorderLayout.SOUTH);
	panelx.add(panel3, BorderLayout.SOUTH);
  	info.setVisible(true);

        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();
	fileChooser.setCurrentDirectory(new File(currentdir));
	dialog.setVisible(true);	
	if (parentDriver != null) parentDriver.setVisible(false);
    }

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

    public void reEnter() {
        dialog.setVisible(true);
	if (parentDriver != null) parentDriver.setVisible(false);
        info.setText("");
	cdf1.setText("");
	cdf2.setText("");
	cdf3.setText("");
	outfile.setText("");
        inputfile.setText("");
        masterfile.setText("");
	prefixes.setText("");
    }

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

    public void actionPerformed(ActionEvent evt) {
	Object obj = evt.getSource();
	if (obj == quitb || obj == menuFileExit) { // for "Quit" or "Exit"
           if (frommain == 0) {
             if (modal) dialog.dispose();
             else dialog.setVisible(false);
	     if (parentDriver != null) parentDriver.setVisible(true);
           } else {
	     if (macLib == 1) new File(libcdfPath).delete();
	     System.exit(1);
	   }
	} else if (obj == slt1 || obj == slt2 || obj == slt3 || 
                   obj == slt4 || obj == slt5 || obj == slt6) { 
	// for "Select" buttons
             if (obj == slt1) { // "Select" button for cdf1
                doFileChooser("Select/enter the first source CDF", cdf1, 1, filter);
             } else if (obj == slt2) { // "Select" button for cdf2
                doFileChooser("Select/enter the second source CDF", cdf2, 1, filter);
             } else if (obj == slt3) { // "Select" button for cdf3
                doFileChooser("Select/enter the third source CDF", cdf3, 1, filter);
             } else if (obj == slt4) { // "Select" button for outfile
                doFileChooser("Select/enter the destination CDF", outfile, 2, null);
             } else if (obj == slt5) { // "Select" button for input text file
                doFileChooser("Select the input text file", inputfile, 2, null);
                txinspec = inputfile.getText();
                txinspec = txinspec.trim();
                if (!txinspec.equals("")) {
                    cdf1.setText("");
                    cdf2.setText("");
                    cdf3.setText("");
                    outfile.setText("");
                    // utc.setSelected(true);
                }
             } else { // "Select" button for master file
                doFileChooser("Select/enter the master CDF or text file", masterfile, 2, null);
	     }
	} else if (obj == helpb || obj == menuHelpHelp) { // for "Help" 
		commandX = command + " -java";
		hlp = 1;
                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);
		hlp = 0;
	} else if (obj == entrb) { // for "Enter" button
                cdf1spec = cdf1.getText();
                cdf2spec = cdf2.getText();
                cdf3spec = cdf3.getText();
                destspec = outfile.getText();
                txinspec = inputfile.getText();
                mastspec = masterfile.getText();

                cdf1spec = cdf1spec.trim();
                cdf2spec = cdf2spec.trim();
                cdf3spec = cdf3spec.trim();
                destspec = destspec.trim();
                txinspec = txinspec.trim();
                mastspec = mastspec.trim();

                int numInputFiles = 0;
                if (!cdf1spec.equals("")) numInputFiles++;
                if (!cdf2spec.equals("")) numInputFiles++;
                if (!cdf3spec.equals("")) numInputFiles++;

                if (!txinspec.equals("")) {     /* -file option */
                   if (!mastspec.equals("")) {  /* -master option */
                      if (!destspec.equals("")) {
                         info.setText("");
                          info.append("Can't specify output CDF since it's derived from the master CDF/file:\n"+"   "+mastspec);
                         return;
                      }
                   }
                   else {
                      if (!cdf1spec.equals("") || !cdf2spec.equals("") ||
                          !cdf3spec.equals("")) {
                         info.setText("");
                         info.append("Can't specify input CDFs since they are defined in a text file:\n"+"   "+txinspec);
                         return;
                      }
                      else if (!destspec.equals("")) {
                         info.setText("");
                         info.append("Can't specify output CDF since it's defined in a text file (last argument):\n"+"   "+txinspec);
                         return;
                      }
                   }
                }
                else {
                   if (numInputFiles < 2) {
                      info.setText("");
                      info.append("Missing input CDF(s).  At least 2 input files must be specified.");
                      return;
                   }
                   if (!mastspec.equals("")) {  /* -master option */
                      if (!destspec.equals("")) {
                          info.setText("");
                          info.append("Can't specify output CDF since it's derived from the master CDF/file:\n"+"   "+mastspec);
                         return;
                      }
                   }
                   else if (destspec.equals("")) {
                      info.setText("");
                      info.append("Missing output CDF");
                      return;
                   }
                }

                if (mastspec.equals(""))
                     mastspec = " ";
                else
                     mastspec = "-master " + mastspec + " ";

                String np = null;
                if (noPrefixSelected == 1)
                    np = " -noprefix ";
                else {
                    np = " ";
                    strpf = prefixes.getText();
                    strpf = strpf.trim();
                    if (!strpf.equals(""))
                        Prefix = "-prefixes " + strpf + " ";
                    else
                        Prefix = " ";
                }

                if (txinspec.equals(""))    /* Input text file not provided */
                    strut = " ";
                else
                    strut = "-file " + txinspec;

                if (txinspec.equals("")) {  /* Input text file  not provided */
                    if (cdf3spec.equals("")) 
		        commandX = command + np + strdo + strcw + stral + 
                                   mastspec + Prefix + " " + cdf1spec + " " + 
                                   cdf2spec + " " + destspec;
                    else
		        commandX = command + np + strdo + strcw + stral + 
                                   mastspec + Prefix + " " + cdf1spec + " " + 
                                   cdf2spec + " " + cdf3spec + " " + destspec;
                } 
                else
                    commandX = command + np + strdo + strcw + stral + 
                               mastspec + Prefix + strut;

                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);

	// } else if (obj == cdf1) {
        //		cdf1spec = cdf1.getText();
        //	} else if (obj == cdf2) {
        //               cdf2spec = cdf2.getText();
        // } else if (obj == inputfile) {
                // txinspec = inputfile.getText();
                // txinspec = txinspec.trim();
                // if (txinspec.equals("") || txinspec.trim().equals("")) {
                //   utc.setSelected(false);
                // } else {
                //   utc.setSelected(true);
                // }      
	// } else if (obj == prefixes) {
        //		strpf = prefixes.getText();
        } else if (obj == menuEditCopy) {
                if (istart == -1) {
		    info.setText("Where to copy from?");
                    Toolkit.getDefaultToolkit().beep();
                } else {
                    focused.setSelectionStart(istart);
                    focused.setSelectionEnd(iend);
                    focused.copy();
                }
        } else if (obj == menuEditCut) {
                if (istart == -1) {
		    info.setText("What to cut?");
                    Toolkit.getDefaultToolkit().beep();
                } else {
                    focused.setSelectionStart(istart);
                    focused.setSelectionEnd(iend);
                    focused.cut();
                }
        } else if (obj == menuEditPaste) {
                if (focused == null) {
		    info.setText("Where to paste to?");
                    Toolkit.getDefaultToolkit().beep();
                } else {
                  if (istart != -1) {
                    focused.setSelectionStart(istart);
                    focused.setSelectionEnd(iend);
                  }
                  String tempX;
                  try {
                    tempX = (String) Toolkit.getDefaultToolkit().
                                    getSystemClipboard().getContents(this).
                                    getTransferData(DataFlavor.stringFlavor);
                    if (tempX == null) { // no clipboard text
                        info.setText("No current selection on clipboard");
                        Toolkit.getDefaultToolkit().beep();
                    } else if (tempX.indexOf("\n") != -1) { // multiple lines
                        info.setText("Multiple lines selection on clipboard - not allowed:");
                        info.append("\n\n");
                        info.append(tempX);
                        Toolkit.getDefaultToolkit().beep();
                    } else { focused.paste();}
                  } catch (Exception e) {}
                }
	}
    }

/** Action for checkboxs selection
 */

    public void itemStateChanged(ItemEvent evt) {
	Object obj = evt.getSource();
	if (obj ==  lpc) { // "Log Progress" checkbox
           if (lpc.isSelected()) 
	     strlp = "-log ";
           else
             strlp = " ";
        } else if (obj == doc) { // "Data Only" checkbox
           if (doc.isSelected()) 
	       strdo = "-dataonly ";
           else
               strdo = " ";
        } else if (obj == abc) { // "About" checkbox 
	   if (abc.isSelected()) {
		abcX = 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);
		abc.setSelected(false);
		abcX = 0;
	   }
        } else if (obj == noPrefix) { 
            if (noPrefix.isSelected()) {
                noPrefixSelected = 1;
                prefixes.setText("");
            }
            else
                noPrefixSelected = 0;
	} else if (obj == cwc) { // "CDAweb" checkbox
           if (cwc.isSelected()) 
               strcw = "-cdaweb ";
           else 
               strcw = " ";
        } else if (obj == cao) { // "Augment_Label" checkbox
           if (cao.isSelected()) {
             stral = "-augment_label ";
           } else {
             stral = " ";
           }
        }
    }

    public void focusGained(FocusEvent e) {
        focused = (JTextField)e.getSource();
        if (prevfocused != null) {
            prevfocused.setText(prevfocused.getText());
            if (iend != -1)
                if (iend < focused.getText().length())
                             prevfocused.setCaretPosition(iend);
                else focused.setCaretPosition(focused.getText().length());
        }
    }

    public void focusLost(FocusEvent e) {
        if (istart != -1)     {
            focused.setSelectionStart(istart);
            focused.setSelectionEnd(iend);
            prevfocused = focused;
          }
        }
    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {
        if (focused != null) {
          String selectedText = focused.getSelectedText();
          if (selectedText!=null) {
            istart = focused.getSelectionStart();
            iend = focused.getSelectionEnd();
          } else {
            istart = -1;
            iend = -1;
          }
        }
    }

/** 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) {
	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]);

           if (abcX == 0 && hlp == 0) {
               info.setText("");
               info.append("Program is running...\n");
           }
           Dimension dialogSize = dialog.getSize();
           ((JComponent)(dialog.getContentPane())).paintImmediately(
                                    0, 0, dialogSize.width, dialogSize.height);

           InputStreamReader inReader = new InputStreamReader(process.getInputStream(), "UTF-8");
           BufferedReader inStream = new BufferedReader(inReader, 8192);
	   boolean first = true;
	   String line = null;
          
           while ((line = inStream.readLine()) != null) {
	      if (first) {
	 	  info.setText("");
		  first = false;
	      }
              info.append(line+"\n");
	   }
           
	   process.waitFor(); 
  	   info.setCaretPosition(0);
           if (process.exitValue() == 1) 
               Toolkit.getDefaultToolkit().beep();
	   else if (hlp == 0 && !abc.isSelected()) {
               if (info.getText().toLowerCase().indexOf("error") == -1)
	         info.append("Done!\n\n");
               else
                 info.append("Error: merging is not done...\n\n");
	   }

        } catch (Exception e) {
              info.setText("error executing: "+e);
              Toolkit.getDefaultToolkit().beep();
        }
    }

/** Initiate the file chooser and strip the extension for the selected file
    if necessary
 */

    private void doFileChooser (String title, JTextField textField, int theone, SimpleFileFilter filter) {
//	JFileChooser fileChooser = new JFileChooser();
	ExampleFileView fileView = new ExampleFileView();
//        fileChooser.setCurrentDirectory(new File(currentdir));
	fileChooser.setDialogTitle(title);
        if (filter != null) {
	  fileChooser.addChoosableFileFilter(filter);
	  fileChooser.setFileFilter(filter);
          try {
            fileView.putIcon("cdf",
                             new ImageIcon(CDFMerge.class.getResource("CDF_Logo3.gif")));
            fileView.putIcon("CDF",
                             new ImageIcon(CDFMerge.class.getResource("CDF_Logo3.gif")));
            fileChooser.setFileView(fileView);
          } catch (Exception e) {}
        } else 
          fileChooser.setFileFilter(null);

        int returnValue = fileChooser.showDialog(dialog, "OK");
        if (returnValue == JFileChooser.APPROVE_OPTION) {
           File selectedFile = fileChooser.getSelectedFile();
           if (selectedFile != null) {
              int ind;
              String myfile = selectedFile.getAbsolutePath();
              if (theone == 1) { // for .cdf file
                ind = myfile.lastIndexOf(".cdf");
                if (ind != -1) myfile = myfile.substring(0, ind);
                ind = myfile.lastIndexOf(".CDF");
                if (ind != -1) myfile = myfile.substring(0, ind);
              } 
	      fileChooser.setCurrentDirectory(selectedFile);
              textField.setText(myfile);
           }
        } else {
//         JOptionPane.showMessageDialog(dialog, "No file chosen");
        }
    }

/** 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");

        CDFMerge thispgm = new CDFMerge(null, cdfbase);
	thispgm.fileChooser.setCurrentDirectory(new File(thispgm.currentdir));
        thispgm.frommain = 1;
	thispgm.run();
    }


}
