package usda.weru.weps;

import usda.weru.nrmv.ConvertAllToNrmv;
import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileReader;
import de.schlichtherle.truezip.file.TFileWriter;

import java.awt.Component;
import java.awt.EventQueue;
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.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import java.util.StringTokenizer;
import java.util.concurrent.Semaphore;
import javax.help.CSH;
import javax.measure.unit.NonSI;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.apache.log4j.Logger;
import org.openide.util.Exceptions;
import usda.weru.mcrew.ManageData;
import usda.weru.util.ConfigData;
import usda.weru.util.Mantis;
import usda.weru.util.Util;
import usda.weru.util.WepsFileChooser;
import usda.weru.util.WepsMessage;
import usda.weru.util.WepsMessageDialog;
import usda.weru.util.WepsMessageLog;
import usda.weru.util.windgen.MakeInterpolatedStation;
import usda.weru.weps.location.CligenStation;
import usda.weru.weps.location.FileStation;
import usda.weru.weps.location.InterpolatedStation;
import usda.weru.weps.location.Station;
import usda.weru.weps.location.StationMode;
import usda.weru.weps.location.WindgenStation;
import usda.weru.weps.reports.Locks;
import usda.weru.weps.reports.ReportManager;
import usda.weru.weps.reports.ReportPack;

/**
 * This class makes simulation RUNS for the wind and climate generation data
 * files using the model and shows all the analysis and report genration screens
 * with the data from it.
 */
public final class RunProgram implements Runnable, PropertyChangeListener {

    private String CurrentProj = "";
    private String lastSuccessfulRun = "";
    private String ManageFile = "";
    private String SoilFile = "";
    private String WinGen = "";
    private String CliGen = "";
    private String WinExe = "";
    private String WinGenNumber = "";
    private String WinCmd = "";
    private String TotalYears = "";
    private String startYear = "";
    private String CliExe = "";
    private String CliGenState = "";
    private String CliGenStation = "";
    private String CliCmd = "";
    private String WepsExe = "";
    private String WepsCmd = "";
    private String calWepsCmd = "";
    private String WinFlg = "";
    private String CliFlg = "";
    private String notesText = "";
    private String oldNotes = "";
    private Locks rvLock = new Locks();
    private final Logger LOGGER = Logger.getLogger(RunProgram.class);

    /**
     * holds the command line arguments for three executables 0 windgen.exe 1
     * cligen.exe 2 weps.exe
     */
    String[][] commandsArr = new String[3][];
    String runDir;
    Component parent;
    RunDialog runDialog;
    Thread mainRunThread;
    Process exeProcess;
    private RunFileData runFileData;
    ConfigData configData;
    private String newDir;
    private boolean stopFlag = false;
    private boolean calMode;
    //This boolean is used to check if the copying of the files is done properly for the run. - neha
    private boolean copyResult = false;
    private String xLength;
    private String yLength;
    boolean noteLock = false;
    /**
     * On=bject handle for the calibration factor dialog box for accessing its
     * components within the scope of RUN Program class.
     */
    public CalFactorDialog calibFactors;
    /**
     * The current project name to which this simulation RUN is associated.
     */
    public String projName = "";
    /**
     * Wind station interpolation exe part 1
     */
    private String winIntp1Exe = "";
    /**
     * Wind station interpolation exe part 2
     */
    private String winIntp2Exe = "";

    /**
     * Interpolated wind station builder -- null if not interpolating station
     */
    private MakeInterpolatedStation mis = null;

    /**
     * Copies files into run directory for weps.exe and starts a thread to make
     * a simulation run.
     *
     */
    public RunProgram() {
    }

    /**
     * Copies files into run directory for weps.exe and starts a thread to make
     * a simulation run.
     *
     * @param parent The dialog in which this GUI operates.
     * @param rfd The object handle to runfiledata for accessing items and
     * information through the object modifiers
     * @param cd The configuraion data object handle to make use of setting
     * details.
     * @param cm True if calibration mode is ON else false.
     */
    public RunProgram(Component parent, RunFileData rfd, ConfigData cd, boolean cm) {

        this.runFileData = rfd;
        this.configData = cd;
        this.parent = parent;
        this.calMode = cm;

        if (parent instanceof PropertyChangeListener) {
            addPropertyChangeListener((PropertyChangeListener) parent);
        }

        this.addPropertyChangeListener(rfd);
        rfd.updateDates();
        cd.fireAll(this);
        String rtnExe = checkExesExist();
        if (rtnExe != null) {
            JOptionPane.showMessageDialog(parent, "File not found " + rtnExe,
                    "Exe Not Found Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        rfd.fireAll(this);
        //Make sure that X length and Y length are not zero
        try {
            double test = Double.parseDouble(xLength);
            if (Double.isNaN(test) || Math.abs(test) == 0) {
                throw new NumberFormatException();
            }
        } catch (NumberFormatException nfe) {
            JOptionPane.showMessageDialog(parent, "0.0 is an invalid value for the field X-Length.");
            return;
        }

        try {
            double test = Double.parseDouble(yLength);
            if (Double.isNaN(test) || Math.abs(test) == 0) {
                throw new NumberFormatException();
            }
        } catch (NumberFormatException nfe) {
            JOptionPane.showMessageDialog(parent, "0.0 is an invalid value for the field Y-Length.");
            return;
        }

        if (!checkManExists() && !checkSoilExists()) {
            //no management file or soil file.
            JOptionPane.showMessageDialog(parent, "Management and Soil files not selected or found.  Please select them.",
                    "Files not found ", JOptionPane.ERROR_MESSAGE);
            return;
        } else if (!checkManExists()) {
            JOptionPane.showMessageDialog(parent, "Management file not selected or found.  Please select one.",
                    "File not found ", JOptionPane.ERROR_MESSAGE);
            return;
        } else if (!checkSoilExists()) {
            JOptionPane.showMessageDialog(parent, "Soil file not selected or found.  Please select one.",
                    "File not found ", JOptionPane.ERROR_MESSAGE);
            return;
        }

        //make sure we don't have an xml file
        if (!checkManFormat()) {
            JOptionPane.showMessageDialog(parent, "The selected management file is in an unsupported and "
                    + "experimental XML format.\nReturn to MCREW and save as a *.man format.",
                    "Unsupported File Format ", JOptionPane.ERROR_MESSAGE);
            return;
        }

        if (this.calMode && !checkManCalibration()) {
            return;
        }

        // check if project exists -- if not, save it -- if unsaved, stop run
        if (CurrentProj.endsWith(RunFileData.UntitledProject)) {
            JOptionPane.showMessageDialog(parent,
                    "Untitled Project.  Save project first, then make a run.",
                    "Error (RP-000)", JOptionPane.ERROR_MESSAGE);
            removeListeners(rfd, cd);
            return;   // name not set -- do not run sim
        }

        if (ManageFile.equals(RunFileData.DefaultManageFileName)) {
            JOptionPane.showMessageDialog(parent,
                    "You must pick a management scenario before making a run.",
                    "Error (RP-002)", JOptionPane.ERROR_MESSAGE);
            removeListeners(rfd, cd);
            return;
        }

        if (SoilFile.equals(RunFileData.DefaultSoilFileName)) {
            JOptionPane.showMessageDialog(parent,
                    "You must pick a soil before making a run.",
                    "Error (RP-003)", JOptionPane.ERROR_MESSAGE);
            removeListeners(rfd, cd);
            return;
        }

        TFile tmp = new TFile(WinGen);
        if (!tmp.isAbsolute()) {
            tmp = new TFile(CurrentProj + "/" + lastSuccessfulRun + "/" + WinGen);
        }
        //WINDGEN PRECHECK LOGIC
        StationMode windgenMode = runFileData.getBean().getWindgenStationMode();
        Station windgenStation = runFileData.getBean().getWindgenStation();

        if (windgenMode == null) {
            JOptionPane.showMessageDialog(parent, "No windgen station selected.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        } else if (windgenStation instanceof WindgenStation) {
            //normal station, we generate a wind file with windgen
            //make sure we have enough data to run
            WindgenStation test = (WindgenStation) windgenStation;
            if (test.getWBan() == 0) {
                JOptionPane.showMessageDialog(parent, "The windgen station record is missing the wban parameter.\n"
                        + "Please contact your data provider for updated records.", "Incomplete Windgen Record",
                        JOptionPane.ERROR_MESSAGE);
                return;
            }
        } else if (windgenStation instanceof FileStation) {
            //file station, we use an already generated file.
            FileStation station = (FileStation) windgenStation;
            TFile file = station.getFile();
            if (file == null || !file.exists()) {
                JOptionPane.showMessageDialog(parent, "Windgen file does not exist\n" + "File:  " + file.getAbsolutePath(),
                        "Error (RP-004)", JOptionPane.ERROR_MESSAGE);
                return;
            }
        } else if (windgenStation instanceof InterpolatedStation) {
            //interpolated station
            //no checks yet.
        } else if (windgenStation == null) {
            //no station selected
            JOptionPane.showMessageDialog(parent, "No windgen station selected.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        } else {
            //don't know how to handle the windgen station
            LOGGER.error("Unexpected windgen station type: " + windgenStation.toString());
            return;
        }
        //END WINDGEN PRECHECK LOGIC

        //CLIGEN PRECHECK LOGIC
        StationMode cligenMode = runFileData.getBean().getCligenStationMode();
        Station cligenStation = runFileData.getBean().getCligenStation();

        if (cligenMode == null) {
            LOGGER.error("Unexpected cligen station type: " + cligenStation.toString());
            return;
        } else if (cligenStation instanceof CligenStation) {
            //normal station, we generate a climate file with cligen
            //make sure we have enough data to run
            CligenStation test = (CligenStation) cligenStation;
            if (test.getState() == 0 || test.getId() == 0) {
                JOptionPane.showMessageDialog(parent, "The cligen station record is missing the state id or station id.\n"
                        + "Please contact your data provider for updated records.", "Incomplete Cligen Record",
                        JOptionPane.ERROR_MESSAGE);
                return;
            }
        } else if (cligenStation instanceof FileStation) {
            //file station, we use an already generated file.
            FileStation station = (FileStation) cligenStation;
            TFile file = station.getFile();
            if (file == null || !file.exists()) {
                JOptionPane.showMessageDialog(parent, "Cligen file does not exist\n" + "File:  " + file.getAbsolutePath(),
                        "Error (RP-004)", JOptionPane.ERROR_MESSAGE);
                return;
            }
        } else if (cligenStation == null) {
            //no station selected
            JOptionPane.showMessageDialog(parent, "No cligen station selected.", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        } else {
            //don't know how to handle the cligenStation station
            LOGGER.error("Unexpected cligen station type: " + cligenStation.toString());
            return;
        }
        //END CLIGEN PRECHECK LOGIC

        tmp = new TFile(CliGen);
        if (!tmp.isAbsolute()) {
            tmp = new TFile(CurrentProj + "/" + lastSuccessfulRun + "/" + CliGen);
        }
        if (CliFlg.equals("1") && !(tmp.exists())) {
            JOptionPane.showMessageDialog(parent,
                    "Climate file does not exist\nSpecify file or enable climate generation.\n"
                    + "File:  " + new TFile(CliGen).getAbsolutePath(),
                    "Error (RP-005)", JOptionPane.ERROR_MESSAGE);
            removeListeners(rfd, cd);
            return;
        }

        //Run Name Selector
        RunNameChooser rnc = new RunNameChooser(runFileData, calMode);
        TFile runDirFile = rnc.showRunNameChooser(parent);
        if (runDirFile == null) {
            removeListeners(rfd, cd);
            //user cancelled
            return;
        }
        runFileData.setData(RunFileData.LastRunAttempt, rnc.getRunFile().getName());

        newDir = runDirFile.getName();
        runDir = runDirFile.getAbsolutePath();

        if (mis != null) {
            mis.setParameter(MakeInterpolatedStation.WINFILE_NAME, new TFile(runDir, "win_gen.win").getCanOrAbsPath());
        }

        //make the new run directory
        if (!runDirFile.mkdir()) {
            JOptionPane.showMessageDialog(parent, "Cannot create run directory with name " + newDir,
                    "Error (RP-005)", JOptionPane.ERROR_MESSAGE);
            removeListeners(rfd, cd);
            return;
        }

        // If there occurs a change in the rotation years in Mcrew, then that
        // change should be reflected in the Run Dialog and also in the weps.run file
        //[EndDate in weps.run should change accordingly]
        rfd.setRotationYears(ManageFile);
        rfd.updateDates();

        if (!rnc.getCreateBatch()) {
            this.runDialog = new RunDialog(parent, newDir, this);
            //	//System.out.println("Total years as in RunProgram:"+TotalYears);
            this.runDialog.setTotalYears(TotalYears);
            this.runDialog.setVisible(true);
        }

        //        rfd.showRunFileData("RP:");
        // add -b# for starting year flag
        //WINDGEN EXECUTABLE LOGIC
        if (windgenStation instanceof WindgenStation) {
            WindgenStation station = (WindgenStation) windgenStation;
            //normal station, we generate a wind file with windgen
            List<String> windCmd = new ArrayList<String>();
            windCmd.add(WinExe);
            windCmd.add("-s " + String.valueOf(station.getWBan()));	// station number
            //Add the data file from the config
            WinCmd = Util.parse(WinCmd);
            parseCmd(WinCmd, windCmd);          // misc params
            if (startYear.length() > 0) {
                windCmd.add("-b" + startYear);	// start year
            }
            windCmd.add("-y" + TotalYears);     // number of years
            // output file name, always uses the default name
            windCmd.add("-o" + new TFile(runDir, RunFileData.DefaultWinGenName).getAbsolutePath());
            String[] winArr = windCmd.toArray(new String[windCmd.size()]);
            commandsArr[0] = winArr;

        } else if (windgenStation instanceof FileStation) {
            FileStation station = (FileStation) windgenStation;
            //file station, we use an already generated file.
            copyResult = copyFileStation(runDir, station);
            if (copyResult == false) {
                JOptionPane.showMessageDialog(parent, "Error in copying the Wind File. Aborting Run. ",
                        "Error Copying Files", JOptionPane.ERROR_MESSAGE);
                return;
            }
            if (runDialog != null) {
                runDialog.JTF_win.setText("copied");
            }

        } else if (windgenStation instanceof InterpolatedStation) {
            //interpolated station
            if (runDialog != null) {
                runDialog.JTF_win.setText("interpolating...");
            }
            mis = new MakeInterpolatedStation(null);
            mis.setParameter(MakeInterpolatedStation.INTERPOLATE1_EXE, winIntp1Exe);
            mis.setParameter(MakeInterpolatedStation.INTERPOLATE2_EXE, winIntp2Exe);
            mis.setParameter(MakeInterpolatedStation.WINDGEN_EXE, WinExe);
            mis.setParameter(MakeInterpolatedStation.LAT, String.valueOf(
                    windgenStation.getLatLong().latitudeValue(NonSI.DEGREE_ANGLE)));
            mis.setParameter(MakeInterpolatedStation.LON, String.valueOf(
                    windgenStation.getLatLong().longitudeValue(NonSI.DEGREE_ANGLE)));

            String winIdxFile = ConfigData.getDefault().getDataParsed(ConfigData.WinIndex);
            mis.setParameter(MakeInterpolatedStation.IDX_FILE, winIdxFile);
            mis.setParameter(MakeInterpolatedStation.SIM_START, startYear);
            mis.setParameter(MakeInterpolatedStation.SIM_LENGTH, TotalYears);

            String polFile = ConfigData.getDefault().getDataParsed(ConfigData.WindgenInterpolationBoundaryFile);
            TFile pol = polFile != null && !polFile.isEmpty() ? new TFile(polFile) : null;
            if (pol == null || !pol.exists()) {
                LOGGER.error("Unable to find windgen projection file.");
                return;
            }
            polFile = pol.getAbsolutePath();
            mis.setParameter(MakeInterpolatedStation.POL_FILE, polFile);

            String winDB = ConfigData.getDefault().getDataParsed(ConfigData.WinData);
            mis.setParameter(MakeInterpolatedStation.WDB, winDB);
            System.out.println("runDir " + runDir);
            mis.setParameter(MakeInterpolatedStation.WINFILE_NAME, new TFile(runDir, "interpolated.win").getCanOrAbsPath());
            mis.setParameter(MakeInterpolatedStation.WEIGHTSFILE_NAME, new TFile(runDir,
                    "interpolated_weights.out").getCanOrAbsPath());

        }
        //END WINDGEN EXECUTABLE LOGIC

        //CLIGEN EXECUTABLE LOGIC
        if (cligenStation instanceof CligenStation) {
            CligenStation station = (CligenStation) cligenStation;
            List<String> cliCmd = new ArrayList<String>();
            cliCmd.add(CliExe);
            // state number
            cliCmd.add("-S" + station.getState());
            // state name
            cliCmd.add("-s" + String.valueOf(station.getId()));
            //Add the data file from the config
            CliCmd = Util.parse(CliCmd);
            // misc params
            parseCmd(CliCmd, cliCmd);
            if (startYear.length() > 0) {
                // start year
                cliCmd.add("-b" + startYear);
            }
            // number of years
            cliCmd.add("-y" + TotalYears);
            // output file name
            cliCmd.add("-o" + new TFile(runDir, RunFileData.DefaultCliGenName).getAbsolutePath());
            String[] cliArr = cliCmd.toArray(new String[cliCmd.size()]);
            commandsArr[1] = cliArr;

        } else if (cligenStation instanceof FileStation) {
            FileStation station = (FileStation) cligenStation;
            copyResult = copyFileStation(runDir, station);
            if (copyResult == false) {
                JOptionPane.showMessageDialog(parent, "Error in copying the Climate File. Aborting Run. ",
                        "Error Copying Files", JOptionPane.ERROR_MESSAGE);
                return;
            }
            if (runDialog != null) {
                runDialog.JTF_cli.setText("copied");
            }
        }
        //END CLIGEN EXECUTABLE LOGIC

        List<String> wepsVec = new LinkedList<String>();
        wepsVec.add(WepsExe);
        if (calMode) {
            // misc calib cmds
            parseCmd(calWepsCmd, wepsVec);
        }
        // misc cmds
        parseCmd(WepsCmd, wepsVec);
        // output file name
        wepsVec.add("-P" + runDir);
        String[] wepsArr = wepsVec.toArray(new String[1]);
        commandsArr[2] = wepsArr;

        //check that none of the commands are too long
        if (Util.isWindows()) {
            for (String[] cmd : commandsArr) {
                if (cmd == null) {
                    continue;
                }
                for (String arg : cmd) {
                    if (arg.length() > 259) {
                        runDialog.setVisible(false);
                        JOptionPane pane = new JOptionPane("Command argument too long.\n" + cmd[0] + "\n" + arg,
                                JOptionPane.ERROR_MESSAGE) {
                            private static final long serialVersionUID = 1L;

                            @Override
                            public int getMaxCharactersPerLineCount() {
                                return 80;
                            }
                        };

                        JDialog dialog = pane.createDialog("Command Argument Error");
                        dialog.setVisible(true);
                        return;
                    }
                }
            }
        }

        copyResult = copyManIFCNotes(runDir);
        if (copyResult == false) {
            JOptionPane.showMessageDialog(parent,
                    "Error in copying the Management or Soil Files. Aborting Run.", "Error Copying Files",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        runFileData.writeRunDataXML(CurrentProj);
        runFileData.writeRunFile(runDir);
        if (calMode) {
            TFile backup = new TFile(runDir + TFile.separator + "weps.run");
            TFile orig = Util.incrementFileName(backup, "_orig", ".run");
            try {
                backup.mv(orig);
            } catch (IOException e) {
                LOGGER.warn("Failed to backup weps.run file");
            }
            runFileData.writeRunFile(runDir, calMode);
        }

        mainRunThread = new Thread(this, "RunProgram");

        if (rnc.getCreateBatch()) {
            ScriptWriter.writeBatchScript(runDirFile, configData, WinExe, WinGenNumber,
                    CliExe, CliGenState, CliGenStation, WepsExe, TotalYears, commandsArr);
        } else {
            //start executing
            mainRunThread.start();
        }

        removeListeners(rfd, cd);

        //System.out.println("RP_constructor at the END:");
    }

    private void parseCmd(String cmdLin, List<String> cmdVec) {
        String[] args = cmdLin.split("(^-)|(\\s+-)", -1);
        for (String arg : args) {
            if (arg.trim().length() > 0) {
                cmdVec.add("-" + arg.trim());
            }
        }
    }

//    /**
//     * Copies files into run directory for weps.exe and starts a thread to make a simulation run.
//     * @param parent The dialog in which this GUI operates.
//     * @param rfd The object handle to runfiledata for accessing items and information through
//     * the object modifiers
//     * @param cd The configuraion data object handle to make use of setting details.
//     * @param cm True if calibration mode is ON else false.
//     * @param p The name of the project that this RUN file belongs to.
//     */
//    public RunProgram(Component parent, RunFileData rfd, ConfigData cd, boolean cm, String p) {
//        this(parent, rfd, cd, true);
//        projName = p;
//    //System.out.println("RP_Costructor 5 : Project Name : " + projName);
//    }
    private String checkExesExist() {
        TFile chkFil = new TFile(WinExe);
        if (!chkFil.exists()) {
            return WinExe;
        }
        chkFil = new TFile(CliExe);
        if (!chkFil.exists()) {
            return CliExe;
        }
        chkFil = new TFile(WepsExe);
        if (!chkFil.exists()) {
            return WepsExe;
        }
        return null;
    }

    private boolean checkManFormat() {
        TFile chkFile = new TFile(ManageFile);
        return !chkFile.getName().toLowerCase().endsWith(".xml");
    }

    private boolean checkManExists() {
        TFile chkFile = new TFile(ManageFile);
        return chkFile.exists();
    }

    private boolean checkSoilExists() {
        TFile chkFile = new TFile(SoilFile);
        return chkFile.exists();
    }

    private boolean checkManCalibration() {
        ManageData man = new ManageData();
        man.readDataFile(ManageFile);

        List<String> msgs = new LinkedList<String>();
        if (man.checkCalibration(msgs) == ManageData.CHECK_FAILED) {
            WepsMessageLog log = new WepsMessageLog();
            for (String msg : msgs) {
                log.logMessage(WepsMessage.MessageSeverity.ERROR, msg);
            }
            WepsMessageDialog.showMessageList(null, "Management File Errors", "Unable to proceed with calibration run.\n"
                    + "Errors were detected with the management file.", CurrentProj, log.getMessages());
            return false;
        }
        return true;
    }

    /**
     * Entry point for testing standalone. Used if this dialog is rum as an
     * independent application. if executed, makes the GUI visible.
     *
     * @param args These are the command line arguments passed to the main
     * method.
     */
    static public void main(String args[]) {
        String projectsDir = "";
        WepsFileChooser wfc = new WepsFileChooser(WepsFileChooser.Filetype.PROJECT, projectsDir,
                WepsFileChooser.SELECT);
        wfc.setCurrentDirectory(new de.schlichtherle.truezip.file.TFile("c:/weps/weps.install/projects"));
        RunFileData rfd = new RunFileData();
        //rfd.setSubmodelOutput(runFileData.getSubmodelOutput());
        //setOldSMOutput(rfd);
        if (wfc.showDialog(null) == JFileChooser.APPROVE_OPTION) {
            de.schlichtherle.truezip.file.TFile sf = new TFile(wfc.getSelectedFile());
            try {
                projectsDir = sf.getCanonicalPath();
            } catch (IOException e) {//System.err.println(
                // "Error getting canoncial path of projectsDir");
            }
            rfd.readRunData(projectsDir);
            rfd.showRunFileData("this is a test");
        } else {
            //System.err.println("No project directory selected");
            System.exit(1);
        }
        ConfigData cd = ConfigData.getDefault();

        RunProgram rp = new RunProgram();
//		private PropertyChangeSupport changes = new PropertyChangeSupport(this);
        rp.addPropertyChangeListener(cd);
        rp.changes.firePropertyChange(ConfigData.CurrentProj, null, projectsDir);
        rp.removePropertyChangeListener(cd);
        rfd.showRunFileData("Standalone test");
        JFrame jf = new JFrame();
        new RunProgram(jf, rfd, cd, false);
        try {
            Thread.sleep(50000);
        } catch (java.lang.InterruptedException x) {
        }
        System.exit(1);
    }

    private void removeListeners(RunFileData rfd, ConfigData cd) {

        this.addPropertyChangeListener(rfd);
        rfd.addPropertyChangeListener(this);
        this.addPropertyChangeListener(cd);
        cd.addPropertyChangeListener(this);

    }

    private boolean copyManIFCNotes(String runDir) {
        String fromFile;
        String toFile;
        String tmp;
        boolean retValue = false;

        // copy management file
        tmp = ManageFile;

        fromFile = tmp;
        if (tmp.lastIndexOf(TFile.separator) > 0) {
            toFile = runDir + tmp.substring(tmp.lastIndexOf(TFile.separator));
        } else {
            toFile = runDir + TFile.separator + tmp;
        }
        if (calMode) {
            TFile temporary = new TFile(toFile);
            String tmpOrig = Util.incrementFileName(temporary, "_orig", ".man").getAbsolutePath();
            toFile = tmpOrig;
            retValue = Util.copyFile(fromFile, toFile);
            if (!retValue) {
                return retValue;
            }
            String tmpCalib = Util.incrementFileName(temporary, "_calib", ".man").getAbsolutePath();
            toFile = tmpCalib;
            retValue = Util.copyFile(fromFile, toFile);
            if (!retValue) {
                return retValue;
            }
        } else {

            retValue = Util.copyFile(fromFile, toFile);
            if (!retValue) {
                return retValue;
            }
        }

        // copy IFC file
        tmp = SoilFile;
        fromFile = tmp;
        if (tmp.lastIndexOf(TFile.separator) > 0) {
            toFile = runDir + tmp.substring(tmp.lastIndexOf(TFile.separator));
        } else {
            toFile = runDir + TFile.separator + tmp;
        }
        retValue = Util.copyFile(fromFile, toFile);
        return retValue;

    }

    private boolean copyFileStation(String runDir, FileStation station) {
        TFile fromFile = station.getFile();
        TFile toFile = new TFile(runDir, fromFile.getName());

        return Util.copyFile(fromFile, toFile);
    }

    /**
     * *********************************************************************
     * wjr
     */
    private void displayCalibReport(TFile calibFile, String myRunDir) {
        calibFactors = new CalFactorDialog(this, configData, runFileData);
//        int numCols = 0;
//        numCols = calibFactors.JTA_cropAttributes.getColumns();
        calibFactors.setLocation(50, 50);
        try {

            String inpLin;
            try (BufferedReader in = new BufferedReader(new TFileReader(calibFile))) {
                inpLin = null;
                while (true) {
                    String tmpLin = in.readLine();
                    if (tmpLin == null) {
                        break;
                    }
                    inpLin = tmpLin;
                }
            }
            if (inpLin != null) {
                StringTokenizer st = new StringTokenizer(inpLin, "|");
                StringBuilder sb = new StringBuilder();
                String myNew = "";
                String adjustmentDate = "";
                String adjustmentCrop = "";
                String adjustmentValue = "";

                //System.out.println( " RP_displayCalibReport : Number of Columns: " + numCols );
                while (st.hasMoreTokens()) {
                    st.nextToken();
                    adjustmentDate = st.nextToken();
                    sb.append(" " + adjustmentDate + "\t");
                    st.nextToken();
                    adjustmentCrop = st.nextToken();
                    myNew = adjustmentCrop;

                    /* if( myNew.length() < ( numCols - 23 ) ){
                     for(int i = 0; i < ( ( numCols - 23 ) - myNew.length() ); i++ ){
                     myNew += " ";
                     }
                     }*/
                    sb.append(myNew);
                    adjustmentValue = st.nextToken();
                    sb.append("\t\t" + adjustmentValue + " " + "\n");
                    calibFactors.addCalibrationAdjustment(adjustmentDate, adjustmentCrop, adjustmentValue);
                }
//                oldNotes = new String(notesText);
                notesText = sb.toString() + "\n" + notesText;
//                changes.firePropertyChange(RunFileData.NotesText, null, notesText);
                /*JOptionPane.showMessageDialog(parent,
                 outLin,
                 "Calibration Factors",
                 JOptionPane.INFORMATION_MESSAGE);
                 JOptionPane.showMessageDialog(parent,
                 outLin,
                 "Calib Factors",
                 JOptionPane.ERROR_MESSAGE);*/

                String myCurrProjName = new TFile(myRunDir).getParentFile().getAbsolutePath();
                if (calibFactors == null) {

                    String[] myFiles = new TFile(myRunDir).list();
                    String myManageFile = "";
                    for (String myFile : myFiles) {
                        if (calMode) {
                            if (myFile.endsWith("_calib.man")) {
                                myManageFile = myFile;
                            }
                        } else if (myFile.endsWith(".man")) {
                            myManageFile = myFile;
                        }
                    }
                    if (myManageFile.lastIndexOf('.') > 0) {
                        myManageFile = myManageFile.substring(0, myManageFile.lastIndexOf('.'));
                    }

                    calibFactors.JTF_projName.setText(myCurrProjName);
                    calibFactors.JTF_runName.setText(newDir);
                    calibFactors.JTF_manFile.setText(myManageFile);
                    calibFactors.JTA_cropAttributes.setText(sb.toString());
                    calibFactors.toFront();
                    calibFactors.setVisible(true);
                } else {

                    java.io.File[] myFiles = new TFile(myRunDir).listFiles();

                    String myManageFile1 = "";
                    for (java.io.File myFile : myFiles) {
                        if (calMode) {
                            if (myFile.getName().endsWith("_calib.man")) {
                                calibFactors.setManagementFile(new TFile(myFile));
                                myManageFile1 = myFile.getName();
                            }
                        } else if (myFile.getName().endsWith(".man")) {
                            calibFactors.setManagementFile(new TFile(myFile));
                            myManageFile1 = myFile.getName();
                        }
                    }
                    if (myManageFile1.lastIndexOf('.') > 0) {
                        myManageFile1 = myManageFile1.substring(0, myManageFile1.lastIndexOf('.'));
                    }
                    calibFactors.JTF_projName.setText(myCurrProjName);
                    calibFactors.JTF_runName.setText(newDir);
                    calibFactors.JTF_manFile.setText(myManageFile1);
                    calibFactors.JTA_cropAttributes.setText(sb.toString());
                    calibFactors.updateManagementFile();
                    calibFactors.toFront();
                    calibFactors.setVisible(true);
                }
            }
        } catch (IOException e) {
            //System.err.println("RFD_rRF: " + e);
        } catch (java.lang.NullPointerException f) {
            JOptionPane.showMessageDialog(parent,
                    "Error loading run file",
                    "Error (RFD-001)",
                    JOptionPane.ERROR_MESSAGE);
            f.printStackTrace();
        }
    }

    /**
     * The runnable thread method ( for implements part of Runnable) used to
     * concurrently execute similar programs for additional load bearing like
     * using multiple run files to check more results and generate reports on
     * different files, etc.
     *
     */
    @Override
    public void run() {
        //System.out.println("[RunProgram.java] run();");
        //Log for this thread.
        WepsMessageLog log = new WepsMessageLog();

        PipeIn pipout = null;
        PipeIn piperr = null;
        PrintWriter outerr = null;
        PrintWriter outout = null;
        oldNotes = notesText;
        noteLock = true;
        boolean aborted = false;
        try {

            outerr = new PrintWriter(new BufferedWriter(new TFileWriter(
                    new TFile(runDir, RunFileData.StdErr)))); // SEP01	RUN08
            outout = new PrintWriter(new BufferedWriter(new TFileWriter(
                    new TFile(runDir, RunFileData.StdOut))));// SEP01	RUN08
        } catch (FileNotFoundException ex) {
            LOGGER.error("Could not open stdout or stderr", ex);
            JOptionPane.showMessageDialog(null, "Could not open stdout or stderr in RunProgram\nRun aborted", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }

        if (mis != null) {
            runDialog.JTF_win.setText("interpolating");
            mis.setOut(outout, outerr);
            mis.run();
            runDialog.JTF_win.setText("finished");
        }
        int rtnVal = -1;
        for (int idx = 0; idx < commandsArr.length; idx++) {
            if (idx == 0 && "2".equals(WinFlg)) {
                continue;
            }
            outout.println("");
            outerr.println("");
            if (commandsArr[idx] == null) {
                outout.println((idx == 0) ? "Wind file supplied" : "Climate file supplied");
                outerr.println((idx == 0) ? "Wind file supplied" : "Climate file supplied");
                continue;
            }
            for (String item : commandsArr[idx]) {
                outout.println(item);
            }
            for (String item : commandsArr[idx]) {
                outerr.println(item);
            }

            runDialog.JTF_arr[idx].setText("running");

            try {
                exeProcess = Runtime.getRuntime().exec(commandsArr[idx]);
                pipout = new PipeIn(exeProcess.getInputStream(), outout, this, idx);
                pipout.start();
                piperr = new PipeIn(exeProcess.getErrorStream(), outerr, null, idx);
                piperr.start();
                rtnVal = exeProcess.waitFor();
                //Wait for the pipes to finish writing their logs.

                while (piperr.isAlive() || pipout.isAlive()) {
                    Thread.sleep(100);
                }

            } catch (java.io.IOException i) {
                //System.err.println("rP: Error " + i);
                log.logMessage(new WepsMessage(i));
                Mantis.error("WEPS Error", i, runDir);

            } catch (java.lang.InterruptedException j) {
                //System.err.println("rP: Error " + j);
                log.logMessage(new WepsMessage(j));
            }

            if (pipout != null) {
                log.mergeLog(pipout.getLog());
            }
            if (piperr != null) {
                log.mergeLog(piperr.getLog());
            }

            if (log.getCount(WepsMessage.MessageSeverity.ERROR) > 0) {
                WepsMessageDialog.showMessageList(null, "Run Errors", CurrentProj, log.getMessages(
                        WepsMessage.MessageSeverity.ERROR));
                aborted = true;
            }

            if (rtnVal != 0) {
                if (!stopFlag) {
                    JOptionPane.showMessageDialog(parent, "Error executing " + commandsArr[idx][0], "Abnormal Termination "
                            + rtnVal, JOptionPane.ERROR_MESSAGE);
                    Mantis.message("WEPS Error", "Error executing " + commandsArr[idx][0], runDir);
                    aborted = true;
                    break;
                } else {
                    JOptionPane.showMessageDialog(parent, "Run canceled by user " + runDir, "Abnormal Termination",
                            JOptionPane.WARNING_MESSAGE);
                    aborted = true;
                    break;
                }
            }

            runDialog.JTF_arr[idx].setText("finished");
        }

        outout.close();
        outerr.close();

        runDialog.runFlag = false;
        runDialog.JB_can.setEnabled(false);

        /* weps run completed successfully */
        if (exeProcess.exitValue() == 0 && !aborted) {
            TFile calibFile = new TFile(runDir, RunFileData.CalibFileName);
            if (calibFile.exists() && calibFile.length() != 0) {
                displayCalibReport(calibFile, runDir);
            }
            //Display Dialog of warnings. and update the notes variable with each warning.
            if (log.getCount(WepsMessage.MessageSeverity.WARNING) > 0) {
                runDialog.JTF_status.setText("Warnings...");
                //oldNotes = new String(notesText);
                //for(WepsMessage message : log.getMessages(WepsMessage.MessageSeverity.WARNING)){
                //notesText += message.toString() + "\n";
                //}
                notesText = "This WEPS Run generated one or more Warning messages. "
                        + "For detailed information about these Warnings, see this run's '"
                        + RunFileData.WarningsFile + "' output file.\n\n" + notesText;
                try {
                    try (BufferedWriter out = new BufferedWriter(
                            new TFileWriter(new TFile(runDir, RunFileData.WarningsFile)))) {
                        out.write("Project: " + CurrentProj);
                        out.newLine();
                        out.write("Run: " + runDir);
                        out.newLine();
                        out.write("Timestamp: " + new Date().toString());
                        out.newLine();
                        out.newLine();
                        for (WepsMessage message : log.getMessages(WepsMessage.MessageSeverity.WARNING)) {
                            out.write(message.toString());
                            out.newLine();
                        }
                    }

                } catch (IOException ioe) {
                    //System.err.println("Error writing weps warnings to log file.");
                }
                WepsMessageDialog.showMessageList(null, "Warning Messages Generated", "", CurrentProj,
                        WepsMessageDialog.OK_OPTION, log.getMessages(WepsMessage.MessageSeverity.WARNING));
            }
            noteLock = false;
            changes.firePropertyChange(RunFileData.NotesText, null, notesText);
            runFileData.writeNotesFile(runDir);
            changes.firePropertyChange(RunFileData.NotesText, null, oldNotes);
            //Delete files we've been told are not needed after a good run.
            purgeRunFiles();
            //WepsEvent.fireRun(this, new File(runDir), true );
            changes.firePropertyChange(Weps.WEPS_RUNCREATED, null, runDir);
            //Update the last run variable
            changes.firePropertyChange(RunFileData.LastRun, null, new TFile(runDir).getAbsolutePath());
            //display each of the reports selected for immediate viewing
            String reportsToViewString = configData.getData(ConfigData.ReportsView);
            String[] reportsToView = reportsToViewString.split(",", -1);
            for (String reportName : reportsToView) {
                reportName = reportName.trim();
                if (reportName.length() > 0) {
                    ReportPack pack = ReportManager.getDefault().getReportPack(new TFile(runDir), reportName);
                    pack.startFill();
                    ReportManager.getDefault().displayReport(runDir, reportName);
                }
            }
            //create pdf's for all reports
            Thread task = new Thread("RunProgram pdfs") {
                int state = 0;

                @Override
                public void run() {
                    switch (state) {
                        case 0:
                            state = 1;
                            try {
                                EventQueue.invokeAndWait(this);
                            } catch (InterruptedException | InvocationTargetException ex) {
                            }
                            //This is where all reports are initially created 
                            String reportsToPDFString = configData.getData(ConfigData.ReportsGeneratePDF);
                            String[] reportsToPDF = reportsToPDFString.split(",", -1);
                            for (String reportName : reportsToPDF) {
                                reportName = reportName.trim();
                                //System.out.println("reportName: " + reportName);
                                if (reportName.length() > 0 /*&& reportName.equals("run")*/) {
                                    //System.out.println("running PDF..." +reportName);
                                    try {
                                        //locks used to help manage report generation and 
                                        //issues with executing threads concurrently
                                        rvLock.getrpMutex();
                                        rvLock.getrvMutex();
                                        ReportPack pack = ReportManager.getDefault().getReportPack(new TFile(runDir), reportName);
                                        //pack.startFill();
                                        pack.waitWhileFilling();
                                        ReportManager.getDefault().generateReportPDF(runDir, reportName);
                                        rvLock.setrpMutex();
                                        rvLock.setrvMutex();
                                    } catch (Throwable t) {
                                        LOGGER.error("Unable to generate \"" + reportName + "\".pdf.", t);
                                        JOptionPane.showMessageDialog(parent, "Unable to generate \"" + reportName
                                                + "\".", "PDF Error", JOptionPane.ERROR_MESSAGE);
                                    }
                                }
                            }
                            state = 2;
                            EventQueue.invokeLater(this);
                            return;

                        case 1:
                            runDialog.JTF_status.setText("Generating reports...");
                            return;

                        case 2:
                            runDialog.setVisible(false);
                            runDialog.dispose();
                            runDialog = null;
                            break;
                    }
                }
            };
            task.start();
            try {
                task.join();
            } catch (InterruptedException ex) {
                Exceptions.printStackTrace(ex);
            }
        } else {
            runDialog.setVisible(false);
            runDialog.dispose();
            runDialog = null;
            changes.firePropertyChange(Weps.WEPS_RUNCREATED, null, runDir);
        }

        if ("on".equals(this.configData.getData(ConfigData.NRMVMode))
                || "summaries".equals(this.configData.getData(ConfigData.NRMVMode))) {
            System.out.println("running summaries...");
            ConvertAllToNrmv catn = new ConvertAllToNrmv(newDir, runDir);
            catn.shouldDoAverages("summaries".equals(this.configData.getData(ConfigData.NRMVMode)));
            catn.run();
        }
    }

    /**
     * Inner class with a JDialog as the GUI interface to be used for the text
     * messages to be used as required for the Run program messages to be
     * delivered.
     */
    public static class TextDialog extends JDialog implements ActionListener {

        private static final long serialVersionUID = 1L;

        /**
         * Tells if the text dialog box is active and running.
         */
        protected boolean active = false;
        /**
         * True, tells that thetext dialog is closed and not being used.
         */
        protected JButton closeb;
        /**
         * Label that will be placed as a component on the text/Jdialog
         */
        protected JLabel l1;
        // protected Button disableButton;  // the button which fires up this dialog

        /**
         * Default constructor for the dialog box that initializes it with some
         * component specifics mentioned.
         *
         */
        public TextDialog() {
            active = true;

            l1 = new JLabel();

            closeb = new JButton("Close");
            JPanel textp = new JPanel();
            textp.add(l1);
            JPanel closep = new JPanel();
            closep.add(closeb);

            getContentPane().add("North", textp);
            getContentPane().add("South", closep);

            this.setLocation(200, 600);
            setSize(200, 100);

            closeb.addActionListener(this);
            setSize(this.getPreferredSize());

        }

        /**
         * Sets the title fo the dialog box in which the text dialog sits.
         *
         * @param t The string that will be aasigned
         */
        public void mySetTitle(String t) {
            this.setTitle(t);
        }

        /**
         * This gets the label name from the string already assigned.
         *
         * @return The current string that is assigned.
         */
        public String myLabelGetText() {
            return (l1.getText());
        }

        /**
         * This sets the label name to the string parameter passed.
         *
         * @param labelText The sting value to be assigned
         */
        public void myLabelSetText(String labelText) {
            l1.setText(labelText);
        }

        /**
         * Recognizes event for keeping window visible/hidden.
         *
         * @param e Action event to realize who the generator is.
         */
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == closeb) {
                active = false;
                // disableButton.setEnabled (true);
                setVisible(false);
                dispose();

            }
        }
    }

    /**
     * Wrapper for window tha t tracks exe progress. Replaces RunWindow class
     *
     * @author wjr
     */
    class RunDialog extends usda.weru.weps.gui.RunDialog_n {

        private static final long serialVersionUID = 1L;

        RunProgram runProgram;
        boolean runFlag = true;
        JTextField[] JTF_arr = {JTF_win, JTF_cli, JTF_weps};

        RunDialog(Component parent, String title, RunProgram runProgram) {
            super();
            addHelp();
            this.runProgram = runProgram;
            setTitle("WEPS Run: " + title);
            setLocation(100, 100);

            setVisible(true);
            setResizable(true);
            JL_runName.setText(title);
            JL_runName.setToolTipText(title);

            pack();

            addWindowListener(new WindowAdapter() {

                @Override
                public void windowClosed(WindowEvent e) {
                    stopFlag = true;
                    if (exeProcess != null) {
                        exeProcess.destroy();
                    }
                }
            });

        }

        /**
         * help stuff
         */
        private void addHelp() {
            CSH.setHelpIDString(JLabel4, "runWindGen_html");
            CSH.setHelpIDString(JTF_win, "runWindGen_html");

            CSH.setHelpIDString(JLabel2, "runCliGen_html");
            CSH.setHelpIDString(JTF_cli, "runCliGen_html");

            CSH.setHelpIDString(JLabel3, "runWepsModel_html");
            CSH.setHelpIDString(JTF_weps, "runWepsModel_html");

            CSH.setHelpIDString(JTF_status, "runStatusBar_html");
            CSH.setHelpIDString(JPB_weps, "runProgressBar_html");
            CSH.setHelpIDString(JB_can, "runCancelButton_html");

            CSH.setHelpIDString(this, "runDialog_html");
        }

        /**
         * Sets max number of years for JProgressBar
         *
         * @param tot
         */
        public void setTotalYears(String totstr) {
            try {
                JPB_weps.setMaximum(Integer.parseInt(totstr));
            } catch (java.lang.NumberFormatException e) {
                //System.err.println("RP: can't parse total years string " + e);
            }
        }

        /**
         * Sets current year from weps.exe
         *
         * @param cur year number
         */
        public void setCurrentYear(int cur) {
            JPB_weps.setValue(cur);
        }

        /**
         * Kills current weps.exe run
         *
         * @param event
         */
        @Override
        public void JBCan_actionPerformed(java.awt.event.ActionEvent event) {
            stopFlag = true;
            if (runProgram != null && runProgram.exeProcess != null) {
                runProgram.exeProcess.destroy();
            }
            this.dispose();
        }
    }

    /**
     * Thread to receive weps.exe stdout or stderr. Directs all output into a
     * file. Parses stdout and updates RunDialog
     *
     * @author wjr
     */
    static class PipeIn extends Thread {

        private final WepsMessageLog c_log;
        InputStream from;
        PrintWriter to;
        RunProgram rp;

        public PipeIn(InputStream from, PrintWriter to, RunProgram rp, int idx) {
            this.from = from;
            this.to = to;
            this.rp = rp;

            c_log = new WepsMessageLog();
        }

        public WepsMessageLog getLog() {
            return c_log;
        }

        @Override
        public void run() {

            String inpstr, trimstr, message = null;
            BufferedReader bid = new BufferedReader(new InputStreamReader(from), 10);

            try {
                while ((inpstr = bid.readLine()) != null) {
                    to.println(inpstr);
                    trimstr = inpstr.trim();

                    //Special run time catches
                    if (rp != null) {
                        //trim the input string so that the leading white spaces are removed-neha
                        if (trimstr.startsWith("Year")) {
                            rp.runDialog.JTF_status.setText(inpstr);
                            StringTokenizer st = new StringTokenizer(inpstr);
                            st.nextToken();
                            rp.runDialog.JPB_weps.setValue(Integer.parseInt(st.nextToken()));
                        }
                    }
                    //Catch Errors and warnings
                    if (trimstr.startsWith("Requested Station Not Found.")) {
                        //Cligen was not happy, unable to find desired station.
                        c_log.logMessage(WepsMessage.errorMessage(
                                "Selected cligen station does not exist in the cligen database being used."));
                    } else if (trimstr.startsWith("Error")) {
                        message = trimstr.replaceFirst("Error:", "");
                        message = message.replaceFirst("Error :", "");
                        c_log.logMessage(WepsMessage.errorMessage(message.trim()));
                    } else if (trimstr.startsWith("Warning")) {
                        message = trimstr.replaceFirst("Warning:", "");
                        message = message.replaceFirst("Warning :", "");
                        c_log.logMessage(WepsMessage.warningMessage(message.trim()));
                    }

                }
                to.flush();
            } catch (IOException e) {
                //System.err.println("PipeIn: " + e);
            }
        }
    }

    /**
     * Deletes wingen and cligen files that are no longer needed after the weps
     * simulation.
     */
    public void purgeRunFiles() {

        if (ConfigData.getDefault().isPurgeFlag()) {
            //We have a filter to work with.

            String dirString = runDir;
            TFile dir = new TFile(dirString);
            String[] list = dir.list();
            if (list == null) {
                return;
            }
            for (String list1 : list) {
                if (isPurgeable(list1)) {
                    TFile file = new TFile(dirString, list1);
                    LOGGER.info("Deleting: " + file.getAbsolutePath());
                    try {
                        file.rm();
                    } catch (IOException e) {
                        LOGGER.warn("Unable to delete file: " + file.getAbsolutePath());
                    }
                }
            }
        }

    }

    private boolean isPurgeable(String name) {
        String[] filters = ConfigData.getDefault().getPurgeFilenames();
        for (String filter : filters) {
            if (filter.equalsIgnoreCase(name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 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("pC: " + e.getPropertyName());
        switch (e.getPropertyName()) {
            case ConfigData.WinExe:
                WinExe = (String) e.getNewValue();
                break;
            case RunFileData.WinGenStation:
                WinGenNumber = (String) e.getNewValue();
                break;
            case ConfigData.WinCmd:
                WinCmd = (String) e.getNewValue();
                break;
            case ConfigData.WindInterp1EXE:
                winIntp1Exe = (String) e.getNewValue();
                break;
            case ConfigData.WindInterp2EXE:
                winIntp2Exe = (String) e.getNewValue();
                break;
            case RunFileData.TotalYears:
                TotalYears = (String) e.getNewValue();
                break;
            case RunFileData.StartDate:
                String StartDate = (String) e.getNewValue();
                String[] tmpArr = StartDate.split(" +");
                startYear = tmpArr[2];
                break;
            case ConfigData.CliExe:
                CliExe = (String) e.getNewValue();
                break;
            case RunFileData.CliGenState:
                CliGenState = (String) e.getNewValue();
                break;
            case RunFileData.NotesText:
                if (!noteLock) {
                    notesText = (String) e.getNewValue();
                } else {
                    oldNotes = (String) e.getNewValue();
                }
                break;
            case RunFileData.CliGenStation:
                CliGenStation = (String) e.getNewValue();
                break;
            case ConfigData.CliCmd:
                CliCmd = (String) e.getNewValue();
                break;
            case ConfigData.WepsExe:
                WepsExe = (String) e.getNewValue();
                break;
            case ConfigData.WepsCmd:
                WepsCmd = (String) e.getNewValue();
                break;
            case ConfigData.CalWepsCmd:
                calWepsCmd = (String) e.getNewValue();
                break;
            case RunFileData.WindFlag:
                WinFlg = (String) e.getNewValue();
                //System.out.println("RP_pC: winflg " + WinFlg);
                break;
            case RunFileData.ClimateFlag:
                CliFlg = (String) e.getNewValue();
                break;
            case ConfigData.CurrentProj:
                CurrentProj = Util.parse(e.getNewValue().toString());
                break;
            case RunFileData.SoilFile:
                SoilFile = (String) e.getNewValue();
                break;
            case RunFileData.ManageFile:
                ManageFile = (String) e.getNewValue();
                //changes.firePropertyChange(e);
                break;
            case RunFileData.WindFile:
                WinGen = (String) e.getNewValue();
                break;
            case RunFileData.ClimateFile:
                CliGen = (String) e.getNewValue();
                break;
            case RunFileData.LastRun:
                lastSuccessfulRun = (String) e.getNewValue();
                break;
            case RunFileData.XLength:
                xLength = (String) e.getNewValue();
                break;
            case RunFileData.YLength:
                yLength = (String) e.getNewValue();
                break;
        }
    }
    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.
     */
    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.
     */
    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }

}
