package usda.weru.erosion;

import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileInputStream;
import de.schlichtherle.truezip.file.swing.TFileChooser;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Desktop;
import static java.awt.Frame.ICONIFIED;
import static java.awt.Frame.NORMAL;
import java.awt.HeadlessException;

import javax.swing.JOptionPane;

import java.beans.*;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.util.*;
import javax.swing.SwingWorker;
//import org.apache.log4j.Appender;
//import org.apache.log4j.BasicConfigurator;
//import org.apache.log4j.ConsoleAppender;
//import org.apache.log4j.FileAppender;
//import org.apache.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 
//import org.apache.log4j.PatternLayout;
//import org.apache.log4j.PropertyConfigurator;
//import org.apache.log4j.RollingFileAppender;
//import org.apache.log4j.spi.RootLogger;
import org.openide.util.Exceptions;
import usda.weru.erosion.barriereditor.FieldEditor;
import usda.weru.soil.SoilChooser;
import usda.weru.util.*;
import usda.weru.weps.Weps;
import usda.weru.weps.location.Site;


/**
 * this is the main java file when compiled for a SWEEP release
 * @author maxerdwien
 */
public class Erosion extends usda.weru.erosion.gui.Erosion_n implements PropertyChangeListener {

    private static final long serialVersionUID = 1L;

    private static final Logger logger = LogManager.getLogger(Erosion.class);
    private final String measurementUnits = Util.SIUnits;
    private final int curSubr = 0;
    private String workingDirectory = ".";
    private String exeFile = "tsterode.exe";
    private String exeCmd = "-i${filename} -Egrd";
    private final String thresholdCmd = "-i${filename} -Emit";
    private static String curFileName = "";
    private DataStore ds;
    private String dataChanged;
    private final String ssurgoFileName = "";
    private String soilDB = "";
    private String cfgFile = "cfg/sweep.cfg";
    private String userCfgFile = null;
    private String logConfig = "cfg/log.cfg";
    private String log = null;
    private ConfigData cd = null;
    private ConfigPanel cp = null;
    private String windDB = "";
    private String windIdx = "";
    private SoilChooser c_soilChooser;
    
    protected FieldEditor fer;
    protected FormValidator fv;
    private OutputDisplay OD_graph = null;
    
    private static boolean isSweepRun = false;
    
    private final PropertyChangeSupport changes;

    public Erosion() {
        super();
        isSweepRun = true;
        ds = null;
        changes = new PropertyChangeSupport(this);
    }

    /*
     * The arguments for main are:
     *  -exe: directory containing SWEEP exe
     *  -cmd: command string for SWEEP
     *  -wrk: working directory
     *  -cfg: weps configuration file name
     *  -fil: initial file to load
     */

    public static void main(String[] args) {

        if (About.getJavaSpecificationVersion() < 1.6) {
            JOptionPane.showMessageDialog(null, "WEPS requires the Java Runtime Environment 1.6  or higher.\n"
                    + "Please visit http://java.sun.com and upgrade to the latest version.", "Java Upgrade Required", JOptionPane.ERROR_MESSAGE);
            return;
        }

        Erosion ero = new Erosion();
        System.out.println("Master SWEEP version");
        // default to MSI
        Weps.isMSIbuild = true;
        Weps.isWebstart = false;

        String exeFile = null;
        for (int idx = 0; idx < args.length; idx++) {
            if (args[idx].trim().equals("-exe")) {
                exeFile = (new TFile(args[++idx])).getAbsolutePath();
            } else if (args[idx].trim().equals("-cmd")) {
                ero.exeCmd = args[++idx];
            } else if (args[idx].trim().equals("-wrk")) {
                ero.workingDirectory = args[++idx];
                ero.workingDirectory = Util.parse(ero.workingDirectory);
            } else if (args[idx].trim().equals("-cfg")) {
                ero.cfgFile = args[++idx];
            } else if (args[idx].trim().equals("-usercfg")) {
                ero.userCfgFile = args[++idx];
            } else if (args[idx].trim().equals("-fil")) {
                curFileName = args[++idx];
            } else if (args[idx].trim().equals("-logcfg")) {
                ero.logConfig = args[++idx];
            } else if (args[idx].trim().equals("-log")) {
                ero.log = args[++idx];
            } else if (args[idx].trim().equals("-wsBuildName")) {
                // This parm only exists in Webstart, so set accordingly
                Weps.isMSIbuild = false;
                Weps.isWebstart = true;
                About.setWsBuildName(args[++idx]);
            }
        }
        if (args.length == 11) {
            ero.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
            java.awt.Point pt = ero.getLocation();
            pt.x += 10;
            pt.y += 10;
            ero.setLocation(pt);
        }

        if (!"".equals(curFileName)) {
            TFile inpFil = new TFile(curFileName);
            if (!inpFil.isAbsolute()) {
                curFileName = new TFile(ero.workingDirectory, curFileName).getAbsolutePath();
            }
        }

        ero.cfgFile = Util.parse(ero.cfgFile);
        TFile mainConfigFile = new TFile(ero.cfgFile);

        if (!mainConfigFile.exists()) {
            System.out.println("Specified main config file not found.");
            return;
        }

        //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 (ero.userCfgFile == null) {
            ero.userCfgFile = About.getUserWeps().getAbsolutePath() + "/" + mainConfigFile.getName();
        }

        //if the log has not been set 
        if (ero.log == null) {
            ero.log = About.getUserWeps().getAbsolutePath() + "/log/" + mainConfigNameNoExt + ".log";
        }

        ero.userCfgFile = Util.parse(ero.userCfgFile);
        ero.logConfig = Util.parse(ero.logConfig);
        ero.log = Util.parse(ero.log);
        //setup log4j logging.       

        TFile logConfigFile = new TFile(ero.logConfig);

        TFile logFile = new TFile(ero.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);

        if (logConfigFile.exists()) {
// MEH log4j should not need for log4j 2.
//            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("SWEEP application starting.");
//
//                logger.info("Log Config: " + logConfigFile.getAbsolutePath());
//                logger.info("Log File: " + logFile.getAbsolutePath());
//
//            } catch (Exception ex) {
//                //error loading the cfg
//                configureDefaultLoggers(logFile, ex);
//            }
        } else {
            //the log cfg file does not exist
            configureDefaultLoggers(logFile, null);
        }

        ConfigData.getDefault().load(mainConfigFile, new TFile(ero.userCfgFile));
        deleteOldLogs();

        //Locale change.  We only support US
        Locale current = Locale.getDefault();
        boolean changedLocale = false;
        if (current.equals(Locale.US) == false) {
            //Change the locale to US
            Locale.setDefault(Locale.US);
            changedLocale = true;
            logger.warn("Changed locale to US.");
        }

        ero.cd = ConfigData.getDefault();
        ero.cd.setData(ConfigData.Units, Util.SIUnits);
        ero.cd.setData(ConfigData.SoilTestOrganic, "0");
        ero.cd.setData(ConfigData.SoilSkipOrganicSurfaceLayers, "0");
        if(exeFile != null) ero.cd.setData(ConfigData.SWEEPExe, exeFile);

        ero.JMI_ssurgo.setEnabled(false);
        ero.cp = new ConfigPanel(ero);
        ero.cp.addPropertyChangeListener(ero.cd);
        ero.cd.addPropertyChangeListener(ero.cp);

        ero.cd.addPropertyChangeListener(ero);
                        
        ero.init();

//        ero.cd.fireAll(ero, ero.cp);
        ero.cd.fireAll();
        ero.setTitle(usda.weru.util.Application.SWEEP.getDescription() + " "
                + new TFile(curFileName).getName());
        java.awt.EventQueue.invokeLater(new RunEco(ero));
        ero.requestFocusInWindow();
        ero.setAlwaysOnTop(true);
        ero.setAlwaysOnTop(false);
        ero.JB_graphSubdaily.setEnabled(false);
        ero.JB_graphTotal.setEnabled(false);
        ero.JMI_graph.setEnabled(false);
        ero.JMI_subdaily.setEnabled(false);
        ero.makeWorkingDirectory();
    }

    public static boolean isSweep() {
        return isSweepRun;
    }
    
    public static String getEroName() {
        return curFileName;
    }
    
    public void makeWorkingDirectory() {
        TFile workingD = new TFile(workingDirectory);
        //System.err.println("Working Directory: " + workingD.getAbsolutePath());
        if(!workingDirectory.equals(".") && !workingD.exists()) {
            System.out.println("WARNING: Working Directory doesn't exist. Making default working directory.");
            workingD.mkdirs();
        }
    }
    private static void configureDefaultLoggers(TFile logFile, Exception ex) {
// 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("SWEEP application starting.");
//
//            if (ex != null) {
//                logger.info("Using default logger configuration.");
//                logger.info("Log File: " + logFile.getAbsolutePath());
//            } else {
//                //logger.error("Error configuring loggers. Using default logger configuration.", null);
//                logger.error("Error configuring loggers. Using default logger configuration.");
//            }
//
//        } catch (Exception e) {
//            BasicConfigurator.configure();
//            logger.error("Default logger configuration failed.  Using basic configuration.", e);
//        }
    }

    private static void deleteOldLogs() {
// MEH log4j need to re-implement
//        //loggers are mow 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());
//
//            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 (Exception 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 = new Date();
//                        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);
//                            }
//                        } catch (Exception 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) {
//                            Exceptions.printStackTrace(ex);
//                    }
//                }
//            }
//        }
//    }
    }

    private static class RunEco implements Runnable {

        Erosion ero;

        RunEco(Erosion ero) {
            this.ero = ero;
        }

        @Override
        public void run() {
            ero.setVisible(true);
            if (!"".equals(curFileName)) {
                ero.ds.readTextFile(new TFile(curFileName));
            }
            String title = ero.getTitle();
            if (title.endsWith(" mod")) {
                title = title.substring(0, title.lastIndexOf(" mod"));
                ero.setTitle(title);
            }
        }
    }
    
    protected void init () {

//        this.addPropertyChangeListener(this);
//        cd.addPropertyChangeListener(this);

        ds = new DataStore();
        ds.addPropertyChangeListener(this);
        addPropertyChangeListener(ds);

//        usda.weru.erosion.barriereditor.DisplayField df =
//                new usda.weru.erosion.barriereditor.DisplayField();
//        df.JP_main.setVisible(true);
//        df.addPropertyChangeListener(ds);
//        ds.addPropertyChangeListener(df);
////        df.JP_drawField.setVisible(true);
//        df.getContentPane().remove(df.JP_main);
//        JP_barriers.add(df.JP_main);
        fer = new FieldEditor();
        fer.addPropertyChangeListener(ds);
        ds.addPropertyChangeListener(fer);
        JP_barriers.add(fer, BorderLayout.CENTER);

        Biomass bio = new Biomass();
        bio.addPropertyChangeListener(ds);
        ds.addPropertyChangeListener(bio);
        JP_biomass.add(bio.JP_biomass);

        SoilLayers lay = new SoilLayers();
        lay.addPropertyChangeListener(ds);
        ds.addPropertyChangeListener(lay);
        JP_layers.add(lay.JP_layers);

        SoilSurface srf = new SoilSurface();
        srf.addPropertyChangeListener(ds);
        ds.addPropertyChangeListener(srf);
        JP_surface.add(srf.JP_surface);

        Weather wea = new Weather();
        wea.addPropertyChangeListener(ds);
        ds.addPropertyChangeListener(wea);
        JP_weather.add(wea.JP_weather);

        try {
            fv = new FormValidator(Erosion.class.getResourceAsStream("SWEEPLimits.xml"));
            bio.setFormValidator(fv);
        } catch (IOException ioe) {
            LogManager.getLogger(Erosion.class).error("Unable to load limits file.", ioe);
            JOptionPane.showMessageDialog(null, "Unable to load parameter limits file.", "Error", JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
        wea.setFormValidator(fv);
        Util.loadToolTips(this, new TFile("cfg", "erosiontooltips.cfg"));

        // turn off access to plot pane
//		JTP_main.setEnabledAt(6, false);
        ds.init();
        JTP_main.setSelectedIndex(0);
        //df.JP_drawField.invalidate();
        //df.JP_drawField.repaint();
        fv.validateForm(this);
    }

    @Override
    protected void JMI_exitActionPerformed(java.awt.event.ActionEvent evt) {
        int result = JOptionPane.showConfirmDialog(this, "Are you sure you want to exit? \nAll unsaved work will be lost.",
                "Confirm Exit", JOptionPane.YES_NO_OPTION);
        if (result == JOptionPane.YES_OPTION) {
            setVisible(false);
            System.exit(0);
        }

    }

    private boolean checkSurface() {
        int rtnVal = ds.validate();
        if (rtnVal == 0) {
            return false;
        }
        javax.swing.JOptionPane.showMessageDialog(this, ds.validateMsgs[rtnVal], "Error saving file",
                javax.swing.JOptionPane.ERROR_MESSAGE);
        this.changes.firePropertyChange(DataStore.SetFocus, null, ds.validateFields[rtnVal]);
        return true;
    }

    @Override
    protected void JMI_saveActionPerformed(java.awt.event.ActionEvent evt) {

        if (curFileName.length() == 0) {
            JMI_saveAsActionPerformed(evt);
            return;
        }
        fer.commitEdits();
        this.changes.firePropertyChange(DataStore.Commit, null, "a");
        if (checkSurface()) {
            return;
        }
        ds.writeTextFile(new TFile(curFileName));
    }

    private static TFile lastOpenedDirectory;

    @Override
    protected void JMI_openActionPerformed(java.awt.event.ActionEvent evt) {
        TFileChooser chooser = new TFileChooser();
        if (lastOpenedDirectory != null) {
            chooser.setCurrentDirectory(lastOpenedDirectory);
        } else {
            chooser.setCurrentDirectory(new TFile(workingDirectory));
        }
        // Note: source for ErosionFileFilter can be found in FileChooserDemo,
        // under the demo/jfc directory in the JDK.
        ErosionFileFilter filter = new ErosionFileFilter();
        filter.addExtension("in");
        filter.setDescription("Erosion Input Files");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showOpenDialog(this);
        if (returnVal == TFileChooser.APPROVE_OPTION) {
            //cache the last opened directory
            lastOpenedDirectory = new TFile(chooser.getSelectedFile().getParentFile());

            JB_graphSubdaily.setEnabled(false);
            JB_graphTotal.setEnabled(false);
            JMI_graph.setEnabled(false);
            JMI_subdaily.setEnabled(false);
            ds.reset();
            curFileName = chooser.getSelectedFile().getAbsolutePath();
            TFile inpf = new TFile(chooser.getSelectedFile());
            ds.readTextFile(inpf);
            this.setTitle(usda.weru.util.Application.SWEEP.getDescription() + " " + chooser.getSelectedFile().getName());
            TFile datf = new TFile(inpf.getParent(), inpf.getName().replace(DataStore.InputExt, ".egrd"));
             if (datf.exists()) {
                new LoadGraphs(this, false);
            }

        }

    }

    @Override
    protected void JMI_saveAsActionPerformed(java.awt.event.ActionEvent evt) {
        TFileChooser chooser = new TFileChooser();
        chooser.setCurrentDirectory(new TFile(workingDirectory));
        ErosionFileFilter filter = new ErosionFileFilter();
        filter.addExtension("in");
        filter.setDescription("Erosion Input Files");
        chooser.setFileFilter(filter);
        chooser.setDialogTitle("SaveAs");
        TFile curFile = Util.incrementFileName(new TFile(curFileName));
        chooser.setSelectedFile(curFile);
        int returnVal = chooser.showSaveDialog(this);
        if (returnVal == TFileChooser.APPROVE_OPTION) {
            curFileName = chooser.getSelectedFile().getAbsolutePath();
            if (!curFileName.endsWith(DataStore.InputExt)) {
                curFileName += DataStore.InputExt;
            }           
            fer.commitEdits();
            this.changes.firePropertyChange(DataStore.Commit, null, "a");
            if (checkSurface()) {
                return;
            }
            ds.writeTextFile(new TFile(chooser.getSelectedFile()));
            this.setTitle(usda.weru.util.Application.SWEEP.getDescription() + " " + new TFile(curFileName).getName());
        }
    }

   @Override
    protected void JMI_newActionPerformed(java.awt.event.ActionEvent evt) {
        ds.reset();
        curFileName = "";
    }

    @Override
    protected void JMI_helpActionPerformed(java.awt.event.ActionEvent evt) {
    }

    @Override
    protected void JMI_soilActionPerformed(java.awt.event.ActionEvent evt) {
        TFileChooser chooser = new TFileChooser();
        chooser.setCurrentDirectory(new TFile(workingDirectory));
        // Note: source for ErosionFileFilter can be found in FileChooserDemo,
        // under the demo/jfc directory in the JDK.
        ErosionFileFilter filter = new ErosionFileFilter();
        filter.addExtension("ifc");
        filter.setDescription("Soil Input Files");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showOpenDialog(this);
        if (returnVal == TFileChooser.APPROVE_OPTION) {
            ds.readIFCFile(new TFile(chooser.getSelectedFile()), 0);
        }
    }

    protected boolean checkBarriers() {
        return fer.checkBarriers();
    }

    @Override
    protected void JMI_runActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_JMI_runActionPerformed
        if (!checkBarriers()) {
            JTP_main.setSelectedComponent(JP_barriers);
            return;
        }

        if (!fv.validateForm(this)) {
            if (JOptionPane.showConfirmDialog(this,
                    "Make the run with out of range values?\nOut of range values are highlighted in red",
                    "Fields out of range",
                    JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION) {
                return;
            }
        }

        if (dataChanged.equals("1")) {
            int ret = JOptionPane.showOptionDialog(this, "Save data file and run?", "Data changed",
                    JOptionPane.YES_NO_CANCEL_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    (javax.swing.Icon) null,
                    new String[]{"Save", "Save As", "Cancel"},
                    "Save");
            switch (ret) {
                case JOptionPane.YES_OPTION:       // save
                    JMI_saveActionPerformed(evt);
                    break;
                case JOptionPane.NO_OPTION:        // save as
                    JMI_saveAsActionPerformed(evt);
                    break;
                case JOptionPane.CANCEL_OPTION:    // cancel
                    return;
            }
        }

        //parse the command and replace any variables.
        Map<String, String> props = new HashMap<String, String>();
        props.put("filename", curFileName);
        props.put("FileName", curFileName);

        StringTokenizer st = new StringTokenizer(exeCmd);
        String[] command = new String[st.countTokens() + 1];
        command[0] = exeFile;
        int i = 1;
        while (st.hasMoreTokens()) {
            String token = st.nextToken();

            if (token.startsWith("-i")) {
                if (Util.isWindows()) {
                    token = "\"" + token + "\"";
                }
            } else {

            }
            command[i] = Util.parse(token, props);
            i++;
        }

        if (curFileName.endsWith(".in")) {
            String baseFileName = curFileName.substring(0, curFileName.lastIndexOf(".in"));
            String delFileName = baseFileName + ".emit";
            TFile delFile = new TFile(delFileName);
            if (delFile.exists()) {
                try {
                    delFile.rm();
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
            }
            }
            delFileName = baseFileName + ".egrd";
            delFile = new TFile(delFileName);
            if (delFile.exists()) {
                try {
                    delFile.rm();
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
            }
            }
            delFileName = baseFileName + ".sgrd";
            delFile = new TFile(delFileName);
            if (delFile.exists()) {
                try {
                    delFile.rm();
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
            }
        }
        }

        this.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
        
        TFile workD = new TFile(workingDirectory);
        if(!workD.exists())
        {
            workD.mkdirs();
        }
        
        RunProgram m_run = new RunProgram(this, command, workingDirectory);
        while (!m_run.isDone()) {
        }
        this.setCursor(java.awt.Cursor.getDefaultCursor());
//        if (!m_run.hasErrors()) {
//            JMI_graphActionPerformed(null);
//        }
        new LoadGraphs(this, true);
    }//GEN-LAST:event_JMI_runActionPerformed

    @Override
    protected void JB_runThresholdActionPerformed(java.awt.event.ActionEvent evt) {
        JMI_runThresholdActionPerformed(evt);
    }

    @Override
    protected void JMI_thresholdActionPerformed(java.awt.event.ActionEvent evt) {
        TFile runDir = null;
        try {
            runDir = new TFile(curFileName.substring(0, curFileName.lastIndexOf(DataStore.InputExt)));
        } catch (java.lang.IndexOutOfBoundsException ioobe) {
            javax.swing.JOptionPane.showMessageDialog(this, "Run output directory does not exist\n"
                    + "Make a new threshold run or open an existing one", "File not found",
                    javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        TFile inpf = new TFile(runDir, "winddisp.dat");
        if (!inpf.exists()) {
            javax.swing.JOptionPane.showMessageDialog(this, "File " + inpf.getName() + " not found\n"
                    + "Make a new threshold run or open an existing one", "File not found",
                    javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (runDir.isDirectory()) {
            double[] startErosion = null;
            double[][] probTable = null;
            double[][] windTimes = null;

            WindDisp wdp = new WindDisp();
            try {
//                File inpf = new File(runDir, "winddisp.dat");
                TFileInputStream fis = new TFileInputStream(inpf);
                ObjectInputStream ois = new ObjectInputStream(fis);
                startErosion = (double[]) ois.readObject();
                probTable = (double[][]) ois.readObject();
                windTimes = (double[][]) ois.readObject();
                String stationName = (String) ois.readObject();
                wdp.JL_stationName.setText(stationName);
                wdp.setTitle(wdp.getTitle() + " " + runDir.getName());
                ois.close();
            } catch (FileNotFoundException fnfe) {
                //System.err.println("TR_rAP: cannot open file " + fnfe);
                fnfe.printStackTrace();
                return;
            } catch (java.io.IOException fioe) {
                //System.err.println("TR_rAP: error writing file " + fioe);
                fioe.printStackTrace();
                return;
            } catch (ClassNotFoundException cnfe) {
                //System.err.println("TR_rAP: error writing file " + cnfe);
                cnfe.printStackTrace();
                return;
            }
            wdp.setCellData(startErosion, probTable, windTimes);
            wdp.setVisible(true);
            wdp.setVisible(true);
        }

    }

    @Override
    protected void JMI_runThresholdActionPerformed(java.awt.event.ActionEvent evt) {
        if (!checkBarriers()) {
            JTP_main.setSelectedComponent(JP_barriers);
            return;
        }
        if (dataChanged.equals("1")) {
            int ret = JOptionPane.showConfirmDialog(this, "Save data file and run?", "Data changed", JOptionPane.OK_CANCEL_OPTION);
            if (ret == JOptionPane.CANCEL_OPTION) {
                return;
            }
            if (ret == JOptionPane.YES_OPTION) {
                JMI_saveActionPerformed(evt);
            }
        }
        final String newCmd = exeFile + " " + thresholdCmd;
        final Erosion e = this;
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        @SuppressWarnings("rawtypes")
        SwingWorker<?, ?> worker = new SwingWorker() {

            @Override
            protected Object doInBackground() throws Exception {
                return Site.UNITED_STATES;
            }

            @Override
            protected void done() {
                e.setCursor(Cursor.getDefaultCursor());
                new ThresholdRun(curFileName, newCmd, workingDirectory, windIdx, windDB, e);
                disableThreshold();
            }

        };
        worker.execute();
    }

    public void disableThreshold() {
        JB_runThreshold.setEnabled(false);
        JMI_runThreshold.setEnabled(false);
    }
    
    public void enableThreshold() {
        JB_runThreshold.setEnabled(true);
        JMI_runThreshold.setEnabled(true);
    }
    
    @Override
    protected void JMI_graphActionPerformed(java.awt.event.ActionEvent evt) {
        OD_graph.setVisible(true);
    }
    private OutputDisplay OD_subdaily = null;

    @Override
    protected void JMI_subdailyActionPerformed(java.awt.event.ActionEvent evt) {
        OD_subdaily.setVisible(true);
    }

    @Override
    protected void JMI_outputTextActionPerformed(java.awt.event.ActionEvent evt) {
        new TextViewer(new TFile((new TFile(curFileName)).getParent(),
                (new TFile(curFileName)).getName().replace(DataStore.InputExt, ".egrd")));
    }

    @Override
    protected void JMI_inputTextActionPerformed(java.awt.event.ActionEvent evt) {
//            (new TextViewer(new File(curFileName))).setVisible(true);
        new TextViewer(new TFile(curFileName));
    }

    @Override
    protected void JMI_ssurgoActionPerformed(java.awt.event.ActionEvent evt) {
//        ErosionFileFilter filter = new ErosionFileFilter();
//        filter.addExtension("ifc");
//        filter.setDescription("Soil Input Files");
//        chooser.setFileFilter(filter);
//        int returnVal = chooser.showOpenDialog(this);
//        if (returnVal == TFileChooser.APPROVE_OPTION) {
//            ds.readIFCFile(new TFile(chooser.getSelectedFile()), 0);
//        }
        if (c_soilChooser == null) {
            c_soilChooser = new SoilChooser(this, new TFile(workingDirectory), new TFile(soilDB), changes);
            c_soilChooser.setUseTempFile(true);
            c_soilChooser.addPropertyChangeListener(this);
        }
        c_soilChooser.setSize(new java.awt.Dimension(500, 500));
        c_soilChooser.setVisible(true);
    }

    @Override
    protected void JMI_aboutActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            // JAboutDialog Create with owner and show as modal
            {
                AboutDialog JAboutDialog1 = new AboutDialog(this, usda.weru.util.Application.SWEEP);
                JAboutDialog1.setModal(true);
                JAboutDialog1.setVisible(true);
            }
        } catch (Exception e) {
        }

    }

    @Override
    protected void JMI_userGuideActionPerformed(java.awt.event.ActionEvent evt) {
        TFile guidef = new TFile("readme/SWEEPUserGuide.pdf");
        try {
            java.awt.Desktop.getDesktop().open(guidef);
        } catch (Exception ex) {
            try {
                javax.swing.JOptionPane.showMessageDialog(this, guidef.getCanonicalPath() + " not found",
                        "SWEEP User Guide not found", javax.swing.JOptionPane.ERROR_MESSAGE);
            } catch (HeadlessException he) {
                ex.printStackTrace();
            } catch (IOException ioe) {
                ex.printStackTrace();
            }
        }
    }

    @Override
    protected void JMI_emailActionPerformed(java.awt.event.ActionEvent evt) {
        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("Sweep Comments/Questions", "UTF-8")));

            Desktop.getDesktop().mail(uri);
        } catch (Exception 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
    protected void JMI_configActionPerformed(java.awt.event.ActionEvent evt) {
//		(new ConfigPanel()).setVisible(true);
        cp.setVisible(true);
    }

    @Override
    protected void JB_graphSubdailyActionPerformed(java.awt.event.ActionEvent evt) {
        this.JMI_subdaily.doClick();
    }

    @Override
    protected void JB_graphTotalActionPerformed(java.awt.event.ActionEvent evt) {
        this.JMI_graph.doClick();
    }

    @Override
    protected void JB_runActionPerformed(java.awt.event.ActionEvent evt) {
        this.JMI_run.doClick();
    }

    @Override
    protected void JB_saveActionPerformed(java.awt.event.ActionEvent evt) {
        this.JMI_save.doClick();
    }

    @Override
    protected void JB_newActionPerformed(java.awt.event.ActionEvent evt) {
        this.JMI_new.doClick();
    }

    /*    
     *  -exe: directory containing SWEEP exe
     *  -cmd: command string for SWEEP
     *  -wrk: working directory
     *  -cfg: weps configuration file name
     *  -fil: initial file to load
     */
    @Override
    protected void JMI_loadOldRunActionPerformed(java.awt.event.ActionEvent evt) {

        String[] argArr = {"-exe", "", "-cmd", "", "-wrk", "", "-cfg", "", "-fil", "", ""};
        argArr[1] = this.exeFile;
        argArr[3] = this.exeCmd;
        argArr[5] = this.workingDirectory;
        argArr[7] = this.cfgFile;

        TFileChooser chooser = new TFileChooser();
        chooser.setCurrentDirectory(new TFile(workingDirectory));
        // Note: source for ErosionFileFilter can be found in FileChooserDemo,
        // under the demo/jfc directory in the JDK.
        ErosionFileFilter filter = new ErosionFileFilter();
        filter.addExtension("in");
        filter.setDescription("Erosion Input Files");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showOpenDialog(this);
        if (returnVal == TFileChooser.APPROVE_OPTION) {
            String curFilePath = chooser.getSelectedFile().getAbsolutePath();
            argArr[9] = curFilePath;
            main(argArr);
        }

    }

    @Override
    protected void JB_openActionPerformed(java.awt.event.ActionEvent evt) {
        JMI_open.doClick();
    }

    @Override
    public void propertyChange(PropertyChangeEvent e) {

        String property = e.getPropertyName();
        if (property.equals(DataStore.DataChanged)) {
            dataChanged = (String) e.getNewValue();
            if (dataChanged.equals("1")) {
                String title = this.getTitle();
                if (!title.endsWith("mod")) {
                    if (title.endsWith(".in")) {
                        title += " mod";
                        this.setTitle(title);
                    }
                }
            }
        } else if (property.equals(usda.weru.weps.RunFileData.SoilFile)) {
            String IFCFileName = (String) e.getNewValue();
            ds.readIFCFile(new TFile(IFCFileName), 0);
        } else if (property.equals(ConfigData.SWEEPExe)) {
            exeFile = (String) e.getNewValue();
        } else if (property.equals(ConfigData.SWEEPCmd)) {
            exeCmd = (String) e.getNewValue();
        } else if (property.equals(ConfigData.WinData)) {
            windDB = (String) e.getNewValue();
            windDB = Util.parse(windDB);
            windIdx = windDB.substring(0, windDB.lastIndexOf(".")) + ".idx";
        } else if (property.equals(ConfigData.SWEEPWorkDir)) {
            workingDirectory = (String) e.getNewValue();
            workingDirectory = Util.parse(workingDirectory);
        } else if (property.equals(ConfigData.SoilDB)) {
            soilDB = (String) e.getNewValue();
            c_soilChooser = null;
            JMI_ssurgo.setEnabled(true);
        } else if (property.equals(SoilChooser.PropSoilChooserNewFile)) {
            ds.readIFCFile((TFile) e.getNewValue(), 0);
        }
        try {
            fv.validateForm(this);
        } catch (NullPointerException npe) {
        }
    }

    @Override
    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    @Override
    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }

    private class LoadGraphs implements Runnable {

        private final Erosion ero;
        private boolean dispFlg = false;

        public LoadGraphs(Erosion ero, boolean dispFlg) {
            this.ero = ero;
            this.dispFlg = dispFlg;
            new Thread(this, "Graph Loader").start();
        }

        @Override
        public void run() {
            ero.OD_graph = new OutputDisplay(new TFile(curFileName), ".egrd");
            java.awt.EventQueue.invokeLater(new Runnable() {
                  
                @Override
                public void run() {
                    ero.JB_graphTotal.setEnabled(true);
                    ero.JMI_graph.setEnabled(true);
                    ero.OD_graph.setVisible(dispFlg);
                    ero.JB_graphSubdaily.setBlinking(true);

                }
            });
            ero.OD_subdaily = new OutputDisplay(new TFile(curFileName), ".sgrd");
            java.awt.EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    ero.JB_graphSubdaily.setEnabled(true);
                    ero.JMI_subdaily.setEnabled(true);
                    ero.JB_graphSubdaily.setBlinking(false);
                }
            });

        }
    }
}
