package usda.weru.weps;

import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileReader;
import de.schlichtherle.truezip.file.TFileWriter;
import de.schlichtherle.truezip.file.swing.TFileChooser;
import it.geosolutions.jaiext.JAIExt;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import static java.awt.Cursor.getPredefinedCursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import javax.help.CSH;
import javax.help.HelpBroker;
import javax.help.HelpSet;
import javax.net.ssl.TrustManagerFactory;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ToolTipManager;
import usda.weru.nrmv.ConvertAllToNrmv;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 
import org.jdom2.Element;
import javax.swing.GroupLayout;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
import org.apache.logging.log4j.Level;
import org.geotools.process.raster.AddCoveragesProcess;
import usda.weru.gis.gui.TileCacheCleaner;
import usda.weru.mcrew.MCREWWindow;
import usda.weru.remoteDataAccess.csip.CsipInputControllerStatic;
import usda.weru.remoteDataAccess.csip.CsipLmodUtil;
import usda.weru.soil.NASIS;
import usda.weru.util.About;
import usda.weru.util.AboutDialog;
import usda.weru.util.Application;
import usda.weru.util.ConfigData;
import static usda.weru.util.ConfigData.DefaultRunsLocation;
import usda.weru.util.Help;
import usda.weru.util.LoadProperties;
import usda.weru.util.LoadingContext;
import usda.weru.util.Log4jWepsConfigurationFactory;
import usda.weru.util.LogViewer;
import usda.weru.util.ResetRunLocationPanel;
import usda.weru.util.RestoringContext;
import usda.weru.util.Util;
import usda.weru.util.WepsAWTEventListener;
import usda.weru.util.WepsExceptionHandler;
import usda.weru.util.WepsMessageDialog;
import usda.weru.util.WindGenStationDisplay;
import usda.weru.util.diff.DifferFrame;
import usda.weru.util.table.FilterSet;
import usda.weru.util.table.Helper;
import usda.weru.util.wepsFileChooser2.WepsFileChooser2;
import usda.weru.util.wepsFileChooser2.WepsFileFilter;
import usda.weru.util.wepsFileChooser2.WepsFileTypes2;
import static usda.weru.weps.SimulationPanel.getDatesUnordered;
import usda.weru.weps.gui.LocalePanel_n;
import usda.weru.weps.location.LocationPanel;
import usda.weru.weps.location.Site;
import usda.weru.weps.location.Station;
import usda.weru.weps.reports.ReportManager;
import usda.weru.weps.startup.PreviousVersionResolver;
import usda.weru.weps.startup.ReleaseVersion;
import usda.weru.weps.startup.WelcomeWizard;
import usda.weru.weps.webstart.CsipRunner.WsCsipRunner;
import usda.weru.weps.wepsRunControl.WrcSimulationControl;
import static usda.weru.weps.wepsRunControl.WrcSimulationControl.getNewWrcSimulationControl;
import usda.weru.wmrm.Wmrm;


/**
 * WEPS is an important part of controlling wind erosion through conservation
 * planning. By observing how the soil loss is affected by weather and field
 * conditions, the management operations can be adjusted to reduce soil loss.
 * Although WEPS 1.0 is designed to simulate rectangular field shapes, special
 * field configurations such as circles, strip cropping, or using barriers are
 * part of using WEPS as a conservation planning tool. By manipulating the field
 * shape to represent a field with the same area and rotating the field along
 * with any barriers many field shapes can be approximated. This is the start-up
 * class or main class for the application's execution. Kind of like a
 * CONTROLLER for a MVC architecture.
 */
public class Weps extends usda.weru.weps.gui.Weps_n implements PropertyChangeListener {

//static {
//// -Dlog4j.configurationFactory=usda.weru.util.Log4jWepsXmlConfigurationFactory
//    ConfigurationFactory.setConfigurationFactory(new Log4jWepsXmlConfigurationFactory());
//}

    private static final long serialVersionUID = 1L;
    private static final Logger logger = LogManager.getLogger(Weps.class);
    public static final String WEPS = "WEPS";
    public static final String WEPS_RUNCREATED = WEPS + "run created";
    public static final String WEPS_RUNRESTORED = WEPS + "run restored";
    public static final String WEPS_RUNLOCATION = WEPS + "run location";
    /**
     * Static definitions for WEPS system.
     */
    public DrawField df;
    public RunFileData rfd;
    public RegPanel rp;
    public BarPanel bp;
    public ConfigData cd;
    private LoadProperties propertyLoader = null;
    protected boolean reviewWarnings = true;
    public boolean warnAboutLocale = true;
    public boolean isRestored = false;
    public static boolean isWebstart = false;
    public static boolean isNRCSMode = false;
    public static boolean isDevMode = false;
    public static boolean iniEmpty = false;
    public static boolean isMSIbuild = false;
    private static boolean oldManCheck = false;
    private static String manName = "";
    
    protected String [] mainArgs;
    /**
     * The set of objects used to associate the help line system.
     */
    public HelpSet hs;
    /**
     * Object used for setting up the help system and associated data for
     * context sensitive help regarding the GUI objects on the application
     * interface panel and a short description on what they are meant for on the
     * interface.
     */
    public HelpBroker hb;
    private boolean c_singleProjectMode = false;
    private boolean massSoilChooserSDM = false;
    private static Weps c_instance = null;
    private AuxPanel ap = null;
    public AuxPanel getAuxPanel() {
        return ap;
    }
    
    private static SimulationPanel sp;
    public SimulationPanel getSimulationPanel() {
        return sp;
    }
    
    static {
        JAIExt.initJAIEXT();
    }
    public void setSimulationPanel(SimulationPanel newSP) {
        sp = newSP;
    }
    
    private static LocationPanel lp;
    public LocationPanel getLocationPanel() {
        return lp;
    }
    
    //used for NRCS SDM query (see WepsTreeModelSoil.java and JdbcSoilInterfaceDatabase.java
    public Site<?> getSelectedFromSiteChooser() {
        return lp.getSelectedSite();
    }
    
    public void setLocationPanel(LocationPanel newLP) {
        lp = newLP;
    }
    
    public static Weps getInstance() {
        return c_instance;
    }

    public static boolean checkOldMan() {
        return oldManCheck;
    }
    
    public static void setOldMan(boolean man) {
        oldManCheck = man;
    }
    
    public static String getManName() {
        return manName;
    }
    
    public void setMassSoilChooserSDM(boolean enable) {
        massSoilChooserSDM = enable;
    }
    
    public boolean getMassSoilChooserSDM() {
        return massSoilChooserSDM;
    }
    
    public static void setManName(String newName) {
//        if(newName.contains("\\")) {
//            newName = newName.substring(newName.lastIndexOf("\\") + 1);
//        }else if(newName.contains("/")) {
//            newName = newName.substring(newName.lastIndexOf("/") + 1); 
//        }
//        System.out.println("Old Man Name: " + manName);
//        System.out.println("New Man Name: " + newName);
        if(!newName.equals(manName)) {
            oldManCheck = false;
        }
        manName = newName;
    }
    
    private WsCsipRunner wsRunner;            
    private CsipInputControllerStatic csipStatic;
    private boolean wepsInitComplete = false;
    
    /**
     * Default constructor for the main WEPS GUI application.
     */
    public Weps() {
        super();
        
        mainArgs = null;
        
        //setMinimumSize(new Dimension(650, 175));
        c_instance = this;
        //setIconImage(wepsIcon.getImage());


        //MEH image
        System.setProperty("org.geotools.referencing.forceXY", "true");
        // For NRCS systems: TLSv1.0 is closed, use later version
//        System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
        System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");
        System.out.println("Setting TLS version to 1.1, 1.2");
        //Hints.putSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);

        addHelp();

        MI_currentStirEnergyReport.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (lastRun.length() == 0) {
                    JOptionPane.showMessageDialog(Weps.this, "No current run available",
                            "Error (W-005)", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                String runDir = (!(new TFile(lastRun).isAbsolute()))
                        ? (new TFile(projectDirectory, lastRun)).getAbsolutePath() : lastRun;
                ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_STIR);
            }
        });
        MI_otherStirEnergyReport.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath,
                        ReportManager.REPORT_STIR);
            }
        });
        
        wsRunner = null;

    }

    /**
     * Creates a new instance of JFrame1 with the given title.
     *
     * @param sTitle the title for the new frame.
     * @see #JFrame1()
     */
    public Weps(String sTitle) {
        this();
        setTitle(sTitle);
    }

    @Override
    public void exitApplication() {
        
        // just a signal to bootloader to indicate WEPS running.
        About.clearWepsRunningFile();
        
        if (dataChanged) {
            int res = JOptionPane.showConfirmDialog(this, "Save current WEPS project?",
                    "Save Project", JOptionPane.YES_NO_CANCEL_OPTION);
            switch (res) {
                //We need to set the default window close operation to DO_NOTHING_ON_CLOSE for CANCEL option
                //otherwise the frame remains hidden since the JFrame default close operation is HIDE_ON_CLOSE- added by Neha
                case JOptionPane.CANCEL_OPTION:
                    this.setVisible(true);
                    this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                    return;
                case JOptionPane.YES_OPTION:
                    //if the user wants to save
                    rfd.writeRunDataXML(projectDirectory);
                    break;
                case JOptionPane.NO_OPTION:
                    break;
            }
        }
        try {
            // Beep
            Toolkit.getDefaultToolkit().beep();
            // Show a confirmation dialog
            int reply = JOptionPane.showConfirmDialog(this,
                    "Do you really want to exit?",
                    "WEPS Exit",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE);

            // If the confirmation was affirmative, handle exiting.
            ////System.out.println("W_eA: " + reply);
            if (reply == JOptionPane.YES_OPTION) {
                
                CsipLmodUtil.clearCrLmodSoilCacheTmpDir();
                
                // end the CSIP service runner process
                if (wsRunner != null) {
                    wsRunner.stopRunningAll();
                }
                
                this.setVisible(false);    // hide the Frame

                this.dispose();            // free the system resources

                this.fileWatcher.interrupt();
                System.exit(0);            // close the application

            } else {
                this.setVisible(true);
                this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
            }
        } catch (HeadlessException e) {
        }
        //super.exitApplication();
    }
    
    public RunFileData getRunFileData() {
        return rfd;
    }

    private static void printHelp() {
        System.out.println("Usage: weps [OPTION]");
        System.out.println();
        System.out.println("List of avaliable command line options");
        System.out.println("-cfg path/to/cfg \t specify the main configuration file");
        System.out.println("-usercfg path/to/cfg \t specify the user configuration file");
        System.out.println("-logcfg path/to/cfg \t specify the logging configuration file");
        System.out.println("-log path/to/log \t specify the logging file");
        System.out.println("-wsUseWepsCert \t insert the required web certs (for WEPS and SoilDataMart sites)");
        System.out.println("-db path/to/cfg \t specify the databases directory");
        System.out.println("-help \t\t\t display this screen");
        System.out.println("-userhome path/to/userhome \t specify where the {user.home} directory is located");
    }

    private static void configureDefaultLoggers(TFile logFile, Exception ex) {
        try {
            
            Logger flogger = LogManager.getLogger("RollingFile");
            flogger.info("Configuring default logger.");
            logger.info("Configuring default logger.");
            if (ex != null) {
                logger.info("Using default logger configuration.");
                logger.info("Log File: " + logFile.getAbsolutePath());
            } else {
               logger.warn("Error configuring loggers. Using default logger configuration.");
            }
        }catch (Exception e) {
            //BasicConfigurator.configure();
            logger.error("Default logger configuration failed. Using basic configuration.", e);
        }
        
        
// MEH log4j need to re-implement.
//        try {
//            PatternLayout rfp = new PatternLayout("%d %5p [%t] (%F:%L) - %m%n");
//            RollingFileAppender rfa = new RollingFileAppender(rfp, logFile.getAbsolutePath(), true);
//            rfa.setMaxBackupIndex(5);
//            rfa.setThreshold(Level.DEBUG);
//            BasicConfigurator.configure(rfa);
//
//            PatternLayout rfc = new PatternLayout("%5p [%t] (%F:%L) - %m%n");
//            ConsoleAppender ca = new ConsoleAppender(rfc);
//            ca.setThreshold(Level.WARN);
//            BasicConfigurator.configure(ca);
//
//            logger.info("Configuring default logger.");
//
//            if (ex != null) {
//                logger.info("Using default logger configuration.");
//                logger.info("Log File: " + logFile.getAbsolutePath());
//            } else {
//                logger.warn("Error configuring loggers. Using default logger configuration.");
//            }
//
//        } catch (IOException e) {
//            BasicConfigurator.configure();
//            logger.error("Default logger configuration failed. Using basic configuration.", e);
//        }
    }

    private static void deleteOldLogs(TFile currentLogFile) {
// MEH log4j need to re-implement
        //loggers are now configured.  Rollover the file logger.
//        Appender appender = RootLogger.getRootLogger().getAppender("file");
//        if (appender instanceof FileAppender) {
//            FileAppender ra = (FileAppender) appender;
//            TFile file = new TFile(ra.getFile());
            TFile file = currentLogFile;

            String[] exts = Util.getExtensions(file.getName());
            final String requiredName = Util.purgeExtensions(file.getName(), exts);
            final String requiredExt = exts.length > 1 ? exts[exts.length - 1] : "";

            final Calendar staleLogCalendar = Calendar.getInstance();
            //staleLogCalendar.add(Calendar.DAY_OF_YEAR, -2);
            int days = 0;
            try {
                String dayText = ConfigData.getDefault().getData(ConfigData.DaysToKeepLogs);
                days = Integer.parseInt(dayText);
            } catch (NumberFormatException e) {
                logger.warn("Error parsing " + ConfigData.DaysToKeepLogs, e);
                days = Integer.MAX_VALUE;
            }
            staleLogCalendar.add(Calendar.DAY_OF_YEAR, -Math.abs(days));
            final boolean deleteAllOld = days <= 0;
            FileFilter filter = new FileFilter() {

                @Override
                public boolean accept(java.io.File file) {
                    String name = file.getName();
                    if (name.startsWith(requiredName) && name.endsWith(requiredExt)) {
                        if (deleteAllOld) {
                            return true;
                        }

                        Date fileDate = null;
                        try {
                            String[] exts2 = Util.getExtensions(file.getName());
                            if (exts2 != null && exts2.length > 0) {
                                String timeString = exts2[0].replaceFirst("\\.", "");
                                long time = Long.parseLong(timeString);
                                fileDate = new Date(time);
                            } else {
                                fileDate = new Date(file.lastModified());
                            }
                        } catch (NumberFormatException e) {
                            fileDate = new Date(file.lastModified());
                        }

                        if (staleLogCalendar.getTime().after(fileDate)) {
                            return true;
                        }

                    }
                    return false;
                }
            };

            if (file != null) {
                TFile dir = file.getParentFile();
                if (dir != null) {
                    TFile[] logs = dir.listFiles(filter, dir.getArchiveDetector());
                    for (TFile log : logs) {
                        try {
                            log.rm();
                        } catch (IOException ex) {
                            logger.log(Level.ERROR, ex);
                            //Exceptions.printStackTrace(ex);
                        }
                    }
                }
            }
//        }
    }

    
    /**
     * The entry point for this application. Sets the Look and Feel to the
     * System Look and Feel. Creates a new JFrame and makes the GUI components
     * visible.
     *
     * @param args The command line arguments if any needed for application to
     * start up and any other data required for application execution.
     */
    static public void main(String args[]) {
        try {
            javax.media.jai.JAI testJai = new javax.media.jai.JAI();
            //System.out.println("JAI EVIDENCE: " + testJai.toString());
            AddCoveragesProcess acp = new AddCoveragesProcess();
            //System.out.println("ACP EVIDENCE: " + acp.toString());
// MEH log4j Should not be needed in log4j 2
// There is a bridge lib included with the log4j2 libs to handle this.
//            //link the java logger to the log4j
//            JavaLogging2Log4JHandler.install();

            //Workaround a jvm bug with multiple monitors and buffers
            //http://forums.java.net/jive/thread.jspa?messageID=328557
            System.setProperty("sun.java2d.d3d", "false");

            //Test java version
            if (About.getJavaSpecificationVersion() < 1.6) {
                JOptionPane.showMessageDialog(null, "WEPS requires the Java Runtime Environment 1.6  or higher."
                        + "\nPlease visit http://java.sun.com and upgrade to the latest version.",
                        "Java Upgrade Required", JOptionPane.ERROR_MESSAGE);
                return;
            }
                
            // The Geotools code calls this function.
            // We do not need / include the Netcdf C library.
            // However, this check function throws an error that looks bad.
            // So, disable the logger that is used to throw the error,
            // make the call, then re-enable the logger.
            // The Netcdf code remebers the result of this call
            // regardless of how many times it is called. So when
            // it is called later by Geotools, the result will be
            // remembered and another error will NOT be thrown.
            Log4jWepsConfigurationFactory factory = Log4jWepsConfigurationFactory.getCurrentFactory();
            if (factory != null) {
                factory.setLoggingOff();
            }

            ucar.nc2.jni.netcdf.Nc4Iosp.isClibraryPresent();

            if (factory != null) {
                factory.setLoggingOn();
            }



            // make settings default
            boolean setMainConfig = false;
            String working = null;
            String userWeps = null;
            String mainConfig = "cfg/defaults/weps.cfg";  // cfg/weps.cfg, now in weps defaults folder
            String userConfig = null;
            String logConfig = "cfg/log.cfg";
            String userHome = null;
            String log = null;
            String databases = null;
            
            boolean main_useWepsCert = false;

            // parse command line args
            for (int idx = 0; idx < args.length; idx++) {
                String cmd = args[idx].trim();
                switch (cmd) {
                    case "-working":
                        working = args[++idx];
                        working = working.replace('"', ' ').trim();
                        break;
                    case "-userweps":
                        userWeps = args[++idx];
                        break;
                    case "-db": // For weps.databases directory
                        databases = args[++idx];
                        break;
                    case "-cfg":
                        setMainConfig = true;
                        mainConfig = args[++idx];
                        break;
                    case "-usercfg":
                        userConfig = args[++idx];
                        break;
                    case "-logcfg":
                        logConfig = args[++idx];
                        break;
                    case "-userhome":
                        userHome = args[++idx];
                        break;
                    case "-log":
                        log = args[++idx];
                        break;
                    case "-help":
                    case "-?":
                    case "/?":
                        printHelp();
                        System.exit(0);
                        break;
                    case "-wsUseWepsCert":
                       /* main_useWepsCert = true; */
                       main_useWepsCert = false;  //Disable this functionality as old Symantic cert is no longer valid - LEW
                       break;
                    case "-wsMsiBuild":
                    	isMSIbuild = true;
                    	break;
                    case "-wsBuildName":
                        if (!isMSIbuild) {
	                        isWebstart = true;
	                }
                        try {
                            About.setWsBuildName(args[++idx]);
                        } catch(ArrayIndexOutOfBoundsException e) {
                            System.err.println("No build name defined. Some features may not work as the location will be undefined.");
                            logger.error("No build name defined. Some features may not work as the location will be undefined.");
                        }
                        break;
                    default:
                        System.out.println("Unknown option: " + args[idx]);
                        printHelp();
                        System.exit(0);
                        break;
                }
            }
                                        
            if (userWeps != null) {
                userWeps = Util.parse(userWeps);
                TFile userWepsFile = new TFile(userWeps).getCanOrAbsFile();
                About.setUserWepsRoot(userWepsFile);
            }

            if (working != null) {
                working = Util.parse(working);
                TFile workingFile = new TFile(working);
                if (!workingFile.exists()) {
                    System.err.println("Unable to resolve working directory: " + workingFile.getCanOrAbsPath());
                    logger.warn ("Unable to resolve working directory: " + workingFile.getCanOrAbsPath());
                   System.exit(-1);
                }
            }

            mainConfig = Util.parse(mainConfig);
            TFile mainConfigFile = new TFile(mainConfig).getCanOrAbsFile();
            
            if (mainConfig.toLowerCase().contains("nrcs")) {
                System.err.println("WEPS, setting NRCS mode");
                About.setWsNRCSModeFlag();
                isNRCSMode = true;
            }
            if (mainConfig.toLowerCase().contains("dev")) {
                System.err.println("WEPS, setting developer mode");
                isDevMode = true;
            }
            
            TFile userWepsDir = About.getUserWeps();
            boolean testForOldCfgDir = !userWepsDir.exists();
            
            System.out.printf("Current Working Directory: %s%n",
                    System.getProperty("user.dir"));
            //quit if we can't find the main config file.
            if (setMainConfig && !mainConfigFile.exists()) {
                System.err.println("Specified main config file not found.");
                logger.warn ("Specified main config file not found.");
                JOptionPane.showMessageDialog(null, "The master configuration file \""+ mainConfigFile.getAbsolutePath() + "\" specified does not exist.\n" +
                        "Please check configuration file specified in arguments.\n" +
                        "If using a configuration file from the 'cfg' directory,\n" +
                        "specify full path from working directory.\n(e.g. -cfg cfg\\<configuration file>)", "Configuration Error", JOptionPane.ERROR_MESSAGE);
                System.exit(-1);
            } 
            else if (!setMainConfig && !mainConfigFile.exists()) {
                // default file not found, and no file specified
                System.err.println("Default config file \"cfg\\defaults\\weps.cfg\" not found.");
                logger.warn ("Default master config file \"weps.cfg\" not found.");
                JOptionPane.showMessageDialog(null, "Default master configuration file \"cfg\\defaults\\weps.cfg\" not found.\n" +
                        "Please check configuration directories or specify a path to configuration file\n" +
                        "with arguments using the '-cfg <path\\to\\file>' option.", "Configuration Error", JOptionPane.ERROR_MESSAGE);
                System.exit(-1);
            }
            
            //Strip off the extensions
            String mainConfigNameNoExt = mainConfigFile.getName();
            mainConfigNameNoExt = Util.purgeExtensions(mainConfigNameNoExt,
                    Util.getExtensions(mainConfigNameNoExt));

            //if the user config is not set use the name of the main config file
            if (userConfig == null) {
                userConfig = About.getUserWeps().getAbsolutePath() + "/" + mainConfigFile.getName();
            }

            //if the log has not been set
            if (log == null) {
                log = About.getUserWeps().getAbsolutePath() + "/log/" + mainConfigNameNoExt + ".log";
            }
            
            if (userHome != null) {
                About.setUserHome(userHome);
            }
            
            /* set databases directory if specified on command line */
            if (databases != null) {
                //System.out.println("Setting {weps.databases} to '" + databases + "'");
                About.setDatabases(databases);
            }

            userConfig = Util.parse(userConfig);
            logConfig = Util.parse(logConfig);
            log = Util.parse(log);

            //setup log4j logging.
            TFile logConfigFile = new TFile(logConfig).getCanOrAbsFile();

            About.setLogConfig(logConfigFile);

            TFile logFile = new TFile(log);

            //add the current time to the log file, this allows for a log per instance
            TFile logDir = logFile.getParentFile();
            String timeExt = Long.toString(System.currentTimeMillis());
            String logName = logFile.getName();
            String[] exts = Util.getExtensions(logName);
            String logNameNoExt = Util.purgeExtensions(logName, exts);
            logName = Util.addExtensions(logNameNoExt + "." + timeExt, exts);
            logFile = new TFile(logDir, logName);

            Log4jWepsConfigurationFactory logFactory = Log4jWepsConfigurationFactory.getCurrentFactory();
            if (logFactory != null) {
                logFactory.updateLogFileName(logFile.getAbsolutePath());
            } else {
                logger.log(Level.ERROR, "Log4jWepsConfigurationFactory value is null, cannot reset logfile name to:"+logFile.getAbsolutePath());
            }

// MEH log4j should not need for log4j 2.
//            if (logConfigFile.exists()) {
//                try {
//                    Properties logProps = new Properties();
//                    InputStream in = new TFileInputStream(logConfigFile);
//                    logProps.load(in);
//                    logProps.setProperty("log4j.appender.file.File", logFile.getAbsolutePath());
//                    PropertyConfigurator.configure(logProps);
//                    logger.info("Configuring logger.");
//                } catch (IOException ex) {
//                    //error loading the cfg
//                    configureDefaultLoggers(logFile, ex);
//                }
//            } else {
//                //the log cfg file does not exist
//                configureDefaultLoggers(logFile, null);
//            }
            configureDefaultLoggers(logFile, null);

            // get the 'about' information, parse it, and log it
            {
                String[] strings = About.getAbout(Application.WEPS, false).split("\\n");
                for (String s : strings) {
                    logger.info(s);
                }
            }

            if (args.length > 0) {
                StringBuilder buffer = new StringBuilder("Command Arguments:\n");
                for (int i = 0; i < args.length; i++) {
                    buffer.append("\t[" + i + "]=" + args[i] + "\n");
                }
                logger.debug(buffer.toString());
            }

            boolean showWizard = checkForOldVersion(testForOldCfgDir, userWepsDir);

            ConfigData.getDefault().load(mainConfigFile, new TFile(userConfig).getCanOrAbsFile());
            
            //
            // Install the certificate for the https:infosys.ars.usda.gov site
            // And set a default SSL context which uses the keystore with this new cert
            //
            if (main_useWepsCert) {
                String certFilename;
                String certAlias;
                Certificate cert;
                    
                try {
                    //
                    // add certs into ssl context for this executuin cycle
                    //
                    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
                    keystore.load(null, null);

                    certFilename = "Resources/infosys.ars.usda.gov-symantec.crt";
                    certAlias = "infosys.ars.usda-symantec";
                    cert = CertificateFactory.getInstance("X.509")
                                       .generateCertificate(Weps.class.getResourceAsStream(certFilename));
                    if (!keystore.containsAlias(certAlias)) {
                        //System.out.println("Insert infosys.ars.usda.gov-symantec ssl certificate into ssl chain");
                        keystore.setCertificateEntry(certAlias, cert);
                    }
                    
                    //sdmdataaccess.sc.egov.usda.gov.crt
                    certFilename = "Resources/sdmdataaccess.sc.egov.usda.gov.crt";
                    certAlias = "sdmdataaccess";
                    cert = CertificateFactory.getInstance("X.509")
                                       .generateCertificate(Weps.class.getResourceAsStream(certFilename));
                    if (!keystore.containsAlias(certAlias)) {
                        //System.out.println("Insert soil data mart ssl certificate");
                        keystore.setCertificateEntry(certAlias, cert);
                    }
                    
                    //sdmdataaccess.sc.egov.usda.gov.crt
                    certFilename = "Resources/scegovusdagov.crt";
                    certAlias = "scegovusdagov";
                    cert = CertificateFactory.getInstance("X.509")
                                       .generateCertificate(Weps.class.getResourceAsStream(certFilename));
                    if (!keystore.containsAlias(certAlias)) {
                        //System.out.println("Insert 2nd soil data mart ssl certificate");
                        keystore.setCertificateEntry(certAlias, cert);
                    }
                    
//                    //Add nationalmapgov.crt for usgs mapviewer layer
//                    System.out.println("Adding NationalMap cert chain");
//                    certFilename = "Resources/nationalmapgov.crt";
//                    certAlias = "nationalmapgov";
//                    cert = CertificateFactory.getInstance("X.509")
//                                       .generateCertificate(Weps.class.getResourceAsStream(certFilename));
//                    if (!keystore.containsAlias(certAlias)) {
//                        //System.out.println("Insert nationalmapgov.crt ssl certificate");
//                        keystore.setCertificateEntry(certAlias, cert);
//                    }
//                    
//                    //Add DigiCertHighAssuranceEVRootCA.crt
//                    certFilename = "Resources/DigiCertHighAssuranceEVRootCA.crt";
//                    certAlias = "digicerthighassuranceevrootca";
//                    cert = CertificateFactory.getInstance("X.509")
//                                       .generateCertificate(Weps.class.getResourceAsStream(certFilename));
//                    if (!keystore.containsAlias(certAlias)) {
//                        //System.out.println("Insert DigiCertHighAssuranceEVRootCA.crt ssl certificate");
//                        keystore.setCertificateEntry(certAlias, cert);
//                    }
//                    
//                    //Add DigiCertSHA2HighAssuranceServerCA.crt
//                    certFilename = "Resources/DigiCertSHA2HighAssuranceServerCA.crt";
//                    certAlias = "digicertsha2highassuranceserverca";
//                    cert = CertificateFactory.getInstance("X.509")
//                                       .generateCertificate(Weps.class.getResourceAsStream(certFilename));
//                    if (!keystore.containsAlias(certAlias)) {
//                        //System.out.println("Insert DigiCertSHA2HighAssuranceServerCA.crt ssl certificate");
//                        keystore.setCertificateEntry(certAlias, cert);
//                    }
                    
                    // add keys into SSL
                    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    tmf.init(keystore);
                    SSLContext sslcontextCSIP = SSLContext.getInstance("TLS"); //SSLContexts.createSystemDefault();
                    sslcontextCSIP.init(null, tmf.getTrustManagers(), null);
                    SSLContext.setDefault(sslcontextCSIP);
                }
                catch(IOException | KeyManagementException | KeyStoreException | NoSuchAlgorithmException | CertificateException failureToAdd) {
                    System.err.println("Failed to add ssl certificate");
                    logger.warn ("Failed to add ssl certificate");
                    logger.warn ("Web Start: -wsUseWepsCert specified, but Failed to add ssl certificates.");
                    logger.warn (failureToAdd.getMessage());
                    //System.exit(0);                   
                }
            }
            
            //Add the default exception handler
            Thread.setDefaultUncaughtExceptionHandler(new WepsExceptionHandler(null));

            //Add the event queue listener
            try {
                Toolkit.getDefaultToolkit().addAWTEventListener(new WepsAWTEventListener(),
                        AWTEvent.MOUSE_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
            } catch (SecurityException e) {
                logger.debug("Unable to add a \"catch all\" AWTEventListener.", e);
            }

            //purge old log files so things don't get out of hand in the user directory
            deleteOldLogs(logFile);

            AuxPanel ap = null;
            Weps wp = null;
            try {
                
                // MEH
                // Experement for controlling fonts in GUI
                try {
                    WepsTheme newTheme = new WepsTheme();
                    newTheme.setThisTheme();
                    
                } catch (Exception ex) {
                    logger.debug("Set look and feel error:.", ex);
                }
                
                //Create a new instance of our application's frame, and make it visible.
                logger.debug("Creating Weps instance...");

                wp = new Weps();
                
                // get this going early
                //csipStatic = new CsipInputControllerStatic();
                wp.newCsipInputController();
                
                wp.setCursor(getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                
                wp.mainArgs = args;
                
                //Add a more complete exception handler
                Thread.setDefaultUncaughtExceptionHandler(new WepsExceptionHandler(wp));
                logger.debug("Weps instance created.");

                wp.cd = ConfigData.getDefault();
                logger.debug("Creating LoadProperties instance...");
                wp.propertyLoader = new LoadProperties();
                logger.debug("Done creating LoadProperties instance.");

                logger.debug("Applying property loader to weps...");
                wp.propertyLoader.setupPropertyHashtable(wp.getRootPane());
                logger.debug("Done applying property loader to weps.");

                // For server execution of science code, if a local server is required.
                wp.wsRunner = new WsCsipRunner();
                wp.wsRunner.setCdAndRunIfNeeded(wp.cd);

                //Link the mcrew configData to the weps config data
                usda.weru.mcrew.MCREWConfig.initialize(wp.cd);

                wp.rfd = new RunFileData(false);
                
                // this needs configdata and runfile data to have been initialized
                wp.getCsipInputController().initPropertyChanges();

                ClientPanel cp = new ClientPanel();
                cp.addPropertyChangeListener(wp.rfd);
                wp.rfd.addPropertyChangeListener(cp);
                wp.cd.addPropertyChangeListener(cp);

// This does not work.  The cfg filename is based on these parameters.
// Thus, you cannot read these values from a cfg file that you have openned.
// You will have openned the wrong filename because you have not yet set these parms.
// These parms need to be set before a cfg file is selected.
//                try {
//                    // Checks based on configuration file whether or not to set NRCS mode
//                    if (wp.cd.getData(ConfigData.isNRCSmode).equals("1")) {
//                        System.err.println("WEPS, setting NRCS mode");
//                        About.setWsNRCSModeFlag();
//                        isNRCSMode = true;
//                    }
//                } catch (java.lang.NullPointerException noXmlValueFound) {
//                    // Signals the parameter to specify was not found. Technically not a
//                    // necessary param, and old cfg files may not have it.
//                    System.err.println("No parameter specifying if program is in NRCS mode found. \n\tContinuing with normal mode.");
//                }
//                try {
//                    // Checks based on configuration file whether or not to set DEV mode
//                    if (wp.cd.getData(ConfigData.isDEVmode).equals("1")) {
//                        System.err.println("WEPS, setting developer mode");
//                        isDevMode = true;
//                    }
//                } catch (java.lang.NullPointerException noXmlValueFound) {
//                    // Signals the parameter to specify was not found. Technically not a
//                    // necessary param, and old cfg files may not have it.
//                    System.err.println("No parameter specifying if program is in developer mode found. \n\tContinuing with normal mode.");
//                }

                
                //sp.JP_main.setVisible(true);
                cp.JP_main.setLocation(4, 4);
                wp.JP_client.add(cp.JP_main);
                //wp.JP_main.add(sp.JP_main);
                //sp.setBounds(0,0,235,160);
                //sp.setLocation(200,200);
                SimulationPanel sp = new SimulationPanel();
                sp.addPropertyChangeListener(wp.rfd);
                wp.setSimulationPanel(sp);
                wp.rfd.addPropertyChangeListener(sp);
                wp.JP_sim.add(sp);
                wp.cd.addPropertyChangeListener(sp);

                wp.rp = new RegPanel();
                wp.rp.addPropertyChangeListener(wp.rfd);
                wp.rfd.addPropertyChangeListener(wp.rp);
                wp.cd.addPropertyChangeListener(wp.rp);
                //rp.JP_main.setVisible(true);
                wp.rp.JP_main.setLocation(4, 4);
                wp.JP_reg.add(wp.rp.JP_main);
                //			wp.JP_main.add(rp.JP_main);

                wp.bp = new BarPanel();
                wp.bp.addPropertyChangeListener(wp.rfd);
                wp.rfd.addPropertyChangeListener(wp.bp);
                wp.cd.addPropertyChangeListener(wp.bp);
                //bp.JP_main.setVisible(true);
                wp.bp.JP_main.setLocation(4, 4);
                wp.JP_bar.add(wp.bp.JP_main);
                //wp.JP_main.add(bp.JP_main);

                //LocPanel lp = new LocPanel(wp);
                //lp.addPropertyChangeListener(wp.rfd);
                //wp.rfd.addPropertyChangeListener(lp);
                //wp.cd.addPropertyChangeListener(lp);
                //lp.JP_main.setVisible(true);
                //lp.JP_main.setLocation(4, 4);
                lp = new LocationPanel(wp.getRunFileData().getBean());
                lp.setWepsInstance(wp);
                wp.JP_loc.add(lp);
                
                //wp.JP_main.add(lp.JP_main);

                boolean enableMcrew = !wp.getCsipInputController().isLoading();
               
                if (!enableMcrew) {
                    wp.disableMcrewElements();
//                    wp.runButton.setEnabled(false);
//                    wp.runCalButton.setEnabled(false);
//                    wp.M_run.setEnabled(false);
                }
                
                //AuxPanel ap = new AuxPanel(wp.hb);
                ap = new AuxPanel(wp.cd, enableMcrew);
                wp.ap = ap;
                wp.addPropertyChangeListener(ap);
                ap.addPropertyChangeListener(wp.rfd);
                wp.rfd.addPropertyChangeListener(ap);
                wp.cd.addPropertyChangeListener(ap);
                //ap.JP_main.setVisible(true);
                        
                /**
                 * This block of code allows the MCREW and Soil drop downs to
                 * resize with the main WEPS screen.
                 */
                GroupLayout borderControl = new GroupLayout(wp.JP_aux);
                borderControl.setHorizontalGroup(
                        borderControl.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(borderControl.createSequentialGroup()
                                .addContainerGap(5, 5)
                                .addComponent(ap.JP_main, javax.swing.GroupLayout.DEFAULT_SIZE, 800, Short.MAX_VALUE)
                                .addContainerGap(5, 5)
                        ));
                borderControl.setVerticalGroup(
                        borderControl.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(borderControl.createSequentialGroup()
                                .addContainerGap(5, 5)
                                .addComponent(ap.JP_main, javax.swing.GroupLayout.DEFAULT_SIZE, 800, Short.MAX_VALUE)
                                .addContainerGap(5, 5)
                        ));
                //add(ap.JP_main);
                wp.df = new DrawField();
                wp.rfd.addPropertyChangeListener(wp.df);
                wp.df.setBackground(Color.white);
                wp.df.setSize(210, 210);
                //df.setVisible(true);
                wp.df.setLocation(5, 5);
                wp.JP_map.add(wp.df);

                NotPanel np = new NotPanel();
                //np.JP_main.setVisible(true);
                //  np.JP_main.setLocation(4, 4);
                wp.JP_not.add(np.JP_main);
                np.addPropertyChangeListener(wp.rfd);
                wp.rfd.addPropertyChangeListener(np);
                wp.cd.addPropertyChangeListener(np);

                wp.cd.addPropertyChangeListener(wp);
                wp.addPropertyChangeListener(wp.cd);
                wp.rfd.addPropertyChangeListener(wp);
                wp.addPropertyChangeListener(wp.rfd);

                wp.rfd.addPropertyChangeListener(wp.cd);
                wp.cd.addPropertyChangeListener(wp.rfd);

                wp.bp.addPropertyChangeListener(wp.df);
                wp.df.addPropertyChangeListener(wp.bp);

//                // Webstart: check local (GUI) and remote cligen db files match.
//                //ConfigPanel_n.checkCligenRemoteParams(null);
//                new ConfigPanel(wp).checkCligenRemoteParams(null);
                
                wp.validate();
                wp.cd.fireAll();

                {
                    wp.JB_RR.setVisible(wp.cd.getReportVisibility(wp.JB_RR.getName()));
                    wp.JB_MR.setVisible(wp.cd.getReportVisibility(wp.JB_MR.getName()));
                    wp.JB_CR.setVisible(wp.cd.getReportVisibility(wp.JB_CR.getName()));
                    wp.JB_CC.setVisible(wp.cd.getReportVisibility(wp.JB_CC.getName()));
                    wp.JB_CI.setVisible(wp.cd.getReportVisibility(wp.JB_CI.getName()));
                    wp.JB_SR.setVisible(wp.cd.getReportVisibility(wp.JB_SR.getName()));
                    wp.JB_DR.setVisible(wp.cd.getReportVisibility(wp.JB_DR.getName()));
                    wp.JB_IR.setVisible(wp.cd.getReportVisibility(wp.JB_IR.getName()));
                }
                //splash.setVisible(false);
                //splash.dispose(); //dispose the splash screen
                
                // Webstart
                // Log the data version
                if (isWebstart == true) {
                	logger.info("WebStart: data version: " + About.getWepsDataVersion());
                }
                else {
			logger.info("MSI build, no data version reported.");
		}
		
                wp.dataChanged = false;

                wp.setLocaleTo(Locale.US);
                wp.loadCurrentProject(wp);
//                System.out.println("weps.ini entry for SFLT: "+wp.rfd.getData("RFD-SelectFieldLocTxt"));

                // start the MapViewer loading
                // wait until here, after loadCurrentProject to avoid conflicts with RFD.
                lp.reloadMapViewer();
                lp.mapButton.setText(wp.rfd.getData("RFD-SelectFieldLocTxt"));
                
                try {
                    LoadingContext.enter();
//                    wp.rfd.fireAll();
                } finally {
                    LoadingContext.exit();
                }

                //System.out.println("W_m: " + wp.projectDirectory);
                Util.loadToolTips((Container) wp, new TFile("cfg", "tooltips.cfg"));
                Util.adjustLabelWidths(wp);

                String myprojFile = new TFile(wp.projectDirectory).getName();
                int proFileExtIndex = myprojFile.lastIndexOf(".");

                if (proFileExtIndex > 0) {

                    String projFileStr = myprojFile.substring(0, proFileExtIndex);
                    wp.setTitle(projFileStr);

                } else {
                    //System.err.println("W_m: Project Title not set, File name is : " + myprojFile );
                }

                wp.setTTTime("", 3);

                // TODO: find out what 4EDT means and document - LEW
                final Weps weps4EDT = wp;
                boolean userName = wp.cd.getData(ConfigData.UserFullName) != null
                        ? wp.cd.getData(ConfigData.UserFullName).equals("") : true;
                boolean userEmail = wp.cd.getData(ConfigData.MantisEmail) != null
                        ? wp.cd.getData(ConfigData.MantisEmail).equals("") : true;
                final boolean showWizard4EDT = userName && userEmail;
                EventQueue.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        weps4EDT.setVisible(true);
                        if (showWizard4EDT) {
                            WelcomeWizard wizard = new WelcomeWizard();
                            wizard.show();
                        }
                        //check if there is a file reference problem
                        Thread task = fileReferenceThread(weps4EDT);
                        task.start();
                        
                    }
                });
            } catch (java.lang.OutOfMemoryError e) {
                JOptionPane.showMessageDialog(wp, "JVM has used all available memory\n"
                        + "Please restart to reset memory pool",
                        "Out of memory", JOptionPane.ERROR_MESSAGE);
                logger.error("Out of memory.", e);
            } catch (HeadlessException t) {
                logger.error(t.getMessage(), t);
                //Ensure the application exits with an error condition.
                System.exit(1);
            }

            //set the cursor back to default on the main Weps screen
            wp.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
           
            // This creates the dropdown menus for quickplots
            wp.createdynamicQuickplotMenu(wp.cd.getData(ConfigData.DetailTableFilterFile));
//            // Nowhere to put this yet. MEH.
//            WepsTreeModelPrism c_prismModel = new WepsTreeModelPrism(null, true);
            
            // signal to bootloader
            About.writeWepsRunningFile();

            //Setup thread to watch for deleted management/soil files.
            final Weps wp2 = wp;
            final AuxPanel ap2 = ap;
            wp2.fileWatcher = fileWatcherThread(wp2, ap2);

            wp2.fileWatcher.start();
            wp.wepsInitComplete = true;
            
            // check on the tile image file cache
            TileCacheCleaner.checkAndCleanTileCacheInThread();
//            new Thread () {
//                public void run() {
//                    TileCacheCleaner.SummaryResult res = TileCacheCleaner.doGetCacheSummary();
//                    int j = 1;
//                    
//                    while (res.totalSize > 256000000) {
//                        //TileCacheCleaner.OldestResult oldestres = TileCacheCleaner.doGetOldest();
//                        TileCacheCleaner.doClearOldest();
//                        int k = 1;
//                        
//                        res = TileCacheCleaner.doGetCacheSummary();
//                        j = 1;
//                    }
//                }
//            }.start();
        } catch (HeadlessException e) {
            logger.fatal("Unable to start application.", e);
        }
    }

    private static boolean checkForOldVersion(boolean testForOldCfgDir, TFile userWepsDir) {
        //check for previous version
        boolean showWizard = false;
        try {
            if (testForOldCfgDir) {
                showWizard = true;
                logger.debug("User directory does not exist: " + userWepsDir.getAbsolutePath());
                //first run with this version, do we have previous versions?
                TFile previousWepsDir = PreviousVersionResolver.findPreviousSettingsDirectory(
                        new TFile(userWepsDir.getParentFile()), ReleaseVersion.valueOf(userWepsDir));
                if (previousWepsDir != null) {
                    logger.debug("Previous user directory found: " + previousWepsDir.getAbsolutePath());
                    JOptionPane pane = new JOptionPane(
                            "User settings created by a previous version of WEPS were found at "
                            + previousWepsDir.getAbsolutePath() + ". \nDo you want to import them?",
                            JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
                    final JDialog dialog = pane.createDialog("Confirm Import Settings");
                    dialog.setAlwaysOnTop(true);
                    try {
                        EventQueue.invokeAndWait(new Runnable() {

                            @Override
                            public void run() {
                                dialog.setVisible(true);
                            }
                        });
                    } catch (InterruptedException | InvocationTargetException e) {
                        logger.warn("Unable to display dialog.", e);
                    }

                    Object value = pane.getValue();
                    int result = value != null ? Integer.valueOf(value.toString()) : JOptionPane.NO_OPTION;

                    if (result == JOptionPane.YES_OPTION) {
                        //copy over the old settings
                        logger.debug("User selected to import settings.");
                        boolean imported = PreviousVersionResolver.importSettings(previousWepsDir, userWepsDir);

                        if (!imported) {
                            logger.warn("Import failed.");
                            JOptionPane.showMessageDialog(null, "Unable to import all of the previous settings."
                                    + " Please verfiy your settings in the configuration window.",
                                    "Import Settings Error", JOptionPane.ERROR_MESSAGE);
                        } else {
                            logger.debug("Import succeeded.");
                            showWizard = false;
                        }
                    } else {
                        logger.debug("User selected to NOT previous import settings.");
                    }
                }
            }
        } catch (HeadlessException | SecurityException | NumberFormatException e) {
            logger.error("Unable to import previous settings", e);
        }
        return showWizard;
    }

    /**
     * Locale change. We only support US
     *
     * @param l should always be Locale.US
     */
    private void setLocaleTo(Locale l) {
        /**
         * Note: Assertions are not enabled. These will be useless items unless
         * assertions are enabled. Thus, they will be commented out unless the
         * user wishes to enable specific assertions (feed the virtual machine
         * the -ea argument).
         */
//        assert l == Locale.US;
        Locale current = Locale.getDefault();
        boolean changedLocale = false;
        if (current.equals(l) == false) {
            //Change the locale to US
            Locale.setDefault(l);
            changedLocale = true;
            logger.warn("Changed locale to US.");
        }
        if (changedLocale && warnAboutLocale) {
            LocalePanel_n panel = new LocalePanel_n();
            String text = "WEPS has detected that this machine is using the " + current.getDisplayName()
                    + " locale.  WEPS uses the " + Locale.US.getDisplayName()
                    + " locale.  You do not need to change your machine's locale, "
                    + "but be aware that numbers will be formatted in the "
                    + Locale.US.getDisplayName() + " style.";
            text = "<html>" + text + "</html>";
            panel.jl_text.setText(text);
            JOptionPane.showMessageDialog(this, panel, "System Locale Warning", JOptionPane.WARNING_MESSAGE);
            if (panel.jcb_displayWarning.isSelected()) {
                cd.setData(ConfigData.DoNotWarnAboutSystemLocale, "1");
                cd.save();
            }
        }
    }

    private static Thread fileReferenceThread(final Weps weps4EDT) {
        return new Thread("File Reference Checking") {
            @Override
            public void run() {
                if (weps4EDT.cd.isFileReferenceErrorInConfigData()) {

                    try {
                        weps4EDT.c_configPanel = new ConfigPanel(weps4EDT);
                        EventQueue.invokeAndWait(new Runnable() {

                            @Override
                            public void run() {
                                JOptionPane warningPane = new JOptionPane(
                                        "The current WEPS configuration references files "
                                        + "that can no longer be found. "
                                        + "This may cause unexpected errors. "
                                        + "Please edit your configuration or "
                                        + "contact your system administrator.",
                                        JOptionPane.WARNING_MESSAGE) {
                                    private static final long serialVersionUID = 1L;

                                    @Override
                                    public int getMaxCharactersPerLineCount() {
                                        return 80;
                                    }
                                };
                                JDialog warningDialog
                                        = warningPane.createDialog("File Reference Error");
                                warningDialog.setAlwaysOnTop(true);
                                warningDialog.setVisible(true);
                                weps4EDT.c_configPanel.setVisible(true, true);

                            }
                        });
                        // wait for the config panel to close
                        while (weps4EDT.c_configPanel.isVisible()) {
                            Thread.yield();
                        }
                        if (weps4EDT.cd.isFileReferenceErrorInConfigData()) {
                            EventQueue.invokeAndWait(new Runnable() {

                                @Override
                                public void run() {
                                    JOptionPane error = new JOptionPane(
                                            "The file reference errors are still "
                                            + "unresolved.  This may cause unexpected errors.",
                                            JOptionPane.ERROR_MESSAGE) {
                                        private static final long serialVersionUID = 1L;

                                        @Override
                                        public int getMaxCharactersPerLineCount() {
                                            return 80;
                                        }
                                    };
                                    JDialog errorDialog
                                            = error.createDialog("File Reference Error");
                                    errorDialog.setAlwaysOnTop(true);
                                    errorDialog.setVisible(true);
                                }
                            });

                        }
                    } catch (InterruptedException | InvocationTargetException e) {
                    }
                }

            }
        };
    }

    private static Thread fileWatcherThread(final Weps wp2, final AuxPanel ap2) {
        return new Thread("File Watcher") {

            @Override
            public void run() {
                try {
                    while (wp2 != null) {
                        if (wp2.manFileName != null && wp2.manFileName.length() > 0) {
                            TFile manFile = new TFile(wp2.manFileName);
                            if (!manFile.exists()) {
                                //Man file was deleted.
                                EventQueue.invokeLater(new Runnable() {
                                    @Override
                                    public void run() {
                                        wp2.changes.firePropertyChange(RunFileData.ManageFile,
                                                wp2.manFileName, "");
                                    }
                                });

                            }
                            manFile = null;
                        }

                        if (wp2.soilFileName != null && wp2.soilFileName.length() > 0) {
                            TFile soilFile = new TFile(wp2.soilFileName);
                            if (!soilFile.exists()) {
                                //Man file was deleted.
                                EventQueue.invokeLater(new Runnable() {
                                    @Override
                                    public void run() {
                                        wp2.changes.firePropertyChange(RunFileData.SoilFile,
                                                wp2.soilFileName, "");
                                    }
                                });
                            }
                            soilFile = null;
                        }

                        Thread.sleep(60000);
                    }
                } catch (InterruptedException ex) {
                }
            }
        };
    }
    public transient Thread fileWatcher;

    /**
     * Sets whatever the title of the screen is passed as argument.
     *
     * @param title The title of WEPS application GUI
     */
    @Override
    public void setTitle(String title) {
        updateTitle();
        // Setting the Icon Image in the title bar
        super.setIconImage(About.getWeruIconImage());
    }

    private void updateTitle() {
        String title = "";
        if (projectDirectory != null && projectDirectory.length() > 0) {
            TFile project = new TFile(projectDirectory);
            title = project.getName();
            if (title.toLowerCase().endsWith(".wpj")) {
                title = title.substring(0, title.length() - 4);
            }
        }
        super.setTitle("WEPS Project: " + title);
        String mostRecentRunName = "";
        if (lastRun != null) {
            mostRecentRunName = new TFile(lastRun).getName();
            mostRecentRunName = mostRecentRunName.replace(".wjr", "");
        }
        JTF_mostRecentRun.setText(mostRecentRunName);
    }
     
    private void createdynamicQuickplotMenu( String detailFilterLocation) {
        TFile filters = new TFile(detailFilterLocation);
        Element node = Helper.getRootNode(filters);
        List<Element> qnames = node.getChildren("filterset");
        
        // For current run
        ActionListener actionListener = (ActionEvent event) -> {
            dynamic_quickplot_actionPreformed(event);
        };
        // For selecting a run
        ActionListener actionListenerSelectRun = (ActionEvent event) -> {
            dynamic_quickplot_actionPreformedSelectRun(event);
        };
        
        try {
            for (Element filterSetNode : qnames) {
                FilterSet filterSet = new FilterSet();
                filterSet.fromXml(filterSetNode);
                String qname = filterSet.getqplotname();
                if (qname != null) { // add all menu items and action listeners to dropdown menu
                    c_instance.MI_QuickPlot_MostRecentRun.add(qname);
                    c_instance.MI_QuickPlot_MostRecentRun.getItem(c_instance.MI_QuickPlot_MostRecentRun.getItemCount() - 1).addActionListener(actionListener);
                    c_instance.MI_QuickPlot_PreviousRun.add(qname);
                    c_instance.MI_QuickPlot_PreviousRun.getItem(c_instance.MI_QuickPlot_PreviousRun.getItemCount() - 1).addActionListener(actionListenerSelectRun);
                    // weps interface quickplot button, need temporary JMenuItem for a JPopupMenu
                    javax.swing.JMenuItem temp = new javax.swing.JMenuItem();
                    temp.setText(qname);
                    temp.addActionListener(actionListener);
                    c_instance.quickPlotMenu.add(temp);
                }
            }
        } catch (ConcurrentModificationException ex) {
            System.out.println("=== EXCEPTION IN createDynamicQuickPlotMenu() ===");
        }
    }

    /**
     * Creates a new project
     * @param projName
     * @param forceSuffix if the weps project suffix is added regardless of how projName came in
     * @param overwrite - ff the project is to be overwritten or new on is to be created
     * @param saveLastRun - if the last run is to be preserved in the new project or not
     * @throws IOException 
     */
    private void makeProject(String projName, boolean forceSuffix, boolean overwrite, boolean saveLastRun) throws IOException {
        
        String lastrundata = rfd.getData(RunFileData.LastRun) != null ? rfd.getData(RunFileData.LastRun) : "";
        // rfd.removeRunData()
        TFile mU = new TFile(projName);
        if (overwrite) {
            if (!mU.exists()) {
                JOptionPane.showMessageDialog(this, "Cannot overwrite file, does not exist.",
                        "Error", JOptionPane.WARNING_MESSAGE);
                throw new IOException("Cannot overwrite file, does not exist.");
            }
            String absPath = mU.getAbsolutePath();
            System.out.println("abs: " + absPath);
            
            
            int res = JOptionPane.showConfirmDialog(this, "\tWARNING\n" +
                     "YOU ARE ABOUT TO OVERWRITE THE ENTIRE PROJECT:\n" +
                    absPath + 
                    "\nThis will remove ALL files inside this directory.\n" +
                    "Are you sure you want to do that?", "DELETE PROJECT WARNING", JOptionPane.YES_NO_OPTION);
            if (res == JOptionPane.NO_OPTION)
                return;
            
            if (res == JOptionPane.YES_OPTION) {
                res = JOptionPane.showConfirmDialog(this, "Are you sure you want to overwrite this project:\n" +
                        absPath, "DELETE PROJECT WARNING", JOptionPane.YES_NO_OPTION);
                if (res == JOptionPane.NO_OPTION)
                    return;
            }
            
            // If we made it here, we can safely delete the project, and make a new directory with the same name.
            rfd.removeRunData(new TFile(mU));
            
            mU = new TFile(absPath);
            
            if (!mU.mkdirs()) { 
                JOptionPane.showMessageDialog(this, "Failed to create new project directory",
                        "Error (W-002)", JOptionPane.WARNING_MESSAGE);
                throw new IOException("Cannot create project directory");
            }
            
        } else {
            // no file overwriting
            if (forceSuffix) {
                if (!projName.endsWith(RunFileData.ProjectSuffix)) {
                    projName += RunFileData.ProjectSuffix;
                }
            }
            if (!mU.isAbsolute()) {
                mU = new TFile(projectsPath, projName);
            }
            if (mU.exists()) {
                JOptionPane.showMessageDialog(this, "Project directory already exists",
                        "Error (W-001)", JOptionPane.WARNING_MESSAGE);
                throw new IOException("Project directory already exists");
            }
            if (!mU.mkdirs()) { 
                JOptionPane.showMessageDialog(this, "Cannot create project directory",
                        "Error (W-002)", JOptionPane.WARNING_MESSAGE);
                throw new IOException("Cannot create project directory");
            }
        }
        
        //changes.firePropertyChange(ConfigData.CurrentProj, null, mU.getAbsolutePath());
        cd.setData(ConfigData.CurrentProj, mU.getAbsolutePath());

        if (!cd.getDataParsed(ConfigData.NewProjectDefaultRunsLocation).equals("")) {
            cd.setData(ConfigData.DefaultRunsLocation, cd.getDataParsed(ConfigData.NewProjectDefaultRunsLocation));
            runsLocationPath = cd.getDataParsed(ConfigData.NewProjectDefaultRunsLocation);
        }
        lp.resetChooserToDefaults();
        // save last run or set to empty string for new project
        changes.firePropertyChange(RunFileData.LastRun, null, saveLastRun ? lastrundata : "");
        cd.save();
        setTitle(mU.getName());
    }
    
    private String [] findDirectoryAndFile (String filepath){
        //splits the path apart from its file name and returns a string array with dir in its 0 index and the file name in its 1 index
        String [] fullPath = filepath.split("/|\\\\");
        String dir = "";
        String file = "";
        for(int i = 0; i < fullPath.length; i++){
            if(i == fullPath.length -1){
                file = fullPath[i];
                continue;
            }
            dir += fullPath[i] + "/";
            
        }
        return new String [] {dir, file};
    }
    
    private boolean saveProjectDialog(java.awt.event.ActionEvent event) {
        if(dataChanged) {
            int res = JOptionPane.showConfirmDialog(this, "Save current WEPS project?",
                    "Save Project", JOptionPane.YES_NO_CANCEL_OPTION);
            switch (res) {
                case JOptionPane.CANCEL_OPTION:
                    return false;
                case JOptionPane.YES_OPTION:
                    saveItem_actionPerformed(event);
                    break;
                case JOptionPane.NO_OPTION:
                    break;
            }
        }
        
        return true;
    }
    
    /**
     * Helper Method for newItem_ActionPerformed()
     * Assure that the defaultProjectPath is correct, because it isn't get updated properly.
     * 
     * EL 09/20 - might be getting updated correctly and in that case this won't be necessary
     * 
     * @return String[] index 0: projectPath index 1: current project folder (.wpj)
     */
    private String[] getProjectPath() {
        String[] defaultProjectPath = findDirectoryAndFile(defaultProjectsPath);
        String[] projectPath = findDirectoryAndFile(projectsPath);
        
        if (!defaultProjectPath[0].equals(projectPath[0] + projectPath[1])) {
            defaultProjectPath[0] = projectPath[0] + projectPath[1];
        }
        
        return defaultProjectPath;
    }
    
    public void createDirectory(String filename) {
        File newDir;
        if (filename != null && filename.length() > 1) {
            newDir = new File (filename);
            if (!newDir.exists()) {
                newDir.mkdirs();
            }
        }
    }
    
    /**
     * Used to create any local subdirectories in the projects folder
     */
    public void createLocalDirectories() {
        String[] localDB = {
            ConfigData.getDefault().getDataParsed(ConfigData.DefaultRunsLocationTemplate),
            ConfigData.getDefault().getDataParsed(ConfigData.LocalCropDB),
            ConfigData.getDefault().getDataParsed(ConfigData.localResidueRecords),
            ConfigData.getDefault().getDataParsed(ConfigData.LocalManDB),
            ConfigData.getDefault().getDataParsed(ConfigData.LocalOpDB),
            ConfigData.getDefault().getDataParsed(ConfigData.LocalSoilDB),
            ConfigData.getDefault().getDataParsed(ConfigData.LocalSDMDB),
            ConfigData.getDefault().getDataParsed(ConfigData.ManSkel),
            ConfigData.getDefault().getDataParsed(ConfigData.LocalManDB)
        };
        
        for(String s : localDB) {
            this.createDirectory(s);
        }
    }
    
    /**
     * Used for the initial creation of a project in a fresh install
     */
    public void newInitialProject() {
        String[] projectPath = getProjectPath();
        TFile newProject = new TFile(projectPath[0], projectPath[1]);
                    
        try {
            this.makeProject(newProject.getCanonicalPath(), true, false, false);
            rfd.initialize();
            rfd.fireAll();
            rfd.writeRunDataXML(projectDirectory);
            setTitle(newProject.getName()); //Set the title of the window with no run name since this is a new project - neha
            g_runlocation.setText(runsLocationPath); //g_runlocation.setText(cd.getDataParsed(ConfigData.DefaultRunsLocation));

            RunNameChooser rnc = new RunNameChooser(rfd, false); // create WS_WEPS Runs folder
            rnc.setNewProject();
        } catch (IOException e) {
            //System.err.println("nIaP: projectsDir " + e);
        }
    }
    
    /**
     * Used to either set up a new project or load one. For when a user selects
     * a new Project Folder in the config settings.
     * 
     * If the project folder exists set it to that project
     * 
     * otherwise create a new project
     */
    public void loadOrCreateNewProjectFolder() {
        String[] projectPath = getProjectPath();
        TFile projectFolder = new TFile(projectPath[0], projectPath[1]);
        try {
            if (projectFolder.exists()) {
                String projectDir = projectFolder.getCanonicalPath();

                changes.firePropertyChange(ConfigData.CurrentProj, null, projectDir);
                changes.firePropertyChange(RunFileData.LastRun, null, "");
                rfd.initialize();
                TFile runData = new TFile(projectDir, RunFileData.WepsData);

                if (runData.exists()) {
                    rfd.readRunData(projectDir);
                } else {
                    rfd.writeRunDataXML(projectDir);
                }
                
                this.winCliMode();
                
            } else {
                this.newInitialProject();
            }
        } catch (IOException io) {
            System.err.println("problems loading project directory from config panel");
        }
    }

    @Override
    public void newItem_actionPerformed(java.awt.event.ActionEvent event) {
        if(!this.saveProjectDialog(event)) {
            return;
        }
        
        String [] projectPath = findDirectoryAndFile(projectDirectory);
        TFile newProject = Util.incrementFileName(new TFile(projectPath[0] ,projectPath[1] ), null, ".wpj");
//        String[] projectPath = getProjectPath();
//        TFile newProject;
//        newProject = Util.incrementFileName(new TFile(projectPath[0], projectPath[1]), null, ".wpj");
//            
        TFile checkProjectPath = new TFile(projectPath[0]);

        if (!checkProjectPath.exists()) {
            JOptionPane.showMessageDialog(this, "Projects location not found:\n" 
                    + checkProjectPath.getPath(),
                    "Path Warning", 
                    JOptionPane.WARNING_MESSAGE);
        }

        String dir = projectsPath; // same as projectPath[0]
        WepsFileChooser2 wpc = new WepsFileChooser2(WepsFileTypes2.Project, dir,
                WepsFileChooser2.Action.Create);
        wpc.setCurrentDirectory(projectPath[0]);
        
        wpc.homeToolTip(wpc); // set the tooltip of "home" button to "Home" instead of "Desktop"
        wpc.enableDbButton(false);
        wpc.setPersistSelectedFile(true);
        wpc.setSelectedFile(newProject);
        wpc.setDialogTitle("New Project");
        wpc.setText(newProject.getName()); // Required because we are persisting the file name.
        
        wpc.setFileSelectionMode(WepsFileChooser2.SelectionType.FILES_AND_DIRECTORIES);
        wpc.setDefaultDirectory(new TFile(projectsPath));
        wpc.setCurrentDirectory(new TFile(projectsPathCheck(projectsPath)).getAbsolutePath());
        
        boolean overwrite_project = false;

        TFile selected;

        if (wpc.showDialog(this) == TFileChooser.APPROVE_OPTION) {
            
            selected = new TFile(wpc.getSelectedFile());

            // need to make sure the file exists first
            if (selected.exists()) {
                if (ConfigData.getDefault().getData(ConfigData.SetProjectOverwrite).equals("0")) {
                    JOptionPane.showMessageDialog(this, "This project already exists and WEPS is set to not allow Project Overwrite.",
                            "Project Already Exists", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                if (!selected.isDirectory() || !isWepsProject(selected)) {
                    JOptionPane.showMessageDialog(this, "This does not appear to be a Weps Project, so it\n"
                            + "cannot be overwritten by this program.", "Weps", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                int res = JOptionPane.showConfirmDialog(this,
                        "This Project already exists. Would you like to overwrite the project\n"
                        + "and reuse the name?", "Overwrite Project",
                        JOptionPane.YES_NO_OPTION);
                if (res == JOptionPane.NO_OPTION) {
                    return;
                }
                
                overwrite_project = true;
            }
            
            try {
                makeProject(selected.getCanonicalPath(), true, overwrite_project, false);
                rfd.initialize();
                rfd.fireAll();
                rfd.writeRunDataXML(projectDirectory);
                setTitle(selected.getName()); //Set the title of the window with no run name since this is a new project - neha
                g_runlocation.setText(runsLocationPath); //g_runlocation.setText(cd.getDataParsed(ConfigData.DefaultRunsLocation));
                RunNameChooser rnc = new RunNameChooser(rfd, false); // create WS_WEPS Runs folder
                rnc.setNewProject();
                this.ap.clearManageFile();
            } catch (IOException e) {
                //System.err.println("nIaP: projectsDir " + e);
            }
        }
    }
    
    /**
     * This method checks that a file meets the basic requirements to be considered
     * a weps project.
     * @param file
     * @return 
     */
    private boolean isWepsProject(TFile file) {
        if (!file.isDirectory()) {
            return false;
        }
//        if (!file.getName().endsWith(".wpj")) {
//            return false;
//        } else {
           try {
               TFile test = new TFile(file.getAbsolutePath() + File.separator + "weps.ini");
               if (!test.exists()) {
                   return false;
               }
           } catch (Exception e) {
               return false;
           }
//        }
        return true;
    }

    @Override
    public void openItem_actionPerformed(java.awt.event.ActionEvent event) {
        if(!this.saveProjectDialog(event)) {
            return;
        }
        TFile projectsFolder = new TFile(projectsPath);
        if (!projectsFolder.exists()) {
            JOptionPane.showMessageDialog(this, "Projects location not found:\n" + projectsFolder.getPath(),
                    "Path Warning", JOptionPane.WARNING_MESSAGE);
        }
        WepsFileChooser2 wfc = null;
        try {
            
            wfc = new WepsFileChooser2(WepsFileTypes2.Project, projectsPath, WepsFileChooser2.Action.Open);
            wfc.homeToolTip(wfc);
            wfc.setDefaultDirectory(new TFile(projectsPath));
            wfc.setCurrentDirectory(new TFile(projectsPathCheck(projectsPath)).getAbsolutePath());
            
            wfc.setFileSelectionMode(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY);
            wfc.setDoubleClickSelect(true, ".wpj");
            wfc.setApproveButtonText(WepsFileChooser2.ApproveText.OPEN_SELECTED_PROJECT);
            wfc.setFileFolderText(WepsFileChooser2.ApproveText.FOLDER);
            wfc.setDialogTitle("Open Project");
            wfc.enableDbButton (false);
            
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(this, "Internal error has occurred\nRestart and create new project",
                    "Error (W-003)", JOptionPane.ERROR_MESSAGE);
            //System.err.println("W_oI_aP: " + e);
            return;
        }

        if (wfc.showDialog(this) != TFileChooser.APPROVE_OPTION) {
            //System.out.println("W_oKaP: not approved");
            return;
        }

        TFile sf = new TFile(wfc.getSelectedFile());
        // To handle an error in the file chooser or file system gracefully.
        if(sf.isFile()){
            return;
        }
        
        if (!sf.exists()) {
            JOptionPane.showConfirmDialog(this, "There project that has been selected appears to not exist on the \n" +
                    "file system. This could be due to an error in the selection process" +
                    "or an internal error. Please try again.\n\n" +
                    "PATH: " + sf.getAbsolutePath(), "Error in selecting project", JOptionPane.ERROR_MESSAGE);
            return;
        }
        
        if (!isWepsProject(sf)) {
            int res = JOptionPane.showConfirmDialog(this, 
                    "This file does not appear to be a WEPS project. This\n" +
                            "could be due to it's name, or it is missing some files\n" +
                            "usually associated with a WEPS project. \n\n" +
                            "Would you like to continue anyways?", "Open Project", JOptionPane.ERROR_MESSAGE);
            if (res == JOptionPane.NO_OPTION)
                return;
        }

        try {
            String projectsDir = sf.getCanonicalPath();
            changes.firePropertyChange(ConfigData.CurrentProj, null, projectsDir);
            changes.firePropertyChange(RunFileData.RunsLocation, null, projectsDir);
            changes.firePropertyChange(RunFileData.LastRun, null, "");
            

            LoadingContext.enter();
            try {
                rfd.initialize();
                TFile runData = new TFile(projectsDir, RunFileData.WepsData);
                if (runData.exists()) {
                    rfd.readRunData(projectsDir);
                } else {
                    rfd.writeRunDataXML(projectsDir);
                }
            } finally {
                if(rfd.getData(RunFileData.ManageFile).isEmpty()){this.ap.clearManageFile();}
//                this.ap.setManageFile(manName);
                
                LoadingContext.exit();
            }

            winCliMode();

        } catch (IOException e) {
            //System.err.println("oIaP: projectsDir " + e);
        }
    }

    @Override
    public void saveItem_actionPerformed(java.awt.event.ActionEvent event) {
        this.saveWeps();
    }
    
    public void saveWeps() {
//        sp.setSoilSlope(sp.c_soilSlopeValue.getValue());
//        sp.setRockFragments(sp.c_soilRockFragmentsValue.getValue());
        rfd.writeRunDataXML(projectDirectory);
        dataChanged = false;
    }

    @Override
    public void saveAsItem_actionPerformed(java.awt.event.ActionEvent event) {
        String [] dirandFile = findDirectoryAndFile(projectDirectory);
        TFile tf = Util.incrementFileName(new TFile(dirandFile[0] ,dirandFile[1] ), null, ".wpj");
        WepsFileChooser2 wpc = new WepsFileChooser2(WepsFileTypes2.Project, dirandFile[0],
                WepsFileChooser2.Action.Save);
        //set the tooltip of "home" button to "Home" instead of "Desktop"
        wpc.homeToolTip(wpc);
        
        wpc.setDefaultDirectory(new TFile(projectsPath));
        wpc.setCurrentDirectory(dirandFile[0]);
        wpc.setPersistSelectedFile(true);
        wpc.setSelectedFile(tf);
        // Required because we are persiting the file name.
        wpc.setText(tf.getName());
        wpc.setApproveButtonText(WepsFileChooser2.ApproveText.SAVE_AS);
        
        wpc.setDialogTitle("Save Project As");
        wpc.enableDbButton (false);
        if (wpc.showDialog(this) == TFileChooser.APPROVE_OPTION) {
            // work with the picked item
            JOptionPane.showMessageDialog(this, wpc.getSelectedFile().getAbsolutePath(),
                    "WEPS Project to create", JOptionPane.PLAIN_MESSAGE);
        } else {
            return;
        }
        try {
            makeProject(wpc.getSelectedFile().getCanonicalPath(), true, false, true);
            g_runlocation.setText(cd.getData(DefaultRunsLocation));
            rfd.setData(RunFileData.RunsLocation, cd.getData(DefaultRunsLocation));
            rfd.writeRunDataXML(projectDirectory);
            dataChanged = false;
        } catch (IOException e) {
            //System.err.println("W-sAIaP: projectsDir " + e);
        }

    }
    

    @Override
    protected void openDatabasesItem_actionPerformed(java.awt.event.ActionEvent evt) {
        try {
            Desktop.getDesktop().open(About.getWepsDatabases());
        } catch (IOException e) {
            String path = About.getWepsDatabases().getAbsolutePath();
            logger.warn("Unable to open: " + path, e);
            JOptionPane.showMessageDialog(this, "Unable to open weps databases.", "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    @Override
    protected void resetProjectItem_ActionPerformed(java.awt.event.ActionEvent evt) {
        //We want to create an option pane that will display yes and no, and 
        //we want the default option to be no.
        int response = JOptionPane.showOptionDialog(this, "Reset current settings and delete files?\n"
                + "Run settings will return to defaults.\nManagement and soil files will be deleted.",
                "Reset", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[]{"Yes", "No"}, "No");
        if (JOptionPane.YES_OPTION == response) {
            //clear the project
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            try {
                rfd.setRunLocationRestore(false);
                rfd.initialize();
                
                
                rfd.fireAll();
                saveItem_actionPerformed(null);
                //delete all the non run files
                TFile dir = new TFile(projectDirectory);
                for (TFile file : dir.listFiles()) {
                    deleteNonRuns(file);
                }
                
                //this creates new "weps.ini" if not there
                TFile runDatas = new TFile(projectDirectory, RunFileData.WepsData);
                if (!runDatas.exists()) {
                    saveWeps();
                }
                changes.firePropertyChange(ConfigData.CurrentProj, null, projectDirectory);
                
                dataChanged = true;
            } finally {
                setCursor(Cursor.getDefaultCursor());
            }

        } else {
        }
        saveItem_actionPerformed(null);
//        saveProjectDialog(null);
    }
    
    
    @Override
    protected void resetProjectItem1_ActionPerformed(java.awt.event.ActionEvent evt) {
        //We want to create an option pane that will display yes and no, and 
        //we want the default option to be no.
        int response = JOptionPane.showOptionDialog(this, "Reset current GUI to defaults?\n"
                ,
                "Reset", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[]{"Yes", "No"}, "No");
        if (JOptionPane.YES_OPTION == response) {
            //clear the project
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            try {
                rfd.setRunLocationRestore(true);
                rfd.setGuiRestore(true);
//                rfd.initialize();
                
                saveItem_actionPerformed(null);
                rfd.fireAll();
                if(rfd.getData(RunFileData.ManageFile).isEmpty()){ this.ap.clearManageFile();}
                //delete all the non run files
//                TFile dir = new TFile(projectDirectory);
//                for (TFile file : dir.listFiles()) {
//                    deleteNonRuns(file);
//                }
//                
                //this creates new "weps.ini" if not there
//                TFile runDatas = new TFile(projectDirectory, RunFileData.WepsData);
//                if (!runDatas.exists()) {
//                    saveWeps();
//                }
//                changes.firePropertyChange(ConfigData.CurrentProj, null, projectDirectory);
                
                dataChanged = true;
            } finally {
                setCursor(Cursor.getDefaultCursor());
            }

        } else {
        }
        
    }

    private void deleteNonRuns(TFile file) {
        if (file.getName().toLowerCase().endsWith(RunFileData.RunSuffix)) {
            //is a run, exit
            return;
        }

        if (file.isDirectory()) {
            //try to delete all the children first
            for (TFile child : file.listFiles()) {
                deleteNonRuns(child);
            }
        }

        if (!file.isDirectory() || file.listFiles().length == 0) {
            //only delete if we no longer have any children left.
            try {
                file.rm();
            } catch (IOException e) {
                logger.debug("Unable to delete file: \"" + file.getAbsolutePath()
                        + "\".  Delete will be scheduled for application exit.");
                file.deleteOnExit();
            }
        }
    }
    
    
    /**
     * @param event 
     */
    @Override
    public void deleteProjectItem_actionPerformed(java.awt.event.ActionEvent event) {
                WepsFileChooser2 wfc = null;
        try {
            wfc = new WepsFileChooser2(WepsFileTypes2.Project, projectsPath,
            WepsFileChooser2.Action.Delete);
            //wfc.setMultiSelectionEnabled(true);
            wfc.homeToolTip(wfc);
            //remove the NewFolder button
            wfc.disableNewFolder(wfc);
            wfc.setDoubleClickSelect(true, ".wpj");
            wfc.setFileSelectionMode(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY);
            wfc.setDialogTitle("Delete Project");
            wfc.setApproveButtonText(WepsFileChooser2.ApproveText.DELETE_SELECTED_PROJECT);
            wfc.enableDbButton(false);
            wfc.setDefaultDirectory(new TFile(projectsPath));
            wfc.setCurrentDirectory(new TFile(projectsPathCheck(projectsPath)).getAbsolutePath());
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(this, "Internal error has occurred\nRestart and delete project",
                    "Error (W-004)",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (wfc.showDialog(this) == TFileChooser.APPROVE_OPTION) {
            if (wfc.getSelectedFile().getAbsolutePath().equals(projectDirectory)) {
                JOptionPane.showMessageDialog(this, "Project " + wfc.getSelectedFile().getName() + " is presently open."
                        + "\n Open some other project to delete this one.",
                        "alert", JOptionPane.WARNING_MESSAGE);
                return;
            }
            if (!wfc.getSelectedFile().exists()) {
                JOptionPane.showMessageDialog(this, "An error occured while trying to delete this project.\n" +
                        "It seems the project at the path:\n" + wfc.getSelectedFile().getAbsolutePath() +
                        "\ndoes not exist",
                        "alert", JOptionPane.WARNING_MESSAGE);
            }
            
            int res = JOptionPane.showConfirmDialog(this, "Delete " + wfc.getSelectedFile().getName(),
                        "Delete Project", JOptionPane.YES_NO_CANCEL_OPTION);
            
            if (res == JOptionPane.NO_OPTION || res == JOptionPane.CANCEL_OPTION) {
            } else if (res == JOptionPane.YES_OPTION) {
                rfd.removeRunData(new TFile(wfc.getSelectedFile()));
            }
        }
    }

    @Override
    public void deleteRunItem_actionPerformed(java.awt.event.ActionEvent event) {
        WepsFileChooser2 wfc = null;
        try {
            wfc = new WepsFileChooser2(WepsFileTypes2.RunDir, runsLocationPath, WepsFileChooser2.Action.Delete, true);
            
            wfc.setMultiSelectionEnabled(true);
            //set the tooltip of "home" button to "Home" instead of "Desktop"
            wfc.homeToolTip(wfc);
            //remove the NewFolder button
            wfc.disableNewFolder(wfc);
            
            wfc.setFileFilter(new WepsFileFilter("WEPS Run", WepsFileTypes2.Run) );
            wfc.setDefaultDirectory(new TFile(runsLocationPath));
            wfc.setCurrentDirectory(runsLocationPath);
            
            wfc.setDoubleClickSelect(true, "wjr");
            wfc.setTitleText("Delete Run");
            wfc.setFileFolderText(WepsFileChooser2.ApproveText.FOLDER);
            wfc.setPersistSelectedFile(true);
            wfc.setFileSelectionMode(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY);
            wfc.setApproveButtonText(WepsFileChooser2.ApproveText.DELETE_SELECTED_RUN);
            wfc.setDialogTitle("Delete Run");
            
            wfc.enableDbButton(false);
            wfc.enableCfgDefLocButton(false);
            
//            wfc.setCurrentDirectory(new TFile(projectsPathCheck(runsLocationPath)).getAbsolutePath());
            
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(this, "Internal error has occurred\nRestart and delete run",
                    "Error (W-005)", JOptionPane.ERROR_MESSAGE);

            logger.fatal("Internal error has occurred\nRestart and delete run", e);
            return;
        }
        if (wfc.showDialog(this) == TFileChooser.APPROVE_OPTION) {
            int res = -1;
            java.io.File[] sf = wfc.getSelectedFiles();
            int numFiles = sf.length;
            if (numFiles == 1) {

                res = JOptionPane.showConfirmDialog(this, "Delete " + wfc.getSelectedFile().getName(),
                        "Delete Run", JOptionPane.YES_NO_CANCEL_OPTION);
            } else {

                StringBuilder sb = new StringBuilder(sf[0].getName());
                for (int j = 1; j < numFiles; j++) {
                    sb.append("\n");
                    sb.append(sf[j].getName());
                }
                JTextArea jt = new JTextArea(sb.toString());
                jt.setEditable(false);
                JScrollPane sp = new JScrollPane(jt, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
                sp.setPreferredSize(new Dimension(500, 100));
                res = JOptionPane.showConfirmDialog(this, sp, "Delete Runs", JOptionPane.YES_NO_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE);

            }

            switch (res) {
                case JOptionPane.CANCEL_OPTION:
                    return;
                case JOptionPane.YES_OPTION:
                    deleteRun(sf);
                    break;
                case JOptionPane.NO_OPTION:
                    break;
            }
        }
    }

    public void deleteRun(java.io.File... files) {

        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        List<TFile> lockedFiles = new LinkedList<>();
        for (java.io.File file : files) {
            if (file.getName().equals(lastRun)) {
                changes.firePropertyChange(RunFileData.LastRun, lastRun, "");
            }

            boolean deleted = Util.deleteAll(new TFile(file), lockedFiles);
            if (!deleted) {
                JOptionPane.showMessageDialog(this, "Files failed to delete.",
                        "Deletion Fail", JOptionPane.INFORMATION_MESSAGE);
            }
        }

        if (!lockedFiles.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (TFile notDeleted : lockedFiles) {
                sb.append(notDeleted.getAbsolutePath());
                sb.append("\n");
            }

            JTextArea jt = new JTextArea(sb.toString());
            jt.setEditable(false);
            JScrollPane sp = new JScrollPane(jt, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                    JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            sp.setPreferredSize(new Dimension(500, 100));

            //JOptionPane.showMessageDialog(this, "Unable to Delete Run:\n" + file.getPath() +
            //"\nThe following files may be read only or open in another application.");
            JOptionPane.showMessageDialog(this, sp, "Locked Files", JOptionPane.ERROR_MESSAGE);
        }

        setCursor(Cursor.getDefaultCursor());

    }

    @Override
    protected void exportRunItem_actionPerformed(java.awt.event.ActionEvent evt) {
        TFile source = new TFile(runsLocationPath);        
        RunExporter export = new RunExporter(source, null, false, this);
    }

    @Override
    public void deleteMgmtItem_actionPerformed(java.awt.event.ActionEvent evt) {
        WepsFileChooser2 wfc = null;
        try {
            wfc = new WepsFileChooser2(WepsFileTypes2.ManagementWeps, projectDirectory,
                    WepsFileChooser2.Action.Delete, true);

            wfc.setMultiSelectionEnabled(true);
            //set the tooltip of "home" button to "Home" instead of "Desktop"
            wfc.homeToolTip(wfc);
            //remove the NewFolder button
            wfc.disableNewFolder(wfc);
            wfc.setFileFilter(WepsFileTypes2.ManagementWeps.getFileFilter());
            wfc.setApproveButtonText(WepsFileChooser2.ApproveText.DELETE);
            wfc.setDialogTitle("Delete Management File");
            wfc.setFileSelectionMode(WepsFileChooser2.SelectionType.FILES_AND_DIRECTORIES);
            wfc.enableCfgDefLocButton(false);
            wfc.enableDbButton(false);
            wfc.setDefaultDirectory(new TFile(projectDirectory));
            wfc.setCurrentDirectory(projectDirectory);
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(this, "Internal error has occurred\nRestart and delete Management File",
                    "Error (W-006)",
                    JOptionPane.ERROR_MESSAGE);
            //System.err.println("W_dMI_aP: " + e);
            return;
        }

        //System.out.println("Current Management File is:"+manFileName);
        if (wfc.showDialog(this) == TFileChooser.APPROVE_OPTION) {
            int res = -1;
            java.io.File[] sf = wfc.getSelectedFiles();
            int numFiles = sf.length;
            if (numFiles == 1) {
                if (wfc.getSelectedFile().getAbsolutePath().equals(manFileName)) {
                    JOptionPane.showMessageDialog(this, "Management Rotation File " + sf[0].getName()
                            + " is currently being used for this project."
                            + "\n Open some other project to delete this one.",
                            "alert", JOptionPane.WARNING_MESSAGE);
                    return;
                }

                res = JOptionPane.showConfirmDialog(this, "Delete " + wfc.getSelectedFile().getName(),
                        "Delete Management Rotation File", JOptionPane.YES_NO_CANCEL_OPTION);
            } else {
                //System.out.println("The selected files is"+wfc.getSelectedFile().getName());
                StringBuilder sb = new StringBuilder(sf[0].getName());
                for (int j = 1; j < numFiles; j++) {
                    sb.append("\n");
                    sb.append(sf[j].getName());
                }
                JTextArea jt = new JTextArea(sb.toString());
                jt.setEditable(false);
                JScrollPane sp = new JScrollPane(jt, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
                sp.setPreferredSize(new Dimension(500, 100));
                res = JOptionPane.showConfirmDialog(this, sp, "Delete Management Files",
                        JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);

            }

            switch (res) {
                case JOptionPane.CANCEL_OPTION:
                    return;
                case JOptionPane.YES_OPTION:
                    for (int i = 0; i < numFiles; i++) {
                        Util.deleteAll(new TFile(sf[i]));
                    }
                    break;
                case JOptionPane.NO_OPTION:
                    break;
            }
        } else {
            //System.out.println("W_oKaP: not approved");
        }

    }

    @Override
    public void deleteSoilItem_actionPerformed(java.awt.event.ActionEvent evt) {
        // TO DO: code goes here:
        WepsFileChooser2 wfc = null;
        try {
            wfc = new WepsFileChooser2(WepsFileTypes2.Soil, projectDirectory,
                    WepsFileChooser2.Action.Delete,true);

            wfc.setMultiSelectionEnabled(true);

            //set the tooltip of "home" button to "Home" instead of "Desktop"
            wfc.homeToolTip(wfc);
            //remove the NewFolder button
            wfc.disableNewFolder(wfc);
            wfc.setApproveButtonText(WepsFileChooser2.ApproveText.DELETE);
            wfc.setDialogTitle("Delete Soil File");
            wfc.enableCfgDefLocButton(false);
            wfc.setFileSelectionMode(WepsFileChooser2.SelectionType.FILES_AND_DIRECTORIES);
            wfc.setCurrentDirectory(projectDirectory);
            wfc.setFileFilter(WepsFileTypes2.Soil.getFileFilter());
            wfc.enableDbButton(false);
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(this, "Internal error has occurred\nRestart and delete Soil File",
                    "Error (W-006)",
                    JOptionPane.ERROR_MESSAGE);
            //System.err.println("W_dMI_aP: " + e);
            return;
        }

        //System.out.println("Current Soil File is:"+soilFileName);
        if (wfc.showDialog(this) == TFileChooser.APPROVE_OPTION) {
            int res = -1;
            java.io.File[] sf = wfc.getSelectedFiles();
            int numFiles = sf.length;
            if (numFiles == 1) {
                if (wfc.getSelectedFile().getAbsolutePath().equals(soilFileName)) {
                    JOptionPane.showMessageDialog(this, "IFC Soil File " + sf[0].getName()
                            + " is currently being used for this project."
                            + "\n Open some other project to delete this one.",
                            "alert", JOptionPane.WARNING_MESSAGE);
                    return;
                }

                res = JOptionPane.showConfirmDialog(this, "Delete " + wfc.getSelectedFile().getName(),
                        "Delete IFC Soil File", JOptionPane.YES_NO_CANCEL_OPTION);
            } else {
                StringBuilder sb = new StringBuilder(sf[0].getName());
                for (int j = 1; j < numFiles; j++) {
                    sb.append("\n");
                    sb.append(sf[j].getName());
                }
                JTextArea jt = new JTextArea(sb.toString());
                jt.setEditable(false);
                JScrollPane sp = new JScrollPane(jt, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
                sp.setPreferredSize(new Dimension(500, 100));
                res = JOptionPane.showConfirmDialog(this, sp, "Delete Soil Files",
                        JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
            }

            switch (res) {
                case JOptionPane.CANCEL_OPTION:
                    return;
                case JOptionPane.YES_OPTION:
                    for (int i = 0; i < numFiles; i++) {
                        Util.deleteAll(new TFile(sf[i]));
                    }
                    break;
                case JOptionPane.NO_OPTION:
                    break;
            }
        }

    }

    @Override
    public void exitItem_actionPerformed(java.awt.event.ActionEvent event) {
        exitApplication();
    }

    @Override
    public void refreshAuxDropdowns() {
        ap.refreshMan();
        ap.refreshSoil();
    }
    
    @Override
    protected void MI_log_actionPerformed(java.awt.event.ActionEvent evt) {
        new LogViewer().setVisible(true);
    }
    
    /**
     * This instance of WEPS' about instance if instantiated.
     */
    private AboutDialog ABOUT_INSTANCE;

    @Override
    public void MI_aboutItem_actionPerformed(java.awt.event.ActionEvent event) {
        /* This method opens up the about menu. Should only ever have one instance. */
        try {
            // JAboutDialog Create with owner and show as modal
            if (ABOUT_INSTANCE != null) { 
                if (!ABOUT_INSTANCE.isVisible()) {
                    // if user closes the window, we want to update information.
                    // just in case the user wanted it refreshed.
                    ABOUT_INSTANCE.dispose();
                    ABOUT_INSTANCE = new AboutDialog(this, usda.weru.util.Application.WEPS);
                    ABOUT_INSTANCE.setVisible(true);
                    ABOUT_INSTANCE.setModal(false);
                } 
                ABOUT_INSTANCE.toFront();
            }
            else {
                ABOUT_INSTANCE = new AboutDialog(this, usda.weru.util.Application.WEPS);
                ABOUT_INSTANCE.setModal(false);
                ABOUT_INSTANCE.setVisible(true);
            }
        } catch (Exception e) { System.err.println("[ERROR]: About instance failed to open.");}
    }

    //added by Neha
    @Override
    public void MI_aboutButton_actionPerformed(java.awt.event.ActionEvent event) {
        //we do nothing here-but this button is added in the action listener in addHelp()
    }

    @Override
    protected void MI_welcomWizard_actionPerformed(java.awt.event.ActionEvent evt) {
        WelcomeWizard wizard = new WelcomeWizard(true);
        wizard.show();
    }

    /**
     * outputCurrentSummary is called by methods in line 2390 - 2427.
    
        This method takes the name of the Report and attempts to find the last run project path
        and if that path exists will generate the report, otherwise it will inform the user
        that there is either no current or previous run available.
     * @param reportName - name of the report as taken from ReportManager string.
     */
    public void outputCurrentSummary(String reportName) {
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available", 
                    "Error (W-005)", JOptionPane.WARNING_MESSAGE);
        }
        
        TFile lastRunPath = new TFile(lastRun);
        if(lastRunPath.exists()) {
            lastRun = !lastRunPath.isAbsolute() ? 
                    new TFile(projectDirectory, lastRun).getAbsolutePath() : lastRun;

            ReportManager.getDefault().displayReport(lastRun, reportName);
        } else {
            JOptionPane.showMessageDialog(this, "No current or previous run available. Last known path is:\n" + lastRun + " ",
                    "No " + reportName + " available.", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    
    @Override
    public void MICurrentProjectSummary_actionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_RUN);
    }
    
    @Override
    public void MICurrentManagementSummary_actionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_MANAGEMENT);
    }

    @Override
    public void MICurrentYieldSummary_actionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_CROPSUM);
    }

    @Override
    public void MICurrentCCSummary_ActionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_COVERCROPSUM);
    }

    @Override
    public void MICurrentCISummary_ActionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_CROP_INT_SUM);
    }
    
    @Override
    public void MICurrentSTIRSummary_actionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_STIR);
    }
    
    @Override
    public void MICurrentOutput_actionPerformed(java.awt.event.ActionEvent event) {
        outputCurrentSummary(ReportManager.REPORT_DETAIL);
    }
    
        @Override
    protected void MI_currentConfidenceInterval_actionPerformed(ActionEvent evt) {
        outputCurrentSummary(ReportManager.REPORT_CONFIDENCE_INTERVAL);
    }

    @Override
    public void MICurrentCropDet_actionPerformed(java.awt.event.ActionEvent event) {
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
                    "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (!(new TFile(lastRun).isAbsolute())) {
            lastRun = (new TFile(projectDirectory, lastRun)).getAbsolutePath();
        }
        ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_CROPDET);
    }

    @Override
    public void MICurrentCCDetActionPerformed(java.awt.event.ActionEvent event) {
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
                    "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (!(new TFile(lastRun).isAbsolute())) {
            lastRun = (new TFile(projectDirectory, lastRun)).getAbsolutePath();
        }
        ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_COVERCROPDET);
    }

    @Override
    public void MI_CurrentCIDetActionPerformed(java.awt.event.ActionEvent event) {
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
                    "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (!(new TFile(lastRun).isAbsolute())) {
            lastRun = (new TFile(projectDirectory, lastRun)).getAbsolutePath();
        }
        ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_CROP_INT_DET);
    }

    @Override
    public void MI_CurrentCIPerDetActionPerformed(java.awt.event.ActionEvent event) {
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
                    "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (!(new TFile(lastRun).isAbsolute())) {
            lastRun = (new TFile(projectDirectory, lastRun)).getAbsolutePath();
        }
        ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_CROP_INT_PER_DET);
    }

    // variable to keep track of most recent quickplot.
    private int most_recent_quickplot = 0;
    
    /*
    Helper method for dynamic quickplot action preformed
    searches through the quickplot menu list created for
    the matching event, and gets the subsequent index for the
    filter set to be used in generating a quickplot
    */
    private int getCurrentQuickplot(java.awt.event.ActionEvent event) {
        // Any errors will generate the default quickplot at 0
        int index = 0;
        for (int i = 0; i < c_instance.MI_QuickPlot_MostRecentRun.getItemCount(); i++) {
            if (event.getActionCommand().equals(c_instance.MI_QuickPlot_MostRecentRun.getItem(i).getText())) {
                index = i;
                break;
            }
        }
        most_recent_quickplot = index;
        return index;
    }
    
    /*
    This method handles the event of clicking on View Output -> Previous Run -> Quickplots
    and the selection of menu item. New quickplots can be configured in:
    weps.install/tables/quickplot_configurations/ (specific filterset file here)
    */
    private void dynamic_quickplot_actionPreformedSelectRun(java.awt.event.ActionEvent event) {
        int index = getCurrentQuickplot(event); // get index of filter set
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_QUICKPLOT, index);
    }
    
    /*
    This method handles the event of clicking on View Output -> Most Recent Run -> Quickplots
    and the selection of menu item. New quickplots can be configured in:
    weps.install/tables/quickplot_configurations/ (specific filterset file here)
    */
    private void dynamic_quickplot_actionPreformed(java.awt.event.ActionEvent event) {
        int index = getCurrentQuickplot(event); // get events filterset index 
        
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
            "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }
        // get the absolute path
        if (!(new TFile(lastRun).isAbsolute())) {
            lastRun = (new TFile(projectDirectory, lastRun)).getAbsolutePath();
        }
        ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_QUICKPLOT, index);
        
    }    
    
    private void display_most_recent_quickplot(java.awt.event.ActionEvent event) {
        int index = most_recent_quickplot;
        
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
            "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }

        TFile lastRunPath = new TFile(lastRun);
        if(lastRunPath.exists()) {
            lastRun = !lastRunPath.isAbsolute() ? 
                    new TFile(projectDirectory, lastRun).getAbsolutePath() : lastRun;

            ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_QUICKPLOT, index);
        } else {
            JOptionPane.showMessageDialog(this, "No current or previous run available. Last known path is:\n" + lastRun + " ",
                    "No " + ReportManager.REPORT_QUICKPLOT + " available.", JOptionPane.INFORMATION_MESSAGE);
        }        
    }
    
    // Just links to most recent quickplot generated.
    @Override
    protected void JB_MostRecentQuickPlot_ActionPerformed(java.awt.event.ActionEvent evt) {
        display_most_recent_quickplot(evt);
    }
    
    /**
     * Opens the Run Manager
     */
    @Override
    protected void MI_runmanger_actionPerformed(java.awt.event.ActionEvent evt) {
        Wmrm wmrm = new Wmrm(this);
        wmrm.setVisible(true);
        wmrm.init();
        
    }

    @Override
    public void MICurrentRawOutput_actionPerformed(java.awt.event.ActionEvent event) {
        if (lastRun.length() == 0) {
            JOptionPane.showMessageDialog(this, "No current run available",
                    "Error (W-005)", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (!(new TFile(lastRun).isAbsolute())) {
            lastRun = (new TFile(projectDirectory, lastRun)).getAbsolutePath();
        }
        ReportManager.getDefault().displayReport(lastRun, ReportManager.REPORT_DEBUG);
    }

    @Override
    protected void MI_otherConfidenceInterval_actionPerformed(ActionEvent evt) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_CONFIDENCE_INTERVAL);
    }

    @Override
    protected void JBIRActionPerformed(java.awt.event.ActionEvent evt) {
        MI_currentConfidenceInterval_actionPerformed(evt);
    }

// Output reports - other run
    @Override
    public void MIOtherYieldSummary_actionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_CROPSUM);
    }

    @Override
    public void MIOtherCropDet_ActionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_CROPDET);
    }

    @Override
    public void MIOtherCCSummary_ActionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_COVERCROPSUM);
    }

    @Override
    public void MIOtherCISummary_ActionPerformed(java.awt.event.ActionEvent event) {
        //For Alex to Finish implementing
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_CROP_INT_SUM);
    }

    @Override
    public void MI_OtherCCDetActionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_COVERCROPDET);
    }

    @Override
    public void MI_OtherCIDetActionPerformed(java.awt.event.ActionEvent event) {
        //For Alex to Finish implementing
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_CROP_INT_DET);
    }

    public void MI_OtherCIPerDetActionPerformed(java.awt.event.ActionEvent event) {
        //For Alex to Finish implementing
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_CROP_INT_PER_DET);
    }

    @Override
    public void MIOtherManagementSummary_actionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_MANAGEMENT);
    }

    @Override
    public void MIOtherSTIREnergyReport_ActionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_STIR);
    }

    @Override
    public void MIOtherSummary_actionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_RUN);
    }

    @Override
    public void MIOtherOutput_actionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_DETAIL);
    }

    @Override
    public void MIOtherRawOutput_actionPerformed(java.awt.event.ActionEvent event) {
        ReportManager.getDefault().displayReport(projectDirectory, runsLocationPath, ReportManager.REPORT_DEBUG);
    }


    public void QuickPlotsShortcut_actionPerformed(java.awt.event.ActionEvent event) {
    }
    

// Run Menu
    @Override
    public void MIMakeRun_actionPerformed(java.awt.event.ActionEvent event) {
        //System.out.println("run button pressed");
        //static function set in simulation panel if dates are unordered 
        //new run can not happen
        //System.out.println(getDatesUnordered());
        if (getDatesUnordered()) {
            JOptionPane.showMessageDialog(null, "Please Adjust Start Date and End Date."
                    + "\nStart Date must be set before End Date, unable to make Run.",
                    "Date Selection Error.", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        WrcSimulationControl wrc = getNewWrcSimulationControl(this, rfd, cd, false);
        wrc.execute();
        
        //set the title of the window to the new run - neha
        setTitle(new TFile(projectDirectory).getName());
        
        //reset weps.ini
        sp.setSoilSlope(sp.getOriginalSlope(),false);
        
    }

    @Override
    public void MIMakeCalibrationRun_actionPerformed(java.awt.event.ActionEvent event) {
        //System.out.println("cal button pressed");
        //static function set in simulation panel if dates are unordered 
        //new cal run can not happen
        //System.out.println(getDatesUnordered());
        if (getDatesUnordered()) {
            JOptionPane.showMessageDialog(null, "Please Adjust Start Date and End Date."
                    + "\nStart Date must be set before End Date, unable to make Calibration Run.",
                    "Date Selection Error.", JOptionPane.WARNING_MESSAGE);
            return;
        }
        //System.out.println("MI_mCR_aP : I am in MIMakeCalibrationRun BEFORE action performed");
        WrcSimulationControl wrcCalib = getNewWrcSimulationControl (this, rfd, cd, true);
        //System.out.println("MI_mCR_aP : I am in MIMakeCalibrationRun AFTER action performed");
        wrcCalib.execute();
    }

    @Override
    public void MIRestoreRun_actionPerformed(java.awt.event.ActionEvent event) {
        WepsFileChooser2 wpc = new WepsFileChooser2(WepsFileTypes2.Run, projectDirectory, WepsFileChooser2.Action.Select);
        String path = runsLocationPath;
        if (path == null || path.length() <= 0) {
            path = defaultRunsLocationPath;
        }
        TFile currentDirectory = new TFile(path);
        if (!currentDirectory.exists()) {
            JOptionPane.showMessageDialog(this, "Runs location not found:\n" + currentDirectory.getPath(),
                    "Path Warning", JOptionPane.WARNING_MESSAGE);
            currentDirectory = new TFile(ConfigData.getDefault().getDataParsed(ConfigData.CurrentProj));
        }
        wpc.setCurrentDirectory(currentDirectory.getAbsolutePath());
        //set the tooltip of "home" button to "Home" instead of "Desktop"
        wpc.homeToolTip(wpc);
        //remove the NewFolder button
        wpc.disableNewFolder(wpc);
        wpc.setDialogTitle("Restore Run");
        wpc.setFileSelectionMode(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY);
        wpc.setDoubleClickSelect(true, ".wjr");
        wpc.setApproveButtonText(WepsFileChooser2.ApproveText.OPEN_SELECTED_RUN);
        wpc.setFileFolderText(WepsFileChooser2.ApproveText.FOLDER);
        wpc.enableDbButton(false);
        wpc.setDefaultDirectory(currentDirectory);
        wpc.setFileFilter(WepsFileTypes2.Run.getFileFilter());
        int retVal = wpc.showDialog(this);
        if (retVal == TFileChooser.APPROVE_OPTION) {
            // Added debug lines as it is not always identifying the path the same way on each invocation of the FileChooser with the same double mouse click selection - LEW
            System.out.println("wpc.getSelectedFile().getParent(): " + wpc.getSelectedFile().getParent());
            System.out.println("wpc.getSelectedFile(): " + wpc.getSelectedFile());
            
            if(wpc.getSelectedFile().getParent().endsWith(".wjr") && wpc.getSelectedFile().getAbsolutePath().endsWith(".wjr")){
                restoreRun(new TFile(wpc.getSelectedFile().getParent()));
            }else{
                restoreRun(new TFile(wpc.getSelectedFile()));
            }
            // Added the "getParent()" to eliminate the duplication of the last (selected) ".wjr" subfolder
            // Still need to resolve the actual cause of this duplication though. - LEW
//            restoreRun(new TFile(wpc.getSelectedFile().getParent()));
    

            // Causes an exception since we have not "Approved" this, but "Cancelled" it.
        //} else {
        //    restoreRun(new TFile(wpc.getSelectedFile()));
        }
    }
    
    public void restoreRun(TFile runFile) {
        isRestored = true;
        RestoringContext.enter();
        try {
            logger.debug("Restore Run: " + runFile.getPath());
            //Is MCREW open?
            if (MCREWWindow.isOpen()) {
                logger.debug("MCREW is open.  Canceling restore.");
                JOptionPane.showMessageDialog(this, "Unable to restore run.\nPlease close MCREW.",
                        "WEPS", JOptionPane.WARNING_MESSAGE);
                return;
            }

            //Is soil open?
            if (usda.weru.soil.Soil.isOpen()) {
                logger.debug("Soil editor is open.  Canceling restore.");
                JOptionPane.showMessageDialog(this, "Unable to restore run.\nPlease close the soil editor.",
                        "WEPS", JOptionPane.WARNING_MESSAGE);
                return;
            }

            //Has warnings?        
            if (reviewWarnings) {
                TFile warningsFile = new TFile(runFile, RunFileData.WarningsFile);
                if (warningsFile != null && warningsFile.isFile() && warningsFile.length() > 0) {
                    logger.debug("Warnings file exists for run.");
                    int result = JOptionPane.showConfirmDialog(this, "The run you are restoring generated warnings.\n"
                            + "Would you like to review the warnings?", "WEPS",
                            JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
                    switch (result) {
                        case JOptionPane.YES_OPTION:
                            BufferedReader in = null;
                            try {
                                String temp;
                                StringBuilder sb = new StringBuilder();
                                in = new BufferedReader(new TFileReader(warningsFile));
                                while ((temp = in.readLine()) != null) {
                                    sb.append(temp.trim() + "\n");

                                }
                                WepsMessageDialog.showScrollableMessage(this, "Review Generated Warnings",
                                        sb.toString(), projectDirectory, JOptionPane.WARNING_MESSAGE,
                                        WepsMessageDialog.OK_OPTION);

                            } catch (IOException e) {
                                logger.warn("Unable to read warnings file. " + warningsFile.getPath());
                            } finally {
                                try {
                                    in.close();
                                } catch (IOException e) {
                                    logger.error("Unable to close stream. " + warningsFile.getPath(), e);
                                }
                            }

                            break;
                        case JOptionPane.NO_OPTION:
                            break;
                        case JOptionPane.CANCEL_OPTION:
                            return;
                    }
                } else {
                    logger.debug("No warnings to review for run.");
                }
            }
            try {
                setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                System.out.println("running...");
                System.out.println(runFile.getCanonicalPath());
                rfd.readRunFile(runFile.getCanonicalPath(), false, true);

                ap.refreshSoil();
                ap.refreshMan();

                changes.firePropertyChange(RunFileData.LastRun, null, runFile.getAbsolutePath());
                changes.firePropertyChange(RunFileData.LastRunAttempt, null, runFile.getAbsolutePath());

                setTitle(new TFile(projectDirectory).getName());
                changes.firePropertyChange(WEPS_RUNRESTORED, null, runFile.getCanonicalPath());
            } catch (IOException e) {
                logger.error("Unknown error while restoring run.", e);
                JOptionPane.showMessageDialog(this, "Unable to restore run.", "Unexpected Error", JOptionPane.ERROR_MESSAGE);
            }
        } finally {
            RestoringContext.exit();
            setCursor(getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
    }
    private String windGenStation = null;
    private String windGenCmdArgs = null;

    @Override
    public void MIWindStation_actionPerformed(java.awt.event.ActionEvent event) {
        Station station = getRunFileData().getBean().getWindgenStation();
        String data = ConfigData.getDefault().getDataParsed(ConfigData.WinData);

        new WindGenStationDisplay(data, station);
    }

    /**
     * Sending of emails from within the application interface happens via this
     * method as it allows the user to pull the EMAIL dialog made available and
     * perform the activitites useful for application related feedback like
     * runtime exception, a bad RUN file or PROJECT directory related issues
     * that might need the support team to address few issues that did arise
     * during the program execution.
     *
     * @param event The mouse click or keyboard enter action event that triggers
     * this method.
     */
    @Override
    public void MISendEmail_actionPerformed(java.awt.event.ActionEvent event) {
        try {
            // Sometimes, the email window appears behind Weps.
            // Iconify Weps so that the emailer is left visible to the user.
            this.setExtendedState(ICONIFIED);
            
            URI uri = new URI(String.format("mailto:%s?subject=%s",
                    ConfigData.getDefault().getData(ConfigData.CommentAddr),
                    URLEncoder.encode("WEPS Comments/Questions", "UTF-8")));

            Desktop.getDesktop().mail(uri);
        } catch (IOException | URISyntaxException e) {
            this.setExtendedState(NORMAL);
            logger.error("Unable to open email", e);
            JOptionPane.showMessageDialog(this, "Unable to open user's default email program.",
                    "Email failed", JOptionPane.WARNING_MESSAGE);
        }
    }

    @Override
    public void MIHelpTopics_actionPerformed(java.awt.event.ActionEvent event) {
    }

    private ConfigPanel c_configPanel;

    @Override
    public void MIEditConfig_actionPerformed(java.awt.event.ActionEvent event) {
        synchronized (this) {
            if (c_configPanel != null) {
                int state = c_configPanel.getExtendedState();
                //remove any iconified bits
                state &= ~JFrame.ICONIFIED;
                c_configPanel.setExtendedState(state);
                //bring it to the front
                c_configPanel.toFront();
                c_configPanel.setVisible(true);
                return;
            }
        }
        try {
            c_configPanel = new ConfigPanel(this);
            c_configPanel.addWindowListener(new WindowAdapter() {

                @Override
                public void windowClosed(WindowEvent e) {
                    synchronized (Weps.this) {
                        c_configPanel = null;
                    }
                }

            });
            c_configPanel.setVisible(true);

        } catch (java.lang.Exception e) {
        }
    }

    @Override
    public void windowGainedFocus_actionPerformed(java.awt.event.WindowEvent evt) {
        //System.out.println("WEPS:WINDOW GAINED FOCUS entered");
        this.invalidate();
        this.repaint();
    }
    /*-----------------------------------------------------------------
     *
     * The following methods are called when the respective tool bar button
     * is pressed.  Weps_n makes buttons call the respective menu item as a
     * default action.  All the buttons here started out calling their
     * super so that their definitions can be here but they do the "right"
     * thing.  These items can be overridden at will.
     */

    private PropertyChangeSupport changes = new PropertyChangeSupport(this);

    /**
     * Allows the container to add or register some other components to
     * recognize the changes that occur on this component.
     *
     * @param l The listener that listens and reacts towards the the changes to
     * be reflected
     */
    @Override
    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    /**
     * Allows the container to remove or de-register some other components and
     * stop recognizing the changes that occur on this component.
     *
     * @param l The listener that does not listen and react towards the the
     * changes to be reflected.
     */
    @Override
    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
    private boolean dataChanged = false;
    private boolean fireallFlg = false;
    private String projectDirectory = "";
    private String projectsPath = "";
    private String defaultProjectsPath = "";
    private String newRunsDefaultLocation = "";
    private String lastRun = "";
    private String selectFieldLocTxt = "";

    public String runsLocationPath = "";

    public String defaultRunsLocationPath = "";
    private String measurementUnits = "";
    private String manFileName = "";
    private String soilFileName = "";

    private void setRunLocationText(String text) {
        g_runlocation.setText(text);
    }

    /**
     * We want to pick up the management file, soil file and last project IN
     * THAT ORDER.If any of those are uninitialized, an null will take it's
     * place.
     * @return String array with null if the file doesn't exist 
     */
    public String[] getExceptionPackage() {
        String[] returnCase = new String[3];
        if (manFileName.equals("")) {
            returnCase[0] = null;
        } else {
            returnCase[0] = manFileName;
        }
        if (soilFileName.equals("")) {
            returnCase[1] = null;
        } else {
            returnCase[1] = soilFileName;
        }
        if (lastRun.equals("")) {
            returnCase[2] = null;
        } else {
            returnCase[2] = lastRun;
        }
        return returnCase;
    }

    public TFile getRunsLocation() {
        if (runsLocationPath != null && !runsLocationPath.equals("")) {
            return new TFile(runsLocationPath);
        } else {
            String path = ConfigData.getDefault().getDataParsed(ConfigData.DefaultRunsLocation != null ? 
                    ConfigData.DefaultRunsLocation : ConfigData.DefaultRunsLocationTemplate);
            if (path != null) {
                return new TFile(path);
            }
        }
        return null;
    }

    /**
     * Recognizes and takes appropriate actions on registered properties from
     * different screens to update and synchronize data and GUI screens as
     * needed
     *
     * @param e The event itself that is responsible for triggering the change
     * required for registered properties/components.
     */
    @Override
    public void propertyChange(PropertyChangeEvent e) {
        //System.out.println("in property change)");
        if (e.getPropertyName().startsWith(ConfigData.REP)) {
            getButton(e.getPropertyName()).setVisible(cd.getReportVisibility(e.getPropertyName()));
        } else {
            switch (e.getPropertyName()) {
                case ConfigData.SingleProjectMode:
                    if (e.getNewValue().equals("1")) {
                        System.err.println("WEPS, setting single project mode");
                        M_project.setText("File");
                        M_project.remove(newItem);
                        M_project.remove(openItem);
                        M_project.remove(saveAsItem);
                        M_project.remove(deleteProjectItem);
                        c_singleProjectMode = true;
                        newButton.setVisible(false);
                        openButton.setVisible(false);

                    }
                    break;
                case RunFileData.DataChanged:
                    String val = (String) e.getNewValue();
                    if (val.equals("fireall")) {
                        fireallFlg = !fireallFlg;
                    }
                    if (fireallFlg) {
                        return;
                    }
                    dataChanged = val.equals(RunFileData.DataChanged);
                    break;
                case ConfigData.CurrentProj:
                    projectDirectory = e.getNewValue().toString();
                    projectDirectory = Util.parse(projectDirectory);
                    if (runsLocationPath.equals("")) {
                        setRunLocationText(ConfigData.getDefault().getData(ConfigData.DefaultRunsLocation));
                    } else {
                        setRunLocationText(new TFile(runsLocationPath).getAbsolutePath());
                    }
                    updateTitle();
                    break;
                case RunFileData.RunTypeDisp:
                    //                if (e.getNewValue().equals(ConfigData.NRCS)) {
                    MI_currentStirEnergyReport.setVisible(true);
                    MI_otherStirEnergyReport.setVisible(true);
                    //                } else {
                    //                    MI_currentStirEnergyReport.setVisible(false);
                    //                    MI_otherStirEnergyReport.setVisible(false);
                    //                }
                    break;
                case RunFileData.LastRun:
                    lastRun = ((String) e.getNewValue());
                    updateTitle();
                    break;
                case ConfigData.ProjDir:
                    projectsPath = ((String) e.getNewValue());
                    projectsPath = Util.parse(projectsPath);
//                    projectsPath = projectsPathCheck(projectsPath);
                    break;
                case ConfigData.DefaultProjName:
                   defaultProjectsPath = ((String) e.getNewValue());
                   defaultProjectsPath = Util.parse(defaultProjectsPath);
                    break;
                case ConfigData.NewProjectDefaultRunsLocation:
                    /// config panel -> Project Data & Loc -> New Prj. Default Runs Location
                    newRunsDefaultLocation = ((String) e.getNewValue());
                    newRunsDefaultLocation = Util.parse(newRunsDefaultLocation);
                    break;
                case ConfigData.Units:
                    measurementUnits = ((String) e.getNewValue());
                    break;
                case RunFileData.ClimateFile:
                    cliGenFile = ((String) e.getNewValue());
                    break;
                case RunFileData.WindFile:
                    winGenFile = ((String) e.getNewValue());
                    break;
                case RunFileData.SelectFieldLocTxt:
                    selectFieldLocTxt =((String) e.getNewValue());
                    break;
//                case ConfigData.MantisPassword:
//                    mantisPassword = e.getNewValue().toString();
//                    break;
//                case ConfigData.MantisUser:
//                    mantisUser = e.getNewValue().toString();
//                    break;
//                case ConfigData.MantisURL:
//                    mantisURL = e.getNewValue().toString();
//                    break;
//                case ConfigData.MantisEmail:
//                    mantisEmail = e.getNewValue().toString();
//                    break;
//                case ConfigData.MantisProject:
//                    mantisProject = e.getNewValue().toString();
//                    break;
//                case ConfigData.MantisMaxSize:
//                    mantisMaxSize = e.getNewValue().toString();
//                    break;
//                case ConfigData.AddDirectoryButton:
//                    addDirectoryButton = e.getNewValue().toString();
//                    break;
                case ConfigData.TTInit:
                    setTTTime((String) e.getNewValue(), 1);
                    break;
                case ConfigData.TTDismiss:
                    setTTTime((String) e.getNewValue(), 2);
                    break;
                case RunFileData.WinGenStation:
                    windGenStation = ((String) e.getNewValue());
                    break;
                case ConfigData.WinCmd:
                    windGenCmdArgs = ((String) e.getNewValue());
                    break;
                case RunFileData.ManageFile:
                    setManageFileName(e);
                    break;
                case RunFileData.SoilFile:
                    setSoilFile(e);
                    break;
                case RunFileData.RunsLocation:
                    if (e.getNewValue() == null || e.getNewValue().toString().equals("NULL")) {
                        runsLocationPath = ConfigData.getDefault().getData(ConfigData.DefaultRunsLocation);
                    } else {
                        runsLocationPath = e.getNewValue().toString();
                        // update the config data so other parts of the program can see it
                        ConfigData.getDefault().setData(ConfigData.DefaultRunsLocation, runsLocationPath);
           
                    }
                    setRunLocationText(runsLocationPath);
                    break;
                case ConfigData.DefaultRunsLocation:
                    defaultRunsLocationPath = e.getNewValue().toString();
                    break;
                case ConfigData.DoNotReviewWarningsWhenRestoringRun:
                    reviewWarnings = e.getNewValue().toString().equals("0");
                    break;
                case Weps.WEPS_RUNCREATED:
                    changes.firePropertyChange(e);
                    break;
                case ConfigData.DoNotWarnAboutSystemLocale:
                    String value = e.getNewValue().toString();
                    warnAboutLocale = !value.equals("1");
                    break;
                case ConfigData.DoNotEstimateMissingSurgoValues:
                    if (e.getNewValue().equals("0")) {
                        NASIS.setEstimateNullValues(true);
                    } else {
                        NASIS.setEstimateNullValues(false);
                    }
                    break;
                case ConfigData.OMFractionThreshold:
                    try {
                        NASIS.setOmFractionThreshold(Double.parseDouble(e.getNewValue().toString()));
                    } catch (NumberFormatException ex) {
                    }
                    break;
                case ConfigData.ReportsConfidenceIntervalEnabled:
                    MI_currentConfidenceInterval.setVisible(ConfigData.getDefault().isReportConfidenceIntervalEnabled());
                    MI_otherConfidenceInterval.setVisible(ConfigData.getDefault().isReportConfidenceIntervalEnabled());
                    JB_IR.setVisible(ConfigData.getDefault().isReportConfidenceIntervalEnabled());
                    break;
                case ConfigData.ReportsCropIntPerDetEnabled:
                    MI_CurrentCIPDet.setVisible(ConfigData.getDefault().isReportCropIntPerDetEnabled());
                    MI_otherCIPDet.setVisible(ConfigData.getDefault().isReportCropIntPerDetEnabled());
                    break;
            }
        }
    }

    /**
     * Listens for properties and actions from different applications in weps.
     */
    private void setSoilFile(PropertyChangeEvent e) {
        soilFileName = (String) e.getNewValue();
        TFile sf = new TFile(soilFileName);
        if (!sf.exists()) {
            if (soilFileName.equals("")) {
                return;
            }
            soilFileName = "";
            changes.firePropertyChange(RunFileData.SoilFile, null, "");
            return;
        }

        //Make sure the file is in the project        
        logger.debug("soil file: " + sf);
        TFile pd = new TFile(projectDirectory);
        try {
            //always copy soil from run dir to proj dir in a file restore
            String fromFile = sf.getCanonicalPath();
            String toFile = new TFile(pd, sf.getName()).getCanonicalPath();
            if (Util.isReadOnly(toFile) && (!toFile.equals(fromFile))) {
                int response = JOptionPane.showConfirmDialog(null, 
                        "You are attempting to write over the read-only soil file \"" + sf.getName() + "\" in the project directory. Proceed with this overwrite?",
                        "proceed?",
                        JOptionPane.YES_NO_OPTION);
                if (response == 0) {
                    //yes means 0
                    File makeDestWritable = new File(toFile);
                    makeDestWritable.setWritable(true);
                    Util.copyFile(fromFile, toFile);
                }
            } else {
                Util.copyFile(fromFile, toFile);
            }
            changes.firePropertyChange(RunFileData.SoilFile, fromFile, toFile);

        } catch (java.io.IOException ioe) {
            logger.error("Unable to copy soil file.", ioe);
        }
    }

    private void setManageFileName(PropertyChangeEvent e) {
        //Set the name of the current Management File as manFileName
        //If it doesnt exist, then make the string empty
        manFileName = (String) e.getNewValue();
        //setManName((String)e.getNewValue());
        TFile mf = new TFile(manFileName);
        setManName(mf.getAbsolutePath());
        if (!mf.exists()) {
            manName = "";
            manFileName = "";
            changes.firePropertyChange(RunFileData.ManageFile, null, "");
        }
    }

    private boolean ttFlg = false;

    private void setTTTime(String val, int id) {

        switch (id) {
            case 1:
                try {
                    int initDelay = Integer.parseInt(val.trim());
                    ToolTipManager.sharedInstance().setInitialDelay(initDelay);
                    ttFlg = true;
                } catch (NumberFormatException e) {
                    //System.err.println("W_sTTT: error setting initial delay " + val);
                }
                break;
            case 2:
                try {
                    int disDelay = Integer.parseInt(val.trim());
                    ToolTipManager.sharedInstance().setDismissDelay(disDelay);
                    ttFlg = true;
                } catch (NumberFormatException e) {
                    //System.err.println("W_sTTT: error setting dismiss delay " + val);
                }
                break;
            case 3:
                if (ttFlg) {
                    return;
                }
                int tim = ToolTipManager.sharedInstance().getDismissDelay();
                String timStr = "" + tim;
                changes.firePropertyChange(ConfigData.TTDismiss, null, timStr);
                tim = ToolTipManager.sharedInstance().getInitialDelay();
                timStr = "" + tim;
                changes.firePropertyChange(ConfigData.TTInit, null, timStr);
                break;
        }
    }

    private void addHelp() {
        logger.debug("Adding help...");
        loadHelp();
        addCSH(Help.getHelpSet());

        hs = Help.getHelpSet();

        logger.debug("Creating help broker...");
        hb = hs.createHelpBroker();
        logger.debug("Finished adding help.");
    } //end of addhelp()

    private void loadHelp() {
        logger.debug("Loading help...");
        try {
            //Try to load the master help first.  If it can not be found we try a weps specific help.
            //We try to load directories first for development reasons.  This way we see changes without
            //updating the jar files.

            String masterJar = "jar/MasterHelp.jar";
            String masterDir = "help/MasterWeps.hs";

            String wepsJar = "jar/WepsHelp.jar";
            String wepsDir1 = "help/weps.hs";
            String wepsDir2 = "help/weps1/weps.hs";

            if (Help.loadJar(masterJar)) {
                logger.debug("Loaded " + masterJar);
            } else if (Help.loadDirectory(masterDir)) {
                logger.debug("Loaded " + masterDir);
            } else if (Help.loadJar(wepsJar)) {
                logger.debug("Loaded " + wepsJar);
            } else if (Help.loadDirectory(wepsDir1)) {
                logger.debug("Loaded " + wepsDir1);
            } else if (Help.loadDirectory(wepsDir2)) {
                logger.debug("Loaded " + wepsDir2);
            }
        } finally {
            logger.debug("Done loading help.");
        }
    }

    private void addCSH(HelpSet hs) {
        logger.debug("Adding context sensitive help...");
        hb = hs.createHelpBroker();
        hb.enableHelpKey(getRootPane(), "introduction_html", hs);
        hb.enableHelpOnButton(MI_helpTopics, "introduction_html", hs);
        hb.enableHelpOnButton(aboutButton, "introduction_html", hs);
        ActionListener helper = new CSH.DisplayHelpFromSource(hb);
        //System.out.println("I am in the WEPS addHelp()" + helper);
        MI_helpTopics.addActionListener(helper);
        aboutButton.addActionListener(helper);
        helpButton.addActionListener(new CSH.DisplayHelpAfterTracking(hs, "javax.help.Popup", null));
        CSH.setHelpIDString(newButton, "tbNew_html");
        CSH.setHelpIDString(openButton, "tbOpen_html");
        CSH.setHelpIDString(saveButton, "tbSave_html");
        CSH.setHelpIDString(runButton, "tbRunButton_html");
        CSH.setHelpIDString(runCalButton, "tbRunCal_html");
        CSH.setHelpIDString(loadrunButton, "tbLoadRun_html");
        CSH.setHelpIDString(emailButton, "tbEmail_html");
        CSH.setHelpIDString(mantisButton, "tbMantis_html");
        CSH.setHelpIDString(LaunchNrmvToolbar, "tbNRMV_html");
        CSH.setHelpIDString(aboutButton, "tbHelpButton_html");
        CSH.setHelpIDString(helpButton, "tbPopupHelp_html");
        CSH.setHelpIDString(JB_RR, "tbProjectSummary_html");
        CSH.setHelpIDString(JB_MR, "tbManagementSummary_html");
        CSH.setHelpIDString(JB_CR, "tbCropSummary_html");
        CSH.setHelpIDString(JB_CC, "tbCoverCrop_html");
        CSH.setHelpIDString(JB_CI, "tbCropInterval_html");
        CSH.setHelpIDString(JB_SR, "tbSTIREnergySummary_html");
        CSH.setHelpIDString(JB_DR, "tbDetailedSummary_html");
        CSH.setHelpIDString(JB_IR, "tbConfidenceInterval_html");
        CSH.setHelpIDString(MB_main, "menubarPanel_html");
        CSH.setHelpIDString(M_project, "mnuProject_html");
        CSH.setHelpIDString(MI_config, "mnuConfiguration_html");
        CSH.setHelpIDString(M_output, "mnuViewOutput_html");
        CSH.setHelpIDString(M_run, "mnuRun_html");
        CSH.setHelpIDString(M_tools, "mnuTools_html");
        CSH.setHelpIDString(M_help, "mnuHelp_html");
        CSH.setHelpIDString(g_runlocation, "runLocation_html");
        CSH.setHelpIDString(JB_setRunLocation, "runLocation_html");
        CSH.setHelpIDString(JP_not, "notesPanel_html");
        //for the tool bar of Weps screen
        CSH.setHelpIDString(JTB_main, "toolbarPanel_html");
        CSH.setHelpIDString(JTB_main, "toolbarPanel_html");
        //Backup panel help.
        CSH.setHelpIDString(JP_client, "clientPanel_html");
        CSH.setHelpIDString(JP_reg, "regPanel_html");
        CSH.setHelpIDString(JP_loc, "locationPanel_html");
        CSH.setHelpIDString(JP_bar, "barPanel_html");
        CSH.setHelpIDString(JP_aux, "MCREWSoilPanel_html");
        CSH.setHelpIDString(JP_not, "notesPanel_html");
        CSH.setHelpIDString(JP_sim, "simrunPanel_html");
        CSH.setHelpIDString(runLocationPanel, "runLocation_html");
        logger.debug("Done adding context sensitive help.");

    }//end of addCSH
    private String cliGenFile = "";
    private String winGenFile = "";

    private void winCliMode() {
        if (winGenFile.endsWith(RunFileData.DefaultWinGenName) || winGenFile.trim().length() == 0) {
            //changes.firePropertyChange(ConfigData.WindFlag, null, "0");
            //changes.firePropertyChange(RunFileData.WindFlag, null, "0");
            changes.firePropertyChange(RunFileData.WindFile, null, RunFileData.DefaultWinGenName);
        }
        if (cliGenFile.endsWith(RunFileData.DefaultCliGenName) || cliGenFile.trim().length() == 0) {
            //changes.firePropertyChange(ConfigData.ClimateFlag, null, "0");
            //changes.firePropertyChange(RunFileData.ClimateFlag, null, "0");
            changes.firePropertyChange(RunFileData.ClimateFile, null, RunFileData.DefaultCliGenName);
        }
    }

    private void loadCurrentProject(Weps wp) {
        new LoadCP(wp);
    }

    /**
     * 
     * @param path
     * @return (String) of the path of the current project loc if it is different 
     * than the path parameter.
     */
    private String projectsPathCheck(String path) {
        if(!path.equals((new File (Util.getProperty("project.directory"))).getParentFile().getPath())){
            return (new File (Util.getProperty("project.directory"))).getParentFile().getPath();
        }
        
        return path;
    }

    /**
     * This private class may be a bit confusing. It opens and sets * the
     * current project in the constructor. It then adds a shutdown * hook to
     * save the name of the current project when the app * exits. It does NOT
     * load any data.
     *
     */
    private class LoadCP extends Thread {

        private final TFile projFile;
        Weps wp;

        /**
         * Read the last project recorded in the "lastproject.txt" file in the
         * "cfg" directory. If the file "lastproject.txt" is not found then call
         * findLastProj method.
         */
        public LoadCP(Weps wp) {
            this.wp = wp;
            // The lastproj.txt is created in the present working Project Directory.
            projFile = new TFile(About.getUserWeps(), "lastproject.txt");
            if (!wp.c_singleProjectMode) {
                TFile projDir = new TFile(wp.projectsPath).getCanOrAbsFile();
                if (!projDir.exists() || !projDir.canWrite()) { // ask user to create project directory

                    this.createSelectProjDir();

                    return;
                }
            } else {
                TFile projDir = new TFile(wp.projectsPath).getCanOrAbsFile();
                System.out.println("Project Directory: " + projDir.getAbsolutePath());
            }
            checkForLastProj();
            checkForRunsLocation();
        }

        
        /**
         * Here we are finding the last project that has been modified in the
         * "projects" directory [which is got from the 'projectsPath'] We check
         * for the modification time of the "weps.ini" file in every project
         * directory[.wpj files] and after getting the last modified weps.ini
         * file we get its parent which is the Project[.wpj] directory and store
         * it in the variable "projectsDir". If there are no projects in the
         * "projects" directory, then call "createProj" method.
         */
        private void findLastProj() {
            TFile projDir = new TFile(projectsPath);
            if (!projDir.isDirectory()) {
                return;
            }
            java.io.File[] projNames;
            projNames = projDir.listFiles((java.io.File dir, String name1) -> name1.endsWith(".wpj"));
            if (projNames == null || projNames.length == 0) {
                this.createProject();
                return;
            }
            TFile lastProj = new TFile(projNames[0], "weps.ini");
            TFile tmp = null;
            for (java.io.File projName : projNames) {
                tmp = new TFile(projName, "weps.ini");
                if (tmp.lastModified() <= lastProj.lastModified()) {
                    continue;
                }
                lastProj = tmp;
            }
            
            String projectsDir = lastProj.getParentFile().getAbsolutePath();

            wp.changes.firePropertyChange(ConfigData.CurrentProj, null, projectsDir);
            wp.changes.firePropertyChange(RunFileData.LastRun, null, "");
            wp.rfd.readRunData(projectsDir);
            wp.winCliMode();
        }

        /**
         * Ask the user to create a Valid Project Directory and set this value
         * in the Configuration Panel also
         */
        private void createSelectProjDir() {
            int returnVal = -1;
            JFrame frame = new JFrame("New Default Project");
            frame.setAlwaysOnTop(true);
            frame.setLocationRelativeTo(null);
            
            if(!c_singleProjectMode) {
                returnVal = JOptionPane.showOptionDialog(
                        frame,
                        "WEPS cannot find the default project directory.\n"
                        + "\'Create\' a directory at this "
                        + "location:\n\n" + wp.projectsPath + "\n",
                        "Warning (W-303)",
                        JOptionPane.DEFAULT_OPTION,
                        JOptionPane.WARNING_MESSAGE,
                        null,
                        new String[]{"Create", "Exit"},
                        "Create");
                
                switch(returnVal) {
                    case 0:
                        this.clearLastProject();
                        this.createProjectDir();
                        this.createProject();
                        Runtime.getRuntime().addShutdownHook(this);
                        break;
                    case 1:
                        System.exit(0);
                        break;
                }
                
            } else {
                TFile f = new TFile(wp.projectsPath);
                f.mkdir();
                this.checkForLastProj();
                wp.changes.firePropertyChange(ConfigData.CurrentProj, null, wp.projectsPath);
                changes.firePropertyChange(RunFileData.RunsLocation, null, projectDirectory);
            }
        }

        /**
         * If the user selects an existing Projects DIRECTORY, this will be
         * called from createSelectProjDir() and we check for the Last project
         * in this directory
         */
        @SuppressWarnings("static")
        private void checkForLastProj() {
            if (c_singleProjectMode) {
                TFile dir = new TFile(projectDirectory);
                if (!(dir.exists())) {
                    try {
                        makeProject(projectDirectory, false, false, false);

                    } catch (IOException ex) {
                        logger.error("Unable to create project.", ex);
                    } finally {
                        wp.rfd.initialize();
                    }
                } else {
                    wp.rfd.readRunData(projectDirectory);
                    setTitle(dir.getName());
                    if (wp.rfd.getData(RunFileData.Radius) == null && wp.rfd.getData(RunFileData.YLength) == null) {
                        System.err.println("Weps.ini file is missing or corrupted.");
                        JOptionPane.showMessageDialog(null,
                                "WEPS either could not locate the \"weps.ini\" file in the current WEPS Project "
                                + "directory\n(" + wp.projectDirectory + ") or the \"weps.ini\" file was "
                                + "\ncorrupted. WEPS will build a new \"weps.ini\" file with initial "
                                + "default values. Thus, the \nlast saved state of the interface will "
                                + "not be presented to the user this time. The \n\"weps.ini\" file will "
                                + "again get updated when the user saves the current state of the \ninterface "
                                + "prior to exiting WEPS in the future.",
                                "Invalid weps.ini",
                                JOptionPane.WARNING_MESSAGE);
                        wp.rfd.initialize();
                    }
                }

            } else {
                if (!projFile.exists()) {
                    findLastProj();
                    Runtime.getRuntime().addShutdownHook(this);
                    return;
                }
                BufferedReader in = null;
                try {
                    /**
                     * Reading the "lastproj.txt" file. If the path mentioned in
                     * the file does not refer to an existing file, then show a
                     * warning message, find the last modified project by
                     * calling the findLastProj method and add a Runtime
                     * shutdown Hook.
                     */
                    in = new BufferedReader(new TFileReader(projFile));
                    String temp = in.readLine();
                    File lprojtxt_content = new File(temp);

                    //Get possibly new Project location path
                    String proj_path_new = Util.getProperty("project.path");

                    //Need to convert both to File objects so we can auto-convert to Path objects
                    //and use "isSameFile()" to see if the paths are equivalent
                    //Dealing with two path separators ("/" and "\") for Windows in comparison code
                    File tmpFile_new = new File(proj_path_new);
                    File lprojtxt_parent = new File(lprojtxt_content.getParent());
//**********************************************************************************************
                    //Check if last proj is same as project.path if not reset it.
//                    if (!Files.isSameFile(tmpFile_new.toPath(), lprojtxt_parent.toPath())) {
//                        String tmpDfltProj = Weps.this.cd.getData(ConfigData.DefaultProjName);
//                        File tmpDfltProj_File = new File(tmpDfltProj);
//
//                        Path new_DfltProj_pathName = Paths.get(proj_path_new, tmpDfltProj_File.getName());  //Here is what I want, but as a String
//                        this.clearLastProject();
//                        temp = new_DfltProj_pathName.toString();
//                        
//                    }
// *********** Commented out above as it seems to cause issue loading outside default location **********
                    //If not null, set Current Project to new Default Project in config file XML parameter (when eventually saved there)
                    if (temp != null) {
                        cd.setData(ConfigData.CurrentProj, temp);
                        cd.save();
                    }

                    //pull Current Project path/name from "local" config file (well from in-memory ConfigData object yet)
                    String curProj = Weps.this.cd.getData(ConfigData.CurrentProj);
                    if (curProj != null) {
                        TFile fil = new TFile(curProj);
                        if (fil.exists()) {
                            temp = curProj;
                        }
                    } else {
                        //pulls name from default project name
                        curProj = Weps.this.cd.getData(ConfigData.DefaultProjName);
                        TFile fil = new TFile(curProj);
                        if (fil.exists()) {
                            temp = curProj;
                        }
                    }
                    if (temp != null) {
                        TFile tmpFile = new TFile(temp);
                        if (!tmpFile.exists()) {
                            findLastProj();
                            Runtime.getRuntime().addShutdownHook(this);
                            return;
                        }
                        wp.rfd.readRunData(temp);
                        if (wp.rfd.getData(RunFileData.Radius) == null && wp.rfd.getData(RunFileData.YLength) == null) {
                            System.err.println("Weps.ini file is missing or corrupted.");
                            JOptionPane.showMessageDialog(null,
                                    "WEPS either could not locate the \"weps.ini\" file in the current WEPS Project "
                                    + "directory\n(" + wp.projectDirectory + ") or the \"weps.ini\" file was "
                                    + "\ncorrupted. WEPS will build a new \"weps.ini\" file with initial "
                                    + "default values. Thus, the \nlast saved state of the interface will "
                                    + "not be presented to the user this time. The \n\"weps.ini\" file will "
                                    + "again get updated when the user saves the current state of the \ninterface "
                                    + "prior to exiting WEPS in the future.",
                                    "Invalid weps.ini",
                                    JOptionPane.WARNING_MESSAGE);
                            wp.rfd.initialize();
                        }
                    }
                    in.close();
                } catch (IOException e) {
                } finally {
                    try {
                        if (in != null) {
                            in.close();
                        }
                    } catch (IOException e) {
                        logger.error("Error closing file stream", e);
                    }
                }
            }
            Runtime.getRuntime().addShutdownHook(this);
        }//end of checkForLastProj()

        private void checkForRunsLocation() {
            //only auto create for single project mode
            if (c_singleProjectMode) {
                runsLocationPath = runsLocationPath == null ? this.wp.cd.getData(
                        ConfigData.DefaultRunsLocation) : runsLocationPath.equals("") 
                        ? this.wp.cd.getData(ConfigData.DefaultRunsLocation) : 
                        runsLocationPath;
                TFile dir = new TFile(runsLocationPath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
            }
        }
        
        private void createProjectDir() {
            try {
                TFile newProjDir = new TFile(projectsPath);

                if(newProjDir.exists()) {
                    JOptionPane.showMessageDialog(wp, "Project directory already exists",
                            "Error (W-001)", JOptionPane.WARNING_MESSAGE);
                    throw new IOException("Project directory already exists");
                }

                if(!newProjDir.mkdir()) {
                    JOptionPane.showMessageDialog(wp, "Cannot create project directory",
                            "Error (t W-002)", JOptionPane.WARNING_MESSAGE);
                    throw new IOException("Cannot create project directory"); 
                }
                
            } catch(IOException e) {
                
            }
        }

        /**
         * Ask the user to create a new project or otherwise Exit.
         */
        private void createProject() {
            wp.newInitialProject();
            wp.createLocalDirectories();

            if (!(new TFile(projectDirectory)).exists()) {
                JOptionPane.showMessageDialog(wp, "No project specified\nWEPS will exit",
                        "Error (W-301)", JOptionPane.WARNING_MESSAGE);
                throw new RuntimeException("Error W-301");
            }
        }
        
        private void clearLastProject() {
            if (!wp.c_singleProjectMode) {
                Path path = Paths.get(projFile.getAbsolutePath());
                try {
                    Files.deleteIfExists(path);
                } catch(IOException io) {
                    System.err.println("Cannot delete file");
                }
            }
        }

        /**
         * This run method executes when the WEPS system exits.It writes into
         * the file "lastproject.txt" the name of the last project executed.
         */
        @Override
        public void run() {
            if (wp.c_singleProjectMode) {
                //don't save the last project if we're in single project mode
                return;
            }
            try {
                //Update the lastproj.txt file with the latest project path
                try (PrintWriter out = new PrintWriter(new BufferedWriter(new TFileWriter(projFile)))) {
                    out.println(wp.projectDirectory);
                }
            } catch (IOException e) {
                //System.err.println("LCP_r: " + e);
            }
        }
    }

    @Override
    protected void MIDiff_actionPerformed(java.awt.event.ActionEvent evt) {
        DifferFrame differ = new DifferFrame();
        cd.addPropertyChangeListener(differ);
        cd.fireAll(differ);
        differ.setVisible(true);
    }

    @Override
    protected void JB_DR_actionPerformed(java.awt.event.ActionEvent evt) {
        MICurrentOutput_actionPerformed(evt);
    }

    @Override
    protected void JB_CR_actionPerformed(java.awt.event.ActionEvent evt) {
        MICurrentYieldSummary_actionPerformed(evt);
    }

    @Override
    protected void JB_MR_actionPerformed(java.awt.event.ActionEvent evt) {
        MICurrentManagementSummary_actionPerformed(evt);
    }

    @Override
    protected void JB_RR_actionPerformed(java.awt.event.ActionEvent evt) {
        MICurrentProjectSummary_actionPerformed(evt);
    }

    @Override
    protected void JB_CC_ActionPerformed(java.awt.event.ActionEvent evt) {
        MICurrentCCSummary_ActionPerformed(evt);
    }

    @Override
    protected void JB_CI_ActionPerformed(java.awt.event.ActionEvent evt) {
        //For Alex to Finish implementing
        MICurrentCISummary_ActionPerformed(evt);
    }

    @Override
    protected void JB_SR_actionPerformed(java.awt.event.ActionEvent evt) {
        MICurrentSTIRSummary_actionPerformed(evt);
    }

    @Override
    protected void setRunLocation_actionPerformed(java.awt.event.ActionEvent evt) {
        String runsLocPathName =  cd.getData(ConfigData.DefaultRunsLocation);
        if(!runsLocationPath.isEmpty() && !(runsLocationPath.length()<1)){
            runsLocPathName = runsLocationPath;
        }
//        String runsLocPathName =  cd.getData(ConfigData.run);
        // sends in notice to remove the projects filter BETTER WAY TO DO THIS!!!
//        WepsFileChooser2 wfc = new WepsFileChooser2(WepsFileTypes2.RunDirLocNew, runsLocPathName, WepsFileChooser2.Action.Select,true);
        
//        WepsFileChooser2 wfc = new WepsFileChooser2();
//            wfc.createBasicFileChooser(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY, 
//                    new WepsFileFilter("WEPS Run Location", WepsFileTypes2.RunDirLoc), false, 
//                    "Set Run Location","Set Run Location2",  null);
//        if (runsLocPathName == null || runsLocPathName.length() == 0) {
//            wfc.setCurrentDirectory(projectDirectory);
//        }
    WepsFileChooser2 wfc = new WepsFileChooser2();
//    wfc = new WepsFileChooser2(WepsFileTypes2.RunDirNoFiles, runsLocPathName, WepsFileChooser2.Action.Open);
        wfc.enableRecCheckbox(false);
        
        wfc.createBasicFileChooser(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY, null
                , false, 
                "Select directory For new Run Location.","Select directory For new Run Location",  runsLocPathName);
        wfc.setAccessory(new ResetRunLocationPanel(cd, rfd, wfc));
        wfc.allowNewDir(true);
        wfc.enableDbButton (false);
        wfc.setDialogTitle("Set Run Location");
        wfc.setFileFolderText(WepsFileChooser2.ApproveText.FOLDER);
        wfc.setFileSelectionMode(WepsFileChooser2.SelectionType.DIRECTORIES_ONLY);
        wfc.setFileFilter(WepsFileTypes2.RunDirNoFiles.getFileFilter());
//        wfc.setFileFilter(new WepsFileFilter("WEPS Run Location", WepsFileTypes2.RunDirLoc) );
        wfc.setApproveButtonText(WepsFileChooser2.ApproveText.SELECT_RUN_LOC);
        wfc.setAllowDirectorySelection(true);
        wfc.setDefaultDirectory(new TFile(runsLocPathName));

        wfc.setCurrentDirectory(new TFile(runsLocPathName).getAbsolutePath());
//        wfc.setFileFilter(new WepsFileFilter("WEPS Run Location", WepsFileTypes2.RunDirLoc));
        if (wfc.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            if(wfc.getSelectedFile().isDirectory()){
                //"here is some potentially unneeded code review later (tempHold)
                String tempHold = ConfigData.getDefault().getData(ConfigData.DefaultRunsLocation);
                String temp = wfc.getSelectedFile().getAbsolutePath();
                rfd.setData(RunFileData.RunsLocation, temp);
//                changes.firePropertyChange(RunFileData.RunsLocation, null, temp);
                cd.setData(ConfigData.DefaultRunsLocation, temp);
                ConfigData.getDefault().setData(ConfigData.DefaultRunsLocation, tempHold);
            }
        }
    }

    @Override
    protected void JTF_mostRecentRun_mouseMoved(java.awt.event.MouseEvent evt) {
        String tip = "<HTML><b>Most Recent Run</b><br>" + lastRun + " <br></HTML>";
        String current = JTF_mostRecentRun.getToolTipText();
        if (current == null || current.equals(tip) == false) {
            JTF_mostRecentRun.setToolTipText(tip);
        }
    }

//    protected void JP_center_componentResized(java.awt.event.ComponentEvent evt) {
//        int x=JP_center.getSize().width / 2 - JP_main.getSize().width / 2;
//        int y=JP_center.getSize().height / 2 - JP_main.getSize().height / 2;
//        JP_main.setLocation(x, y);
//
//    }
    @Override
    protected void MI_userGuideActionPerformed(java.awt.event.ActionEvent evt) {
        TFile guidef = new TFile("readme/WEPSUserManual.pdf");
        try {
            java.awt.Desktop.getDesktop().open(guidef);
        } catch (IOException ex) {
            try {
                javax.swing.JOptionPane.showMessageDialog(this, guidef.getCanonicalPath() + " not found",
                        "WEPS User Manual not found", javax.swing.JOptionPane.ERROR_MESSAGE);
            } catch (HeadlessException | IOException he) {
            }
        }
    }

    @Override
    public void display_techDoc() {
        TFile techguidef = new TFile("readme/USDA Handbook 727 - WEPS Technical Documentation.pdf");
        // System.out.println("Tech Doc launch action2 performed");
        try {
            java.awt.Desktop.getDesktop().open(techguidef);
        } catch (IOException ex) {
            try {
                javax.swing.JOptionPane.showMessageDialog(this, techguidef.getCanonicalPath() + " not found",
                        "WEPS Technical Document (USDA Handbook 727) not found", javax.swing.JOptionPane.ERROR_MESSAGE);
            } catch (HeadlessException | IOException he) {
            }
        }
    }
    @Override
    public void display_WebStartUserDoc() {
        TFile techguidef = new TFile("readme/WEPS_User_Guide.pdf");
        // System.out.println("Tech Doc launch action2 performed");
        try {
            java.awt.Desktop.getDesktop().open(techguidef);
        } catch (IOException ex) {
            try {
                javax.swing.JOptionPane.showMessageDialog(this, techguidef.getCanonicalPath() + " not found",
                        "WEPS User Guide not found", javax.swing.JOptionPane.ERROR_MESSAGE);
            } catch (HeadlessException | IOException he) {
            }
        }
    }
//    String mantisURL;
//    String mantisUser;
//    String mantisPassword;
//    String mantisEmail;
//    String mantisProject;
//    //pass maxsize to mantis constructor
//    String mantisMaxSize;
//    public String addDirectoryButton;
    @Override
    protected void JMI_mantisActionPerformed(java.awt.event.ActionEvent evt) {
        usda.weru.util.Mantis man = new usda.weru.util.Mantis();
        man.setVisible(true);
    }
    
    @Override
    protected void JMI_cropsreport_actionPerformed(java.awt.event.ActionEvent evt) {
        cd.setData(ConfigData.CROP_DB, cd.getDataParsed(ConfigData.SystemCropDB));
        
        String cropPath = cd.getDataParsed(ConfigData.CROP_DB);
        
        WepsFileChooser2 wfc2 =
                new WepsFileChooser2(WepsFileTypes2.Crop, cropPath, WepsFileChooser2.Action.Select);
        
        wfc2.setCurrentDirectory(cropPath);
        wfc2.setCropChooser();
        wfc2.enableFolderButtons();
        
        if (wfc2.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            TFile selected = new TFile(wfc2.getSelectedFile());
            cd.setData(ConfigData.CROP_DB, selected.getAbsolutePath());
            cd.save();
            ReportManager.getDefault().displayReport(ReportManager.REPORT_DATABASE_CROPS);
        }
    }

    @Override
    protected void JMI_opsreport_actionPerformed(java.awt.event.ActionEvent evt) {
        cd.setData(ConfigData.OPERATION_DB, cd.getDataParsed(ConfigData.SystemOpDB));
        String operationPath = cd.getDataParsed(ConfigData.OPERATION_DB);
        WepsFileChooser2 wfc2 = 
                new WepsFileChooser2(WepsFileTypes2.Operation, operationPath, WepsFileChooser2.Action.Select);
        
        wfc2.setCurrentDirectory(operationPath);
        wfc2.setOperationChooser();
        wfc2.enableFolderButtons();
        
        if (wfc2.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            TFile selected = new TFile(wfc2.getSelectedFile());
            cd.setData(ConfigData.OPERATION_DB, selected.getAbsolutePath());
            cd.save();
            ReportManager.getDefault().displayReport(ReportManager.REPORT_DATABASE_OPERATIONS);

        }        
    }

    @Override
    protected void JMI_manreport_actionPerformed(java.awt.event.ActionEvent evt) {
        cd.setData(ConfigData.MANAGEMENT_DB, cd.getDataParsed(ConfigData.ManTemp));
        
        String managementPath = cd.getDataParsed(ConfigData.MANAGEMENT_DB);
        
        WepsFileChooser2 wfc2 =
                new WepsFileChooser2(WepsFileTypes2.Management, managementPath, WepsFileChooser2.Action.Select);
        
        wfc2.setCurrentDirectory(managementPath);
        wfc2.enableFolderButtons();
        
        if (wfc2.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            TFile selected = new TFile(wfc2.getSelectedFile());
            cd.setData(ConfigData.MANAGEMENT_DB, selected.getAbsolutePath());
            cd.save();
            ReportManager.getDefault().displayReport(ReportManager.REPORT_DATABASE_MANAGEMENTS);
        }
    }
        
    /**
     * Commented out to get rid of NRMV. code :GRONRMV12
     *
     * @Override protected void RunNRMV() { try { nrmv.nrmv.main(new String[]
     * {"DISPOSE_ON_CLOSE"}); /* try { System.out.println("NRMV launching");
     *
     * Runtime rt = Runtime.getRuntime();
     *
     * String[] cmd = {"java", "-jar", "jar/NRMV_Standalone.jar"}; //
     * NRMV_UPGM.jar requires Java 7 to run Process proc = rt.exec(cmd);
     *
     * InputStream stderr = proc.getErrorStream(); if (stderr.available() > 0) {
     * System.out.println("<ERROR>"); for (int i = 0; i < stderr.available();
     * i++) { System.out.println("" + stderr.read()); }
     * System.out.println("</ERROR>"); }
     *
     * } catch (IOException t) { t.printStackTrace(); }
     */
    /**
     * } catch (Exception ex) { Exceptions.printStackTrace(ex); } }
     */
    @Override
    protected void ClearNRMVFiles() {
        List<java.io.File> nrmvFolders = FindDirectoriesWithSameName("nrmvfiles", new java.io.File(runsLocationPath));
        nrmvFolders.stream().filter(f -> (!delete(f))).forEachOrdered(f -> {
            System.out.println("Error deleting directory: " + f.toString());
        });
    }

    private static List<java.io.File> FindDirectoriesWithSameName(String name, java.io.File root) {
        List<java.io.File> result = new ArrayList<>();

        for (java.io.File file : root.listFiles()) {
            if (file.isDirectory()) {
                if (file.getName().equals(name)) {
                    result.add(file);
                }
                result.addAll(FindDirectoriesWithSameName(name, file));
            }
        }
        return result;
    }

    /**
     * deletes a file or the contents of a directory returns true if successful
     */
    private static boolean delete(java.io.File file) {
        boolean success = true;
        if (file.isDirectory()) {

            //directory is empty, then delete it
            if (file.list().length == 0) {
                if (!file.delete()) {
                    success = false;
                }
                System.out.println("Directory deleted : " + file.getAbsolutePath());

            } else {

                for (java.io.File temp : file.listFiles()) {

                    //recursive delete
                    if (!delete(temp)) {
                        success = false;
                    }
                }

                //check the directory again, if empty then delete it
                if (file.list().length == 0) {
                    if (!file.delete()) {
                        success = false;
                    }
                    System.out.println("Directory deleted : " + file.getAbsolutePath());
                }
            }
        } else //if file, then delete it
        {
            if (!file.delete()) {
                success = false;
            } //System.out.println("\tFile deleted : " + file.getAbsolutePath());
        }
        return success;
    }

    @Override
    protected void createNrmvFiles(boolean summaries) {

        WepsFileChooser2 wpc = new WepsFileChooser2(WepsFileTypes2.Run, projectDirectory, WepsFileChooser2.Action.Select);
        String path = runsLocationPath;
        if (path == null || path.length() <= 0) {
            path = defaultRunsLocationPath;
        }
        java.io.File currentDirectory = new TFile(path);
        if (!currentDirectory.exists()) {
            JOptionPane.showMessageDialog(this, "Runs location not found:\n" + currentDirectory.getPath(),
                    "Path Warning", JOptionPane.WARNING_MESSAGE);
            currentDirectory = new java.io.File(ConfigData.getDefault().getDataParsed(ConfigData.CurrentProj));
        }
        wpc.setCurrentDirectory(currentDirectory.getAbsolutePath());
        // set the tooltip of "home" button to "Home" instead of "Desktop"
        wpc.homeToolTip(wpc);
        // remove the NewFolder button
        wpc.disableNewFolder(wpc);
        int retVal = wpc.showDialog(this);

        if (retVal == TFileChooser.APPROVE_OPTION) {
            ConvertAllToNrmv catn = new ConvertAllToNrmv(wpc.getSelectedFile().getName(), wpc.getSelectedFile().toString());
            catn.shouldDoAverages(summaries);
            catn.run();
        }
    }

    
    public void newCsipInputController () {
        csipStatic = new CsipInputControllerStatic();
    }

    
    public CsipInputControllerStatic getCsipInputController () {
        return csipStatic;
    }

    public void disableMcrewElements () {
        runButton.setEnabled(false);
        runCalButton.setEnabled(false);
        M_run.setEnabled(false);
    }

    
    public void enableMcrewElements () {
        runButton.setEnabled(true);
        runCalButton.setEnabled(true);
        M_run.setEnabled(true);
        
        // Sometimes get here before ap is initialized. Ignore.
        if (ap != null) {
            ap.enableMcrewElements();
        }
    }
    
    // For server execution of science code, if a local server is required.
    // (This is called from the config panel if a change occurs there).
    public void wsRunnerActivate (ConfigData newCd) {
         if (wsRunner != null) {
            wsRunner.setCdAndRunIfNeeded(newCd);
        }
    }
}
