/******************************************************************************
* 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.util.*;
import javax.swing.*;
import java.awt.datatransfer.*;
import java.net.URL;
import gsfc.nssdc.cdf.*;
import gsfc.nssdc.cdf.util.*;

/** CDFexport allows the contents of a CDF to be exported to a variety of formats.
 */

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

    static final long serialVersionUID = 1L;

    public  CDFExport cdfexport;

    private JFrame parentDriver;
    private JDialog dialog;
    protected CDF sourceCDF = null;
    private String channelFile;

    private ExportGeneralOptions aGeneral = null;
    private ExportToCDFOptions aToCDF = null;
    private ExportFilterOptions aFilter = null;
    private ExportCDFTable aCDFTable = null;
    private boolean filterChanged = false;
    protected boolean MacOS = false;
    private boolean WindowsOS = false;

    private ButtonGroup outputgp;
    private JRadioButton output1;
    private JRadioButton output2;
    private JRadioButton output3;
    private JRadioButton output4;

    private JButton entrb;
    private JButton helpb;
    private JButton quitb;

    private JButton slt1;
    private JButton slt2;
    private JButton slt3;
    private JButton slt4;
    private JCheckBox abc;

    protected JTextArea info;
    private JTextField cdf1;
    private JTextField cdf2;
    private JTextField cdf3;
    private JTextField cdf4;

    private JLabel label1;
    private JLabel label2;
    private JLabel label3;
    private JLabel label4;

    private JScrollPane scroller; 
    protected Vector vars;
    protected String cdfspec1, cdfspec2, cdfspec3, cdfspec4;
    private String oldspec1 = null;
    private int oldSel = -1;
    private String currentdir = System.getProperty("user.dir");

    private String[] cdfs = {"cdf", "CDF"};
    private SimpleFileFilter cdffilter = new SimpleFileFilter(cdfs, " CDF files (*.cdf, *.CDF)");

    private JTextField focused = null;
    private JTextField prevfocused = null;

    private int filtering = 0;
    private int validMin = 0;
    private int validMax = 0;
    private int fillVal = 0;
    private int backwardEnvVar; 
    protected long backwardFlag;

    protected int ROWS = 26;
    protected int COLUMNS = 9;
    protected long majority = 0;
    protected long encoding = 0;
    protected int epoch = 4;
    protected long format = 1;
    protected int compressionType = -1;
    protected int compressionLevel = 0;
    protected long checksum = -1;
    protected int overwrite = 0;
    protected int trans0 = 0;
    protected int recordNum = 1;
    protected int indiceNum = 1;
    protected int headings = 1;
    protected int orientation = 0;

    protected int outSelection = -1;

    protected boolean changedCDF = false;
    private JMenuBar menuBar;
    private JMenu menuFile;
    private JMenu menuEdit;
    private JMenu menuOptions;
    private JMenu menuHelp;
    private JMenuItem menuEditCopy;
    private JMenuItem menuEditCut;
    private JMenuItem menuEditPaste;
    private JMenuItem menuFileOpen;
    private JMenuItem menuOptionsGeneral;
    private JMenuItem menuOptionsToCDFv3, menuOptionsToCDFv2;
    private JMenuItem menuOptionsFilter;
    private JMenuItem menuFileExit;
    private JMenuItem menuHelpHelp;
    private int istart = -1;
    private int iend = -1;

    private GridBagLayout gbl = new GridBagLayout();
    private GridBagConstraints gbc = new GridBagConstraints();

    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 int INITIAL_WIDTH = 400;
    static int INITIAL_HEIGHT = 200;
    static boolean defaultModal = false;
    boolean modal;
    int frommain = 0;
    static String osName = System.getProperty("os.name");

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

    CDFExport(JFrame parentDriver) {
        this(parentDriver, defaultModal);
    }

    CDFExport(JFrame parentDriver, boolean modal) {
	cdfexport = this;
	dialog = new JDialog(this, modal);
	this.parentDriver = parentDriver;
        this.modal = modal;

	if (osName.indexOf("Mac OS") != -1) {
	  if (osName.indexOf("Mac OS X") == -1)
            MacOS = true;
	}
	if (osName.indexOf("Windows") != -1)
	  WindowsOS = true;

        try {
          backwardEnvVar = CDF.getFileBackwardEnvVar();
        } catch (Exception ee) {
          System.out.println("Error getting Env Var..."+ ee);
        }

	RepaintManager.currentManager(null).setDoubleBufferingEnabled(true);

    }

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

    public void run() {
	buildUIs();
        cdfexport.pack();
        Dimension ps = cdfexport.getSize();
        Dimension ss = Toolkit.getDefaultToolkit().getScreenSize();
        cdfexport.setLocation(ss.width/2 - ps.width/2,
                           ss.height/2 - ps.height/2);

        cdfexport.setVisible(true);
	if (parentDriver != null) parentDriver.setVisible(false);
    }

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

    public void reEnter() {
	cdfexport.setVisible(true);
	if (parentDriver != null) parentDriver.setVisible(false);
    }

/** Set up the UI items.
 */

    private void buildUIs() {

        addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {
             if (frommain == 0) {
                if (modal) cdfexport.dispose();
                else cdfexport.setVisible(false);
                if (parentDriver != null) parentDriver.setVisible(true);
             } else {
                System.exit(1);
            }
          }
        });

        cdfexport.setTitle("Enter   Selections  for  CDFExport");

        cdfexport.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
	cdfexport.getContentPane().setLayout(new BorderLayout()); 
        addMenu();

	JPanel panelx = new JPanel(new BorderLayout(), true);

	// Panel 1

	slt1 = new JButton("Select");
	cdf1 = new JTextField("", 40);
	label1 = new JLabel("CDF: ");

	JPanel panel1 = new JPanel(new GridBagLayout(), true);
        makeJButton(gbl, gbc, panel1, Box.createRigidArea(vpad10), 0, 0, 1, 1, 1.0, 1.0);
	makeJButton(gbl, gbc, panel1, label1, 0, 1, 1, 1, 1.0, 1.0);
        makeJButton(gbl, gbc, panel1, cdf1, 1, 1, 1, 1, 1.0, 1.0);
        makeJButton(gbl, gbc, panel1, Box.createRigidArea(hpad20), 2, 1, 1, 1, 1.0, 1.0);
        makeJButton(gbl, gbc, panel1, slt1, 3, 1, 1, 1, 1.0, 1.0);
        makeJButton(gbl, gbc, panel1, Box.createRigidArea(vpad20), 0, 2, 1, 1, 1.0, 1.0);

        cdf1.addActionListener(this);
        slt1.addActionListener(this);
        label1.setLabelFor(cdf1);
        label1.setFont(boldFont);
        cdf1.setFont(boldFont);
	cdf1.setToolTipText("Enter the source CDF file (without extension) for export");
	slt1.setToolTipText("Use the file chooser to select the source CDF");

//        cdfexport.getContentPane().add(panel1,BorderLayout.NORTH);
        panelx.add(panel1,BorderLayout.NORTH);

        // Panel 2

        // Initialize the Output radio button.
	
        outputgp = new ButtonGroup();
        output1 = new JRadioButton("Output to the Screen");
        output2 = new JRadioButton("Output to a Text File");
        output3 = new JRadioButton("Output to a V3 CDF File");
	output4 = new JRadioButton("Output to a V2 CDF File");

        OutputListener forOutput = new OutputListener();
        output1.setActionCommand("1");
        output2.setActionCommand("2");
        output3.setActionCommand("3");
	output4.setActionCommand("4");
        output1.addActionListener(forOutput);
        output2.addActionListener(forOutput);
        output3.addActionListener(forOutput);
	output4.addActionListener(forOutput);
        output1.setSelected(true);
        outputgp.add(output1);
        outputgp.add(output2);
        outputgp.add(output3);
	outputgp.add(output4);
	output1.setToolTipText("Output the results to the screen");
	output2.setToolTipText("Output the results to a text file");
	output3.setToolTipText("Export the results to a V3 CDF file");
	output4.setToolTipText("Export the results to a V2 CDF file");

        abc = new JCheckBox("About");
        abc.addItemListener(this);
	abc.setToolTipText("Check the CDF library version");

	JPanel panel2 = new JPanel(new BorderLayout(), true);

	JPanel panel21 = new JPanel(new GridLayout(1,1), true);
	JPanel panel21x = new JPanel(new BorderLayout(), true);

	JPanel panel22 = new JPanel(new GridLayout(2,1), true);
	JPanel panel22x = new JPanel(new BorderLayout(), true);
	JPanel panel22xx = new JPanel(new BorderLayout(), true) ;

	JPanel panel23 = new JPanel(new GridLayout(2,1), true);
	JPanel panel23x = new JPanel(new BorderLayout(), true);
	JPanel panel23xx = new JPanel(new BorderLayout(), true);

        JPanel panel24 = new JPanel(new GridLayout(2,1), true);
        JPanel panel24x = new JPanel(new BorderLayout(), true);
        JPanel panel24xx = new JPanel(new BorderLayout(), true);

        panel21.add(output1);

        label2 = new JLabel("    Output Text File Name: ");
        cdf2 = new JTextField("", 30);
        cdf2.addActionListener(this);
        cdf2.addMouseListener(this);
        cdf2.addFocusListener(this);
        slt2 = new JButton("Select");
        panel22.add(output2);

        panel22xx.add(label2, BorderLayout.WEST);
        panel22xx.add(cdf2, BorderLayout.EAST);
        panel22x.add(panel22xx, BorderLayout.WEST);
        panel22x.add(slt2, BorderLayout.EAST);
	panel22.add(panel22x);
        slt2.addActionListener(this);
	cdf2.setToolTipText("Enter the output text file name (without extension) ");
	slt2.setToolTipText("Use the file chooser to select the output file");

        label3 = new JLabel("    Output CDF File Name: ");
        cdf3 = new JTextField("", 30);
        cdf3.addActionListener(this);
        cdf3.addMouseListener(this);
        cdf3.addFocusListener(this);
 
        slt3 = new JButton("Select");

        label4 = new JLabel("    Output CDF File Name: ");
        cdf4 = new JTextField("", 30);
        cdf4.addActionListener(this);
        cdf4.addMouseListener(this);
        cdf4.addFocusListener(this);

        slt4 = new JButton("Select");

        panel23.add(output3);
        panel23xx.add(label3, BorderLayout.WEST);
        panel23xx.add(cdf3, BorderLayout.EAST);
        panel23x.add(panel23xx, BorderLayout.WEST);
        panel23x.add(slt3, BorderLayout.EAST);
        panel23.add(panel23x);

        panel24.add(output4);
        panel24xx.add(label4, BorderLayout.WEST);
        panel24xx.add(cdf4, BorderLayout.EAST);
        panel24x.add(panel24xx, BorderLayout.WEST);
        panel24x.add(slt4, BorderLayout.EAST);
        panel24.add(panel24x);
        
        slt3.addActionListener(this);
	slt4.addActionListener(this);

	cdf2.setToolTipText("Enter the output CDF file name (without extension) ");
	slt3.setToolTipText("Use the file chooser to select the output V3 CDF file");
	slt4.setToolTipText("Use the file chooser to select the output V2 CDF file");

	if (backwardEnvVar == 0)
          panel2.setLayout(new GridLayout(5,1));
	else
	  panel2.setLayout(new GridLayout(4,1));
        panel2.add(panel21);
        panel2.add(panel22);
	if (backwardEnvVar == 0)
          panel2.add(panel23);
	panel2.add(panel24);
//        panel2.add(Box.createRigidArea(vpad5));
	panel2.add(abc); 
//        panel2.add(Box.createRigidArea(vpad5));

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

        // Panel 3 (buttons and text area)

        JPanel panel3 = new JPanel(new BorderLayout(), true);
	JPanel panel31 = new JPanel(new GridLayout(1, 5, 50, 20), true);

        entrb = new JButton(" Enter ");
        helpb = new JButton(" Help ");
        quitb = new JButton(" Quit ");

	panel31.add(Box.createRigidArea(new Dimension(10,1)));
        panel31.add(entrb);
        panel31.add(helpb);
        panel31.add(quitb);
	panel31.add(Box.createRigidArea(new Dimension(10,1)));
  	panel3.add(panel31, BorderLayout.NORTH);

        entrb.addActionListener(this);
        helpb.addActionListener(this);
        quitb.addActionListener(this);
	entrb.setToolTipText("Continue processing...");
	helpb.setToolTipText("Get the help information");
	quitb.setToolTipText("Exit CDFExport");

	// Text Area
        info = new JTextArea(15,20);
  	info.setEditable(false);
  	info.setVisible(true);
        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);
//        cdfexport.getContentPane().add(panel3, BorderLayout.SOUTH);
        panelx.add(panel3, BorderLayout.SOUTH);

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

    }

/** Set up the menubar and items
 */

    private void addMenu() {
        menuBar = new JMenuBar();
        menuFile = new JMenu("File");
        menuEdit = new JMenu("Edit");
        menuOptions = new JMenu("Options");
        menuHelp = new JMenu("Help");
        menuEditCopy = new JMenuItem("Copy");
        menuEditCut = new JMenuItem("Cut");
        menuEditPaste = new JMenuItem("Paste");
        menuFileOpen = new JMenuItem("Open");
        menuOptionsGeneral = new JMenuItem("Output to Screen/Text File");
        menuOptionsToCDFv3 = new JMenuItem("Output to V3 CDF");
	menuOptionsToCDFv2 = new JMenuItem("Output to V2 CDF");
	 menuOptionsFilter = new JMenuItem("Data Filtering");
        menuFileExit = new JMenuItem("Exit");
        menuHelpHelp = new JMenuItem("Help");

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

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

        // add the menu items to file
        menuFile.add(menuFileOpen);
        menuFile.add(menuFileExit);
        menuFileOpen.addActionListener(this);
        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 options menu
        menuBar.add(menuOptions);

        // add the menu items to options
        menuOptions.add(menuOptionsGeneral);
	if (backwardEnvVar == 0)
          menuOptions.add(menuOptionsToCDFv3);
	menuOptions.add(menuOptionsToCDFv2);
	menuOptions.add(menuOptionsFilter);
        menuOptionsGeneral.addActionListener(this);
        menuOptionsToCDFv3.addActionListener(this);
	menuOptionsToCDFv2.addActionListener(this);
	menuOptionsFilter.addActionListener(this);
	menuOptionsGeneral.setToolTipText("Select options for output to screen or a trext file");
	menuOptionsToCDFv3.setToolTipText("Select options for a V3 CDF file creation");
	menuOptionsToCDFv2.setToolTipText("Select options for a V2 CDF file creation");
	menuOptionsFilter.setToolTipText("Select options for filtering data values");

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

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

    }


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

    public void actionPerformed(ActionEvent evt) {
	Object obj = evt.getSource();
	int ix;
	if (obj == quitb || obj == menuFileExit) { // for "Quit" or "Exit"
	  if (frommain == 0) {
		if (modal) cdfexport.dispose();
		else cdfexport.setVisible(false);
		if (parentDriver != null) parentDriver.setVisible(true);	
	   } else {
             System.exit(1);
          }
	} else if (obj == menuFileOpen || obj == slt1 || obj == slt2 || 
		   obj == slt3 || obj == slt4) {
	     String fileName;
	     // "Open" menu item or "Select" button
             if (obj == slt1 || obj == menuFileOpen) {
		// Menu File's Open item or Select button for source CDF
                fileName = CDFToolUtils.doFileChooser("Select/Enter the Source CDF File Name", 
						      1, cdffilter, currentdir, cdfexport);
		if (fileName != null && fileName.trim().length() != 0) {
                  if (MacOS) {
		    currentdir = fileName.substring(0, fileName.lastIndexOf('/'));
		    if (fileName.startsWith(":") || fileName.startsWith("/")) 
			fileName = fileName.substring(1);
		    fileName = fileName.replace('/', ':');
                  } else {
		    if (WindowsOS) ix = fileName.lastIndexOf('\\');
		    else ix = fileName.lastIndexOf('/');
		    if (ix != -1) currentdir = fileName.substring(0, ix);
		    else currentdir = System.getProperty("user.dir"); 
		  }
//                  String fileNameX = (fileName.toLowerCase().endsWith(".cdf") ? fileName :
//                                      new StringBuffer(fileName).append(".cdf").toString());
//		  cdf1.setText(fileNameX);
		  cdf1.setText(fileName);
		  System.getProperties().put("user.dir", currentdir);
		  if (oldspec1 != null && aGeneral != null) aGeneral.reset();
		  if (oldspec1 != null && aToCDF != null) aToCDF.reset();
		  if (oldspec1 != null && aFilter != null) aFilter.reset();
		}
             } else if (obj == slt3 || obj == slt4) { 
	        // "Select" button for output CDF
		if (obj == slt3) output3.setSelected(true);
		else output4.setSelected(true);
                fileName = CDFToolUtils.doFileChooser("Select/Enter the Output CDF File Name", 
						      1, cdffilter, currentdir, cdfexport);
		if (fileName != null && fileName.trim().length() != 0) {
                  if (MacOS) {
		    currentdir = fileName.substring(0, fileName.lastIndexOf('/'));
                    if (fileName.startsWith(":") || fileName.startsWith("/")) 
			fileName = fileName.substring(1);
                    fileName = fileName.replace('/', ':');
                  } else {
                    if (WindowsOS) ix = fileName.lastIndexOf('\\');
                    else ix = fileName.lastIndexOf('/');
                    if (ix != -1) currentdir = fileName.substring(0, ix);
                    else currentdir = System.getProperty("user.dir");
                  }
//                  String fileNameX = (fileName.toLowerCase().endsWith(".cdf") ? fileName :
//                                      new StringBuffer(fileName).append(".cdf").toString());
//		  cdf2.setText(fileNameX);
		  cdf2.setText("");
		  if (obj == slt3) {
		    cdf3.setText(fileName);
		    output3.setSelected(true);
		    cdf4.setText("");
		  } else {
		    cdf4.setText(fileName);
		    output3.setSelected(true);
		    cdf3.setText("");
		  }
		  System.getProperties().put("user.dir", currentdir);
		} else {
		  if (obj == slt3) {
		    cdf3.requestFocus();
		    cdf3.setCaretPosition(0);
		  } else {
                    cdf4.requestFocus();
                    cdf4.setCaretPosition(0);
		  }
		}
             } else { // == slt2 as "Select" button for Output text file
		fileName = CDFToolUtils.doFileChooser("Select/Enter the Output File Name", 1, 
						      null, currentdir, cdfexport);
		if (fileName != null && fileName.trim().length() != 0) {
                  if (MacOS) {
		    currentdir = fileName.substring(0, fileName.lastIndexOf('/'));
                    if (fileName.startsWith(":") || fileName.startsWith("/")) 
		      fileName = fileName.substring(1);
		    fileName = fileName.replace('/', ':');
                  } else {
                    if (WindowsOS) ix = fileName.lastIndexOf('\\');
                    else ix = fileName.lastIndexOf('/');
                    if (ix != -1) currentdir = fileName.substring(0, ix);
                    else currentdir = System.getProperty("user.dir");
                  }
		  cdf2.setText(fileName);
		  output2.setSelected(true);
		  cdf3.setText("");
		  cdf4.setText("");
		  System.getProperties().put("user.dir", currentdir);
		}
	     }
	} else if (obj == helpb || obj == menuHelpHelp) { // for "Help" 
             info.setText("");
             try {
	       InputStream fis = cdfexport.getClass().getResourceAsStream("cdfxp.txt");
	       InputStreamReader reader = new InputStreamReader(fis);
//               FileReader reader = new FileReader("cdfxp.txt");
               info.read(reader, null);
	       info.setCaretPosition(0);
             } catch (FileNotFoundException e) {
               info.setText("Help info is not available...");
             } catch (IOException e) {
               info.setText("Help info is not available...");
             } catch (Exception e) {
	       info.setText("Help info is not available...");
	     }
	} else if (obj == entrb) { // for "Enter" button
		info.setText("");
		cdfspec1 = cdf1.getText();
		if (cdfspec1 == null || cdfspec1.equals("") || 
		    cdfspec1.trim().length() == 0) {
                    info.setText("Please enter the source CDF file name");
                    Toolkit.getDefaultToolkit().beep();
		    return;
		}
		if (MacOS) {
		  cdfspec1 = cdfspec1.replace('/', ':');
		  if (cdfspec1.startsWith(":")) cdfspec1 = cdfspec1.substring(1);
		}
		int selection = -99;
		String theselected = outputgp.getSelection().getActionCommand();
		if (theselected.equals("1")) { // to screen
		  selection = 1;
		} else if (theselected.equals("3") || 
			   theselected.equals("4")) { // to a CDF
                  String cdfspecX;
		  if (theselected.equals("3")) cdfspecX = cdf3.getText();
		  else cdfspecX = cdf4.getText();
                  if (cdfspecX == null || cdfspecX.equals("") || 
		      cdfspecX.trim().length() == 0) {
                    info.setText("Please enter the destination CDF file name");
                    Toolkit.getDefaultToolkit().beep();
                    return;
                  }
                  if (MacOS) {
                    cdfspecX = cdfspecX.replace('/', ':');
                    if (cdfspecX.startsWith(":")) cdfspecX = cdfspecX.substring(1);
                  }
		  if (theselected.equals("3")) {
		    selection = 3;
		    cdfspec3 = cdfspecX;
		    backwardFlag = BACKWARDFILEoff;
		  } else {
		    selection = 4;
		    cdfspec4 = cdfspecX;
		    backwardFlag = BACKWARDFILEon;
		  }
		} else if (theselected.equals("2")) { // to a text file
                  cdfspec2 = cdf2.getText();
                  if (cdfspec2.equals("") || cdfspec2.trim().length() == 0) {
                    info.setText("Please enter the output file name");
                    Toolkit.getDefaultToolkit().beep();
                    return;
		  }
                  if (MacOS) {
                    cdfspec2 = cdfspec2.replace('/', ':');
                    if (cdfspec2.startsWith(":")) cdfspec2 = cdfspec1.substring(1);
                  }
		  selection = 2;
                }
		if (getCDF()) {
		  if (aCDFTable == null || changedCDF || outSelection != selection) {
		    if (changedCDF) {
		      changedCDF = false;
		    }
		    filterChanged = true;
		    outSelection = selection;
//		    setVisible(false);
                    JFrame myFrame = (parentDriver == null ? this : 
                                      parentDriver);
		    aCDFTable = ExportCDFTable.createCDFTable(myFrame,
							      cdfexport, cdfspec1);
		  } else {
//		    cdfexport.setVisible(false);
		    aCDFTable.reEnter();
		  }
//		  cdfexport.setVisible(true);
//		  cdfexport.show();
		}
	} else if (obj == cdf1) {
		cdfspec1 = cdf1.getText();
                if (MacOS) {
                  cdfspec1 = cdfspec1.replace('/', ':');
                  if (cdfspec1.startsWith(":")) cdfspec1 = cdfspec1.substring(1);
                }
	} else if (obj == cdf2) {
                cdfspec2 = cdf2.getText();
                if (MacOS) {
                  cdfspec2 = cdfspec2.replace('/', ':');
                  if (cdfspec2.startsWith(":")) cdfspec2 = cdfspec2.substring(1);
                }
		output2.setSelected(true);
        } else if (obj == cdf3) {
                cdfspec3 = cdf3.getText();
                if (MacOS) {
                  cdfspec3 = cdfspec3.replace('/', ':');
                  if (cdfspec3.startsWith(":")) cdfspec3 = cdfspec3.substring(1);
                }
                output3.setSelected(true);
        } else if (obj == cdf4) {
                cdfspec4 = cdf4.getText();
                if (MacOS) {
                  cdfspec4 = cdfspec4.replace('/', ':');
                  if (cdfspec4.startsWith(":")) cdfspec4 = cdfspec4.substring(1);
                }
                output4.setSelected(true);
	} else if (obj == menuOptionsGeneral) {
		if (aGeneral == null) 
		  aGeneral = ExportGeneralOptions.createGeneralOptions(this, 
								       cdfexport,
								       true);
		aGeneral.displayGeneralOptions();
        } else if (obj == menuOptionsToCDFv3) {
		if (aToCDF == null) 
                  aToCDF = ExportToCDFOptions.createToCDFOptions(this, 
								 cdfexport, 
								 true);
		aToCDF.displayToCDFOptions();
        } else if (obj == menuOptionsToCDFv2) {
                if (aToCDF == null)
                  aToCDF = ExportToCDFOptions.createToCDFOptions(this,
                                                                 cdfexport,
                                                                 true);
                aToCDF.displayToCDFOptions();
        } else if (obj == menuOptionsFilter) {
                if (aFilter == null) 
                  aFilter = ExportFilterOptions.createFilterOptions(this, 
								    cdfexport, 
								    true);
                aFilter.displayFilterOptions();
        } 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) {
		    Toolkit.getDefaultToolkit().beep();
		} else {
                  if (istart != -1) {
                    focused.setSelectionStart(istart);
                    focused.setSelectionEnd(iend);
                  }
                  String temp;
                  try {
                    temp = (String) Toolkit.getDefaultToolkit().
                                    getSystemClipboard().getContents(this).
                                    getTransferData(DataFlavor.stringFlavor);
                    if (temp == null) { // no clipboard text
                        info.setText("No current selection on clipboard");
                        Toolkit.getDefaultToolkit().beep();
                    } else if (temp.indexOf("\n") != -1) { // multiple lines
                        info.setText("Multiple lines selection on clipboard - not allowed:");
                        info.append("\n\n");
                        info.append(temp);
                        Toolkit.getDefaultToolkit().beep();
                    } else { focused.paste();}
                  } catch (Exception e) {}
                }
	}
    }

/** Create an CDF object for the source CDF
 */

    boolean getCDF() {

	if (oldspec1 == null) { // first time thru
	  try {
	    /* Open the CDF file */
	    sourceCDF  = CDF.open(cdfspec1, READONLYon);
	    vars = sourceCDF.getVariables();
	    if (majority == 0) majority = sourceCDF.getMajority();
	    if (checksum == -1) checksum = sourceCDF.getChecksum();
	    oldspec1 = cdfspec1;
	    oldSel = outSelection;
	    return true;
	  } catch (CDFException e) {
	    Toolkit.getDefaultToolkit().beep();
	    info.setText(e.toString());
	    return false;
	  }
        } else { // we have one CDF already open
	    if (!oldspec1.equals(cdfspec1)) { // a new CDF is to open
              try {
                if (sourceCDF != null) {
                  try {
                    sourceCDF.close();
                  } catch (CDFException ex) {
                    info.setText("Error! closing "+ex.toString());
                    Toolkit.getDefaultToolkit().beep();
                    return false;
                  }
                  sourceCDF = null;
                }
		sourceCDF  = CDF.open(cdfspec1, READONLYon);
		vars = sourceCDF.getVariables();
		if (majority == 0) majority = sourceCDF.getMajority();
		if (checksum == -1) checksum = sourceCDF.getChecksum();
		oldspec1 = cdfspec1;
		oldSel = outSelection;
		changedCDF = true;
		return true;
              } catch (CDFException e) {
                Toolkit.getDefaultToolkit().beep();
                info.setText(e.toString());
		return false;
              }
            } else { // same cdf... 
	      changedCDF = false;
	      return true;
	    }
        }

    }

/** Set/reset the selections to default values
 */

    void reset() {
    
       filtering = 0;
       validMin = 0;
       validMax = 0;
       fillVal = 0;

       ROWS = 26;
       COLUMNS = 9;
       majority = 0;
       encoding = 0;
       epoch = 4;
       format = 1;
       compressionType = -1;
       compressionLevel = 0;
       overwrite = 0;
       trans0 = 0;
       recordNum = 1;
       indiceNum = 1;
       headings = 1;
       orientation = 0;

    }

/** Action for radio buttons for output selection
 */

    private class OutputListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
	   int strot = new Integer(e.getActionCommand()).intValue();
	   info.setText("");
	   if (strot == 1) { // to the screen
	     cdf2.setText("");
	     cdf3.setText("");
	     cdf4.setText("");
	   } else if (strot == 2) { // to a text file
	     cdf3.setText("");
	     cdf4.setText("");
	   } else if (strot == 3) { // to a V3 CDF file
	     cdf2.setText("");
	     cdf4.setText("");
	   } else {		   // to a V2 CDF file
	     cdf2.setText("");
	     cdf3.setText("");
	   }
        }
    }

    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());
        }
        if (focused == cdf2) { // to a text file
	     cdf3.setText("");
             cdf4.setText("");
	     output2.setSelected(true);
        } else if (focused == cdf3) { // to a V3 CDF file
	     cdf2.setText("");
             cdf4.setText("");
	     output3.setSelected(true);
        } else {		    // to a V2 CDF file
	     cdf2.setText("");
             cdf3.setText("");
	     output4.setSelected(true);
	}
    }

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

/** Actions for checkboxs or combo box selection
 */
    public void itemStateChanged(ItemEvent evt) {
        Object obj = evt.getSource();
        if (obj == abc) { // "About" checkbox
           if (abc.isSelected()) {
		try {
		  info.setText("CDF library distribution: "+CDF.getLibraryVersion());
                }
		catch (CDFException e) {System.err.println("error: "+e);}
		abc.setSelected(false);
           }
        }
    }

/** Set up gridbaglayout
 */

    private void makeJButton(GridBagLayout gbl, GridBagConstraints c, Container cont,
			     Object arg, int x, int y, int w, int h, double weightx, 
			     double weighty) {
        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);
    }

    public int getFiltering() {
	return filtering;
    }

    public int getValidMin() {
	return validMin;
    }
    public int getValidMax() {
	return validMax;
    }
    public int getFillVal() {
	return fillVal;
    }

    public boolean getFilterChanged() {
        return filterChanged;
    }

    public void setFiltering(int filtering) {
        this.filtering = filtering;
    }

    public void setValidMin(int validMin) {
        this.validMin = validMin;
    }

    public void setValidMax(int valifMax) {
        this.validMax = validMax;
    }

    public void setFillVal(int fillVal) {
        this.fillVal = fillVal;
    }

    public void setFilterChanged(boolean filterChanged) {
        this.filterChanged = filterChanged;
    }

/** This class can run as an application by its own.
 */

    static public void main(String[] args) {

        try {
            UIManager.setLookAndFeel(UIManager.
                                     getCrossPlatformLookAndFeelClassName());
        } catch (Exception exc) {
        }

//        JFrame myframe = new JFrame();
        CDFExport thispgm = new CDFExport();
        thispgm.frommain = 1;

        String osVersion = System.getProperty("os.version");
	String javaVersion = System.getProperty("java.version");
        if (osName.toLowerCase().indexOf("windows") != -1) {
          int thisOS = new Integer(osVersion.substring(0, osVersion.indexOf("."))).intValue();
          int inIndex = javaVersion.indexOf(".");
          String subJavaVersion = javaVersion.substring(inIndex+1);
          int thisMajorV = new Integer(javaVersion.substring(0, inIndex)).intValue();
          int thisMinorV = new Integer(subJavaVersion.substring(0, subJavaVersion.indexOf("."))).intValue();
          int thisJava = (thisMinorV<10?thisMajorV*10+thisMinorV:thisMajorV*100+thisMinorV);
//        if (osVersion.compareTo("5.0") >= 0 &&   // Windows 2000 and beyond...
//            javaVersion.compareTo("1.4") >= 0) { // Java 1.4
          if (thisOS >= 5 &&   // Windows 2000 and beyond...
               thisJava >= 14) { // Java 1.4
            try {
              Runtime runtime = Runtime.getRuntime();
              Process process = runtime.exec("cmd /c assoc .cdf");
              InputStreamReader inReader = new InputStreamReader(process.getInputStream(), "UTF-8");
              BufferedReader inStream = new BufferedReader(inReader, 8192);

              try {
                process.waitFor();
              } catch (InterruptedException ee) {
                System.err.println("Error with assoc... 1 "+ee);
              }
              thispgm.channelFile = inStream.readLine();
              if (thispgm.channelFile != null &&
                  thispgm.channelFile.toLowerCase().equals(".cdf=channelfile")) {
                process = runtime.exec("cmd /c assoc .cdf="); // dis-associate it
                InputStreamReader inReader2 = new InputStreamReader(process.getInputStream(), "UTF-8");
                inStream = new BufferedReader(inReader2, 8192);
		String dummy = inStream.readLine(); // clear the input buffer
                try {
                  process.waitFor();
                  runtime.addShutdownHook(new RestoreChannelDefinition(thispgm.channelFile));
                } catch (InterruptedException ee) {
                  System.err.println("Error with assoc... 2 "+ee);
                }
              }
            } catch (IOException ex) { // No need to do anything if "cmd" file does not exist
            }
          }
        }

//	thispgm.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
	thispgm.run();
    }

    // A thread to restore the .cdf association for Windows 2000, etc.

    static private class RestoreChannelDefinition extends Thread {

    // The string to be restored.
        String channelDefinition;

        RestoreChannelDefinition(String channelDefinition) {
           this.channelDefinition = channelDefinition;
        }

    // implement the run method of Runable class.

        public void run() {
          try { 
            Process process = Runtime.getRuntime().exec("cmd /c assoc "+
                                                        channelDefinition);
            try {
              process.waitFor();
            } catch (InterruptedException ee) {
              System.err.println("Error with assoc... 3 "+ee);
            }
          } catch (IOException ex) {
            System.err.println("Error running assoc on Windows...(3): "+ex);
          } 
        }
    }

}

