/******************************************************************************
* 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.*;

/** The pathname of the CDF to for which to display a directory listing
 */

public class CDFDir extends JFrame 
		    implements	ActionListener, MouseListener, FocusListener, 
				Runnable {

    static final long serialVersionUID = 1L;


    JFrame parentDriver;
/** The dialog for user interface. */ 
    JDialog dialog = new JDialog();

/** The FileChooser for the file selection. */
    JFileChooser fileChooser = new JFileChooser();
    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 containing panel21 goes to dialog's center portion. */
    JPanel panel2 = new JPanel(new BorderLayout(), true);
/** The panel for run/help/quit buttons. */
    JPanel panel21 = new JPanel(new GridLayout(1, 3, 50, 20), true);

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

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

/** Text field for entering the mandatory CDF file name. */
    JTextField cdf = new JTextField("", 40);

/** A label of "CDF:" for the text field cdf. */
    JLabel CDF = new JLabel("CDF: ");

/** 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 = "cdfdir ";
    String commandX;
/** Environment variable for the current directory. */
    String currentdir = System.getProperty("user.dir");
/** The file separator. */
    String separator = System.getProperty("file.separator");
/** The on-line help file name. */
    String helpolh = "cdfdirj.olh";
    String cdfspec = "";
/** A platform-dependent Runtime object. */
    Runtime runtime = Runtime.getRuntime();
/** A separate process to run the command. */
    Process process = null;
    
    String[] cmds = new String[3];

/** 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");
/** A Edit menu item: Copy. */
    JMenuItem menuEditCopy = new JMenuItem("Copy");
/** A Edit menu item: Cut. */
    JMenuItem menuEditCut = new JMenuItem("Cut");
/** A 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;

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

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

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

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

    CDFDir(JFrame parentDriver, String cdfbase, boolean modal) {
        if (cdfbase != null) {
	   command = "\"" + cdfbase + separator + "bin" + 
		     separator + "cdfdir\" ";
           String help = CDFToolsUtil.getenv("CDF_HELP");
           if (help != null && help.length() > 0) {
             String osName = System.getProperty("os.name");
             if (osName.toLowerCase().indexOf("windows") != -1) {
               int sepindx = help.indexOf(";");
               if (sepindx != -1) 
                 help = help.substring(0, sepindx);
             } 
             helpolh = help + separator + "cdfdirj.olh";
           } else {
	     help = System.getProperty("CDF_HELP");
             if (help != null && help.length() > 0) {
               helpolh = help + separator + "cdfdirj.olh";
             }
           }
	}
        dialog = new JDialog(this, modal);
	this.parentDriver = parentDriver;
        this.modal = modal;
    }

/** set up the GUI stuff for user seletion.
 */
    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 {System.exit(1);}
	   }
        };
        dialog.addWindowListener(l);
        dialog.setTitle("Enter   Parameters/qualifiers  for  CDFdir");
        dialog.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
        dialog.setLocation(screenSize.width/2 - INITIAL_WIDTH/2,
                          screenSize.height/2 - INITIAL_HEIGHT/2);

	// 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(vpad10), 0, 0, 1, 1, 1.0, 1.0);
	makeJButton(panel1, CDF, 0, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel1, cdf, 1, 1, 1, 1, 1.0, 1.0);
        makeJButton(panel1, slt, 2, 1, 1, 1, 1.0, 1.0);
	makeJButton(panel1, Box.createRigidArea(vpad20), 0, 3, 1, 1, 1.0, 1.0);
        cdf.addActionListener(this);
        cdf.addFocusListener(this);
        cdf.addMouseListener(this);
        cdf.setToolTipText("Enter the CDF to list");
        slt.addActionListener(this);
        slt.addFocusListener(this);
        slt.addMouseListener(this);
        slt.setToolTipText("Use the file chooser to select a CDF");
        CDF.setFont(boldFont);
        cdf.setFont(boldFont);
//	dialog.getContentPane().add(panel1,BorderLayout.CENTER);
	panelx.add(panel1,BorderLayout.CENTER);
	
        // Panel 2 (buttons and text area)

        panel21.add(entrb);
        panel21.add(helpb);
        panel21.add(quitb);
  	panel2.add(panel21, BorderLayout.NORTH);
	panel2.add(Box.createRigidArea(vpad30),BorderLayout.CENTER);

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

	// 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);
//        panel2.add(scroller, BorderLayout.SOUTH);
  	info.setVisible(true);

//  	dialog.getContentPane().add(panel2, BorderLayout.SOUTH);
  	panelx.add(panel2, 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();
	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("");
	cdf.setText("");
    }


/** Actions for buttons or menu action 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 {System.exit(1);}
	}
	else if (obj == slt) { // for "Select" button
		doFileChooser("Select/enter the CDF", cdf, 1, filter);
	} else if (obj == helpb || obj == menuHelpHelp) { // for "Help" 
		info.setText("");
		try {
		  FileReader fileStream = new FileReader(helpolh);
		  info.read(fileStream, null);
		} catch (FileNotFoundException e) {
		  info.setText("Help file: " + helpolh + " not found");
		  Toolkit.getDefaultToolkit().beep();
		} catch (IOException e) {
		  info.setText("IOException occurred while accessing help file"
				+ ": " + helpolh);
		  Toolkit.getDefaultToolkit().beep();
		}
	} else if (obj == entrb) { // for "Enter" button
		info.setText("");
		cdfspec = cdf.getText();
		if (cdfspec.equals("")) {
	  	    info.setText("Error... missing CDF file name!");
		    Toolkit.getDefaultToolkit().beep();
		} 
                else {
                    cdfspec = cdfspec.trim();
                    String cdfDelimiter;
                    if (cdfspec.startsWith("'")) cdfDelimiter = " ";
                    else if (cdfspec.startsWith("\"")) cdfDelimiter = " ";
                    else cdfDelimiter = "\"";

                    String OS = System.getProperty("os.name").toLowerCase();
                    if (OS.indexOf("windows") != -1) {
                        cmds[0] = "cmd /c dir " + cdfDelimiter + cdfspec + cdfDelimiter;
                    } else if (OS.indexOf("vms") != -1) {
                        cdfspec = cdfspec.replace('-', '/');
                        commandX = "spawn dir " + cdfDelimiter + cdfspec + cdfDelimiter;
                        cmds[0] = commandX;
                    } else {
		        commandX = "ls -l " + cdfDelimiter + cdfspec + cdfDelimiter;
		        cmds[0] = "/bin/sh";
		        cmds[1] = "-c";
		        cmds[2] = commandX;
                    }
                    runit(cmds);
		    // runit(commandX);
		}
	} else if (obj == cdf) {
		cdfspec = cdf.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 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");
			scroller.getViewport().setView(info);
			scroller.revalidate();
			scroller.repaint();
                        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) {}
                }
        }
    }

    public void focusGained(FocusEvent e) {
	Object focusedObj =  e.getSource();
	if (focusedObj instanceof JTextField) {
	  focused = (JTextField) focusedObj;
          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) {
    // private void runit(String command) {
	try {
              if (command[1] != null)
                process = runtime.exec(command);
              else
                process = runtime.exec(command[0]);

              InputStreamReader inReader = new InputStreamReader(process.getInputStream(), "UTF-8");
              BufferedReader inStream = new BufferedReader(inReader, 8192);

              String line = null;
              while ((line = inStream.readLine()) != null)
                info.append(line+"\n");
              process.waitFor();
	      info.setCaretPosition(0);
	      scroller.getViewport().setView(info);
	      scroller.revalidate();
	      scroller.repaint();

              if (process.exitValue() == 1) {
		Toolkit.getDefaultToolkit().beep();
	      }
        } 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(CDFDir.class.getResource("CDF_Logo3.gif")));
           fileView.putIcon("CDF",
                            new ImageIcon(CDFDir.class.getResource("CDF_Logo3.gif")));
           fileChooser.setFileView(fileView);
        } catch (Exception e) {}

        int returnValue = fileChooser.showDialog(dialog, "OK");
        if (returnValue == JFileChooser.APPROVE_OPTION) {
           File selectedFile = fileChooser.getSelectedFile();
           if (selectedFile != null) {
              int ind;
              String myfile = selectedFile.getAbsolutePath();
	      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");

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

}

