package usda.weru.weps;

import de.schlichtherle.truezip.file.TFile;
import de.schlichtherle.truezip.file.TFileInputStream;
import de.schlichtherle.truezip.file.TFileOutputStream;
import de.schlichtherle.truezip.file.TFileReader;
import de.schlichtherle.truezip.file.TFileWriter;
import java.util.*;
import javax.swing.*;
import java.beans.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import systems.uom.common.USCustomary;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.IllegalDataException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import usda.weru.gis.latlong.LatLong;
import usda.weru.gis.GISData;
import usda.weru.gis.GISLookup;
import usda.weru.mcrew.ManageData;
import usda.weru.util.Caster;
import usda.weru.util.ConfigData;
import usda.weru.util.ExceptionEventQueue;
import usda.weru.util.FireAllContext;
import usda.weru.util.LoadingContext;
import usda.weru.util.PropertyStackContext;
import usda.weru.util.RelativeFileContext;
import usda.weru.util.RestoringContext;
import usda.weru.util.Util;
import usda.weru.util.WepsMessage;
import usda.weru.util.WepsMessageLog;
import usda.weru.util.wepsFileChooser2.WepsFileChooser2;
import usda.weru.util.wepsFileChooser2.WepsFileTypes2;
import usda.weru.weps.location.CligenDataModel;
import usda.weru.weps.location.CligenStation;
import usda.weru.weps.location.ElevationMode;
import usda.weru.weps.location.FileStation;
import usda.weru.weps.location.InterpolatedStation;
import usda.weru.weps.location.Site;
import usda.weru.weps.location.Site.Level0;
import usda.weru.weps.location.StationMode;
import usda.weru.weps.location.Station;
import usda.weru.weps.location.StationUtil;
import usda.weru.weps.location.WindgenDataModel;
import usda.weru.weps.location.WindgenStation;


public class RunFileData implements PropertyChangeListener {

    private static final Logger LOGGER = LogManager.getLogger(RunFileData.class);
    private final WepsMessageLog c_log = new WepsMessageLog();
    private static final String VERSION_MARKER = "#VERSION=";

    protected boolean c_displayMessages = true;

    public static final double VERSION_WATER_EROSION = 1.01;
    public static final double VERSION_ROCK_FRAGMENTS = 1.02;
    public static final double VERSION_LOCPANEL_REWRITE = 1.03;
    public static final double VERSION_LOCPANEL_SITE = 1.04;
    public static final double VERSION_RELATIVE_PATHS = 1.05;
    //The current version is written out when a file is saved.
    public static final double VERSION_CURRENT = VERSION_RELATIVE_PATHS;
    public static final String ProjectSuffix = ".wpj";
    public static final String RunSuffix = ".wjr";
    public static final String DefaultWinGenName = "win_gen.win";
    public static final String DefaultCliGenName = "cli_gen.cli";
    public static final String WarningsFile = "warnings.txt";
    public static final String DefaultSubDailyWindName = "none";
    public static final String DefaultManageFileName = "none";
    public static final String DefaultSoilFileName = "none";
//    public static final String IFCTemplateDir = "{IFCTemplateDir}";
//    public static final String ManTemplateDir = "{ManTemplateDir}";
    public static final String WepsRun = "weps.run";
    public static final String WepsData = "weps.ini";
    public static final String UntitledProject = "untitled.wpj";
    public static final String NotesFileName = "notes.txt";
    public static final String StdErr = "stderr.txt";
    public static final String StdOut = "stdout.txt";
    public static final String HarvCalibParmFileName = "harvest_calib_parm.out";
    public static final String WepsOutput = "gui1_data.out";
    public static final String SCIOutput = "sci_energy.out";
    public static final String EnergyOutput = "stir_energy.out";
    
    
    public static final String RFD = "RFD-";
    
    public static final String FireProperty = RFD + "FireProperty";
    public static final String UserName = RFD + "UserName";
    public static final String FarmId = RFD + "FarmId";
    public static final String TractId = RFD + "TractId";
    public static final String FieldId = RFD + "FieldId";
    //public static final String SiteState=RFD + "SiteState";  // still used for weps.run file documentation - LEW
    //public static final String SiteCounty = RFD + "SiteCounty";  // still used for weps.run file documentation - LEW
//    public static final String State = RFD + "StateUpdate";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_SITE)
    public static final String Site = RFD + "Site";
//    public static final String Latitude = RFD + "Latitude";
//    public static final String LatitudeSign = RFD + "LatitudeSign";
//    public static final String Longitude = RFD + "Longitude";
//    public static final String LongitudeSign = RFD + "LongitudeSign";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_LATLONG)
    public static final String StrLatLong = RFD + "LatLong";
//    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_ELEVATION_MODE)
//    public static final String RFD_ELEVATION_MODE = RFD + "elevation.mode";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_ELEVATION)
    public static final String Elevation = RFD + "Elevation";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_CLIGEN_STATION_MODE)
    public static final String ClimateFlag = RFD + "ClimateFlag";
//    public static final String CliGenStationName = RFD + "CliGenStationName";
    public static final String CliGenState = RFD + "CliGenState";
    public static final String CliGenStation = RFD + "CliGenStation";
    public static final String SelectFieldLocTxt= RFD + "SelectFieldLocTxt";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_CLIGEN_STATION)
    public static final String CligenStation = RFD + "cligen.station";	//handled by the mode
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_WINDGEN_STATION_MODE)
    public static final String WindFlag = RFD + "WindFlag";
//    public static final String WindGenStationName = RFD + "WindGenStationName";
    public static final String WinGenStation = RFD + "WinGenStation";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_WINDGEN_STATION)
    public static final String WindgenStation = RFD + "windgen.station";  //handled by the mode
    public static final String StartDate = RFD + "StartDate";
    public static final String EndDate = RFD + "EndDate";
    public static final String RotationYears = RFD + "RotationYears";
    public static final String CycleCount = RFD + "CycleCount";
    public static final String TimeSteps = RFD + "TimeSteps";
    //public static final String CliGen				= RFD + "CliGen";
    //public static final String WinGen				= RFD + "WinGen";
    //public static final String SubDaily			= RFD + "SubDaily";
    public static final String SoilFile = RFD + "SoilFile";
    public static final String ManageFile = RFD + "ManageFile";
    public static final String MgtCalibFile = RFD + "MgtCalibFile";  //Used only for passing the mgt file used for calibration runs - 02/16-23 - LEW
    public static final String OutputFile = RFD + "OutputFile";
    public static final String ReportForm = RFD + "ReportForm";
    public static final String OutputPeriod = RFD + "OutputPeriod";
    public static final String SubmodelOutput = RFD + "SubmodelOutput";
    public static final String DebugOutput = RFD + "DebugOutput";
    public static final String WaterErosionLoss = RFD + "WaterErosionLoss";
    public static final String SoilRockFragments = RFD + "SoilRockFragments";
    public static final String RegionAngle = RFD + "RegionAngle";
    private static final String SimPoint1 = RFD + "SimPoint1";
    private static final String SimPoint2 = RFD + "SimPoint2";
    private static final String Scales = RFD + "Scales";
    private static final String AccNo = RFD + "AccNo";
    private static final String AccPoint1 = RFD + "AccPoint1";
    private static final String AccPoint2 = RFD + "AccPoint2";
    private static final String SubregionNo = RFD + "SubregionNo";
    private static final String SubPoint1 = RFD + "SubPoint1";
    private static final String SubPoint2 = RFD + "SubPoint2";
    public static final String AverageSlope = RFD + "AverageSlope";
    private static final String BarrierNo = RFD + "BarrierNo";
    public static final String Barrier = RFD + "Barrier";
    public static final String BarrierN = RFD + "BarrierN";
    public static final String BarrierW = RFD + "BarrierW";
    public static final String BarrierS = RFD + "BarrierS";
    public static final String BarrierE = RFD + "BarrierE";
    public static final String BarrierD = RFD + "BarrierD";
    public static final String XLength = RFD + "XLength";
    public static final String YLength = RFD + "YLength";
    public static final String Shape = RFD + "Shape";
    public static final String Radius = RFD + "Radius";
    public static final String WindFile = RFD + "wind file";
    public static final String ClimateFile = RFD + "climate file";
    public static final String SubDailyFile = RFD + "sub-daily file";
    public static final String TotalYears = RFD + "TotalYears";
    public static final String NotesFile = RFD + "NotesFile";
    @RunFileDataBeanBridge.BeanProperty(RunFileBean.PROP_NOTES)
    public static final String NotesText = RFD + "NotesText";
    public static final String NotesReadonly = RFD + "NotesReadOnly";
    public static final String RunTypeDisp = RFD + "runtypedisp";
    public static final String LastRun = RFD + "lastrun";
    public static final String RunsLocation = RFD + "runs location";
    public static final String LastRunAttempt = RFD + "last run attempt";
    public static final String DataChanged = "DataChanged " + RFD;
    public static final String WriteRunData = "WriteRunData";
    public static final String WriteRunFile = "WriteRunFile";
    public static final String ReadRunData = "ReadRunData";
    public static final String ReadRunFile = "ReadRunFile";
    public static final String ShowRunData = "ShowRunData";
    public static final String LoadData = "LoadData";
    public static final String ResetBarriers = "reset barriers";
    
    // here is temp
    public static final String ManageFileSkip = RFD + "ManageFileSkip";
//    public static final String AverageSlopeField = RFD + "AverageSlope_field";//DNA
//    public static final String SoilRockFragmentsField = RFD + "SoilRockFragments_field";//DNA

    public SubmodelOutput so = new SubmodelOutput(ConfigData.getDefault());

    Hashtable<String, String> ht = new Hashtable<>(200);
    Hashtable<String, String> htSnap = new Hashtable<>(200);
    private String curProj = "";
    private String NRCSRunLen = "";
    private String restoreRunElevation = "";
    
    private static boolean continueToShowErrorMessage_latLon = true;

    public TFile fileObject = null;
    
    static boolean lockMessage = true;
    static ArrayList<String> currentRanFiles = new ArrayList<>();
    boolean enableExternalActions = true;
    private RunFileBean c_bean;

    public RunFileData(String pathName) {
        this(pathName, true);
    }

    public RunFileData(String pathName, boolean displayMessages) {
        c_displayMessages = displayMessages;
        readRunFile(pathName);
    }

    public RunFileData(String pathName, boolean displayMessages, boolean bypassUpdate) {
        c_displayMessages = displayMessages;
        readRunFile(pathName, bypassUpdate);
    }
        
    public RunFileData() {
        this(false);
    }

    public RunFileData(boolean initialize) {
        if (initialize) {
            initialize();
        }
    }
    
    static public void main(String args[]) {
        WepsFileChooser2 wfc = new WepsFileChooser2(WepsFileTypes2.Project, "",
                WepsFileChooser2.Action.Open);
        // initializationData testing fix
        wfc.setCurrentDirectory("h:/weps/weps.install/projects");

        RunFileData rfd = new RunFileData();
        if (wfc.showDialog(null) == WepsFileChooser2.APPROVE_OPTION) {
            de.schlichtherle.truezip.file.TFile sf = new TFile(wfc.getSelectedFile());
            String projectsDir = "";
            try {
                projectsDir = sf.getCanonicalPath();
            } catch (IOException e) {
            }//System.err.println(
            //      "Error getting canoncial path of projectsDir");}

            rfd.readRunData(projectsDir);
        } else {
            rfd.initialize();
        }
        rfd.showRunFileData("Standalone test");
        System.exit(1);
    }
    private boolean runLocRestore = true;
    public void setRunLocationRestore(boolean rl){
        runLocRestore = rl;
    }
    
    public void setGuiRestore(boolean r1){
        if(r1){
            String holdRunLoc = getData(RunsLocation);
            initialize();
            setData(RunsLocation, holdRunLoc);
        }
    }
    
    
    public void initialize() {       
        setData(RunTypeDisp, ConfigData.getDefault().getData(ConfigData.DefaultRunMode));
        
        if (ht.containsKey(SelectFieldLocTxt)){
            setData(SelectFieldLocTxt,ht.get(SelectFieldLocTxt));
        }
        else
            setData(SelectFieldLocTxt, "Please Select Field Location");
        setData(UserName, "");
        setData(FarmId, "");
        setData(TractId, "");
        setData(FieldId, "");

        getBean().setSite(usda.weru.weps.location.Site.valueOf("fips:US00-KS-055"));

        setData(StrLatLong, "+37.73835;-100.43785");

        ////default to the cligen mode, only one working at the moment.
        getBean().setElevationMode(ElevationMode.Cligen);
        setData(Elevation, "801.0");
        setData(CliGenState, "");
        setData(CliGenStation, "");
        setData(StartDate, "01 01 2001");
        setData(EndDate, "31 12 2001");
        setData(RotationYears, "1");
        setData(CycleCount, "50");
        setData(TotalYears, "6");
        setData(TimeSteps, "24");
        setData(SubDailyFile, DefaultSubDailyWindName);
        setData(SoilFile, DefaultSoilFileName);
        setData(ManageFile, DefaultManageFileName);
        setData(ReportForm, "0 0 0 0 0 0");
        setData(OutputPeriod, "2");
        //setData(SubmodelOutput, "0 0 0 0 0 0");
        //setData(DebugOutput, "0 0 0 0 0 0");
        setData(RegionAngle, "0");
        setData(SimPoint1, "100.0 100.0");
        setData(SimPoint2, "904.7 904.7");
        setData(Scales, "10.0 0.25");
        setData(AccNo, "1");
        setData(AccPoint1, "100.0 100.0");
        setData(AccPoint2, "904.7 904.7");
        setData(SubregionNo, "1");
        setData(SubPoint1, "100.0 100.0");
        setData(SubPoint2, "904.7 904.7");

        //A negative slope is ignored by WEPS
        setData(AverageSlope, "-1");
//        setData(AverageSlopeField, "-1");
        changes.firePropertyChange(ResetBarriers, null, null);
        setData(BarrierNo, "0");
        setData(BarrierN, "none|0.0|0.0|0.0");
        setData(BarrierS, "none|0.0|0.0|0.0");
        setData(BarrierE, "none|0.0|0.0|0.0");
        setData(BarrierW, "none|0.0|0.0|0.0");

// MEH Do not force these defaults, should come only from
// default or selected project or from Mapviewer selection.
//        getBean().setCligenStationMode(StationMode.NRCS);
//        getBean().setWindgenStationMode(StationMode.NRCS);
//        setData(CliGenStationName, "CIMARRON");
//        setData(CliGenState, "14");
//        setData(CliGenStation, "1522");
        setData(NotesReadonly, "0");
        setData(NotesFile, NotesFileName);
        setData(NotesText, "", false);  // The "\n" is getting stripped off so text appended is not starting on a
        // new line - this is a quick fix - LEW

        setData(Shape, "rectangle");
        setData(XLength, "804.7");
        setData(YLength, "804.7");
        setData(Radius, "0");
        setData(LastRunAttempt, "");
        //Defaults to the config value
        if (!RestoringContext.isRestoring()) {
            setData(RunsLocation, ConfigData.getDefault().getData(ConfigData.DefaultRunsLocation));
        }
        if(!runLocRestore){
            //This will set to the default if a project is being reset fully
            
            String defRunLoc =  ConfigData.getDefault().getDataParsed(ConfigData.DefaultRunsLocationTemplate);
            File testExist = new File(defRunLoc+File.separator + "Runs");
            if(testExist.exists()){defRunLoc = defRunLoc + File.separator + "Runs";}
            
            setData(RunsLocation, defRunLoc);
            setRunLocationRestore(true);
        }else{
            
        }
        setData(WaterErosionLoss, "0.00");

        setData(SoilRockFragments, "-1");
//        setData(SoilRockFragmentsField,"-1");
        fixUpData();
        changes.firePropertyChange(DataChanged, null, "xxx");
//        initRegPanelValues();
    }

    public String getData(String idxstr) {
        return ht.get(idxstr);
    }
    public void setData(boolean skip, final String idxstr, String newData, boolean trimNewData){
//        ManageData manData = new ManageData();
//        String fileName = "";
//                    int result = manData.readDataFile(newData, true);
//                    if (result == ManageData.K_SUCCESS_UPDATED) {
//                        fileName = manData.manFile.getAbsolutePath();
//                        // If K_SUCCESS_UPDATED, then man file already copied
////                        copyFilesToProjDir = false;
//                    }
//                    
////                    if (copyFilesToProjDir) {
////                        fileName = copyFileToProjectDirectory(new TFile(fileName));
////                    }    
//                    setData(idxstr, fileName);
//                    changes.firePropertyChange(DataChanged, null, DataChanged);
//                    
        PropertyStackContext.enter(this, idxstr);
        try {
            String oldData;

            if (idxstr.equals(FireProperty)) {
                oldData = ht.get(newData);
                changes.firePropertyChange(newData, null, oldData);
                return;
            }

            if (newData == null) {
                oldData = ht.get(idxstr);
                ht.remove(idxstr);
            } else {
                if (trimNewData) {
                    newData = newData.trim();      //1148, only trim when told to.
                }
                oldData = ht.get(idxstr);
                if (newData.equals(oldData)) {
                    return;
                }
                ht.put(idxstr, newData);
            }
            
           
            if(idxstr.equals("RFD-ManageFile") && runfilebypasscalib && skip){
//                System.out.println("here" + idxstr);
                if(!newData.isEmpty()){
                    oldData = newData;
                    //NOT SURE IF THIS IS SAFE WAY TO SET THE MANAGEMENT FILE EVERY TIME, 
                    //BUT IT WORKS FOR THIS INSTANCE.
                    Weps.getInstance().getAuxPanel().setManageFile(newData, true);
                }
                
//               setData(ManageFile, oldData);
//               Weps.setOldMan(true);
//               changes.firePropertyChange(DataChanged, null, DataChanged);
//               ManageData mand = new ManageData();
//               mand.setUpdateStatus(true);
               
            }else{
            changes.firePropertyChange(idxstr, oldData, newData);  // This is resetting the WEPS GUI mgt name in calibration runs - LEW
            changes.firePropertyChange(DataChanged, null, DataChanged);
            Weps.setOldMan(true);
            }
        } finally {
            PropertyStackContext.exit(this, idxstr);
        }
    }
    public void setData(final String idxstr, String newData, boolean trimNewData) {

        PropertyStackContext.enter(this, idxstr);
        try {
            String oldData;

            if (idxstr.equals(FireProperty)) {
                oldData = ht.get(newData);
                changes.firePropertyChange(newData, null, oldData);
                return;
            }

            if (newData == null) {
                oldData = ht.get(idxstr);
                ht.remove(idxstr);
            } else {
                if (trimNewData) {
                    newData = newData.trim();      //1148, only trim when told to.
                }
                oldData = ht.get(idxstr);
                if (newData.equals(oldData)) {
                    return;
                }
                ht.put(idxstr, newData);
            }
            
           
//           if(idxstr.equals("RFD-ManageFile")){
//               System.out.println("here" + idxstr);
//               
//               
//           }
            changes.firePropertyChange(idxstr, oldData, newData);  // This is resetting the WEPS GUI mgt name in calibration runs - LEW
            changes.firePropertyChange(DataChanged, null, DataChanged);
        } finally {
            PropertyStackContext.exit(this, idxstr);
        }
    }

    public void setData(String idxstr, String newData) {
        setData(idxstr, newData, true);
    }

    public void fireAll() {
        FireAllContext.enter();
        try {
            Enumeration<String> e = ht.keys();
            changes.firePropertyChange(DataChanged, null, "fireall");
            changes.firePropertyChange(LoadData, null, "1");

            while (e.hasMoreElements()) {
                String key = e.nextElement();
                String value = ht.get(key);

                    changes.firePropertyChange(key, null, value);
                }

            changes.firePropertyChange(DataChanged, null, "fireall");
            changes.firePropertyChange(LoadData, null, "2");
        } finally {
            FireAllContext.exit();
        }
    }

    public void fireAll(PropertyChangeListener... listeners) {
        FireAllContext.enter();
        try {
            Enumeration<String> e = ht.keys();

            for (PropertyChangeListener listener : listeners) {
                PropertyChangeEvent event1 = new PropertyChangeEvent(this, DataChanged, null, "fireall");
                PropertyChangeEvent event2 = new PropertyChangeEvent(this, LoadData, null, 1);
                listener.propertyChange(event1);
                listener.propertyChange(event2);

            }
            while (e.hasMoreElements()) {
                String key = e.nextElement();
                String value = ht.get(key);
                PropertyChangeEvent event = new PropertyChangeEvent(this, key, null, value);
                for (PropertyChangeListener listener : listeners) {
                    listener.propertyChange(event);
                }
            }

            for (PropertyChangeListener listener : listeners) {
                PropertyChangeEvent event1 = new PropertyChangeEvent(this, DataChanged, null, "fireall");
                PropertyChangeEvent event2 = new PropertyChangeEvent(this, LoadData, null, 2);
                listener.propertyChange(event1);
                listener.propertyChange(event2);
            }
        } finally {
            FireAllContext.exit();
        }
    }
    
    private String getLineComment(BufferedReader in) throws IOException {
        String temp;
        while ((temp = in.readLine()) != null) {
            if (temp.length() == 0) {
                return temp;
            }
            if (temp.charAt(0) == '#') {
                return temp;
            }
        }
        return null;
    }

    private String getLine(BufferedReader in) throws IOException {
        String temp;
        while ((temp = in.readLine()) != null) {
            if (temp.length() == 0) {
                return temp;
            }
            if (temp.charAt(0) != '#') {
                return temp;
            }
        }
        return null;
    }

    @SuppressWarnings("try")
    public void setRotationYears(String manageFile) {
        //We need to have a file to work with.
        if (manageFile == null || manageFile.equals("none") || manageFile.length() == 0) {
            return;
        }

        try (BufferedReader in = new BufferedReader(new TFileReader(
                new TFile(manageFile)))) {
            String temp;
            while ((temp = in.readLine()) != null) {
                if (temp.startsWith("*START")) {
                    StringTokenizer st = new StringTokenizer(temp);
                    st.nextToken();
                    String rotationYears = st.nextToken().trim();
                    in.close();
                    setData(RunFileData.RotationYears, rotationYears);
                    changes.firePropertyChange(RunFileData.RotationYears, null, rotationYears);
                    return;
                }
            }

            //System.err.println("RFD_sRY: '*START' not found in management file");
            changes.firePropertyChange(RunFileData.RotationYears, null, "1"); // Default value

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

    private void readRunFileBarriers(BufferedReader in) throws java.io.IOException {
        //Awful hack to get the draw field to work. TODO
        changes.firePropertyChange(ResetBarriers, null, null);

        //Initially set all the barrier data to "none"
        setData(BarrierN, "none|0.0|0.0|0.0");
        setData(BarrierS, "none|0.0|0.0|0.0");
        setData(BarrierE, "none|0.0|0.0|0.0");
        setData(BarrierW, "none|0.0|0.0|0.0");

        String temp = getLine(in);
        int barrierNo = 0;
        try { barrierNo = Integer.parseInt(temp.trim()); }
        catch(NumberFormatException nfe) { LOGGER.error(temp.trim() + " could not be converted to int"); }
        // throw away dummy barrier
        if (barrierNo == 0) {

            for (int jdx = 0; jdx < 6; jdx++) {
                getLine(in);
            }
            return;
        }
        String temp1 = getData(SimPoint1);
        String temp2 = getData(SimPoint2);
        StringTokenizer st = new StringTokenizer(temp1, " ");
        String rx1 = st.nextToken();
        double Rx1 = Double.parseDouble(rx1);
        String ry1 = st.nextToken();
        double Ry1 = Double.parseDouble(ry1);
        st = new StringTokenizer(temp2, " ");
        String rx2 = st.nextToken();
        double Rx2 = Double.parseDouble(rx2);
        String ry2 = st.nextToken();
        double Ry2 = Double.parseDouble(ry2);

        for (int idx = 0; idx < barrierNo; idx++) {
            String line = getLine(in);
            st = new StringTokenizer(line, "| ");
            String bx1 = st.nextToken();
            double Bx1 = Double.parseDouble(bx1);
            String by1 = st.nextToken();
            double By1 = Double.parseDouble(by1);
            line = getLine(in);
            st = new StringTokenizer(line, "| ");
            String bx2 = st.nextToken();
            double Bx2 = Double.parseDouble(bx2);
            String by2 = st.nextToken();
            double By2 = Double.parseDouble(by2);
            StringBuilder sb = new StringBuilder(getLine(in).trim());
            for (int jdx = 0; jdx < 3; jdx++) {
                sb.append("|");
                sb.append(getLine(in).trim());
            }
            line = sb.toString();

            if ((Ry1 == By1 && Ry2 == By2) || (Ry1 == By2 && Ry2 == By1)) {
                if (Rx1 == Bx1 || Rx1 == Bx2) {
                    setData(BarrierW, line);
                    //			} else if (bx1.equals(rx2)) {
                } else if (Rx2 == Bx1 || Rx2 == Bx2) {
                    setData(BarrierE, line);
                } else {
                    c_log.logMessage(WepsMessage.warningMessage("Unknown Barrier Position 1 " + line
                            + " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2
                            + " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2));
                }
            } else if ((Rx1 == Bx1 && Rx2 == Bx2) || (Rx1 == Bx2 && Rx2 == Bx1)) {
                if (Ry1 == By1 || Ry1 == By2) {
                    setData(BarrierS, line);
                } else if (Ry2 == By1 || Ry2 == By2) {
                    setData(BarrierN, line);
                } else {
                    c_log.logMessage(WepsMessage.warningMessage("Unknown Barrier Position 2 " + line
                            + " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2
                            + " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2));
                }
            } else {
                c_log.logMessage(WepsMessage.warningMessage("Unknown Barrier Position 3 " + line
                        + " field-bx1:" + bx1 + "   bx2:" + bx2 + "   by1:" + by1 + "  by2:" + by2
                        + " barrier-rx1: " + rx1 + "   rx2:" + rx2 + "  ry1:" + ry1 + "  ry2:" + ry2));
            }
        }

    }

    private void readNotesFile(String runFilePathName) {
        String temp = "";
        StringBuilder sb = new StringBuilder();
        TFile file = new TFile(runFilePathName, NotesFileName);
        BufferedReader in = null;
        try {
            in = new BufferedReader(new TFileReader(file));
            while ((temp = in.readLine()) != null) {
                sb.append(temp.trim() + "\n");
            }
        } catch (IOException e) {
            LOGGER.warn("Error while reading notes file. " + file.getPath());
            JOptionPane.showMessageDialog(null, "Notes file unreadable.",
                    "Notes Warning", JOptionPane.WARNING_MESSAGE);
            setData(NotesText, "");
            return;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                LOGGER.error("Error closing stream. " + file.getPath(), e);
            }
        }
        setData(NotesText, sb.toString());
    }
    
    /**
     * createHTSnapshot & restoreFromSnapshot is a way to "restore" 
     * The current WEPS state. Must create a snapshot first and then restore 
     * from where snapshot was created. -DNA
     */
    private void createHTSnapshot(){
        htSnap.clear();
        htSnap.putAll(ht);
    }
    
    private void restoreFromSnapshot(){
        resetReadContext(htSnap);
        fireAll();
    }

    /**
     * This method reads the data in the RUN file meant for the GUI
     * initialization from the existing set of values and makes it visible on
     * the respective components of the interface.
     *
     * @param runFilePathName The system path to the RUN file from where this
     * data is retrieved.
     */

    void setLockMessage(boolean bool) {
        lockMessage = bool;
    }

    boolean getLockMessage() {
        return lockMessage;
    }

    public void readRunFileOnly (String runFilePathName) {
        enableExternalActions = false;
        c_displayMessages = false;
        readRunFile (runFilePathName, true, false);
    }
    public boolean runfilebypasscalib = false;
    public void readRunFile(String runFilePathName) {
        readRunFile(runFilePathName, false);
    }
    public void readRunFile(String runFilePathName, boolean bypassUpdate) {
        if(runfilebypasscalib){bypassUpdate = true;}
        readRunFile (runFilePathName, bypassUpdate, false);
    }
    
    public void readRunFile(String runFilePathName, boolean bypassUpdate, boolean copyFilesToProjDir) {   
        if(runfilebypasscalib){bypassUpdate = true;}
        if (currentRanFiles.contains(runFilePathName)) {
            //System.out.println("run contained: " + runFilePathName);
            //System.out.println("run no longer eligible for error message");
        } else {
            currentRanFiles.add(runFilePathName);
            setLockMessage(true);
        }

        LoadingContext.enter();
        RelativeFileContext.enter(new TFile(runFilePathName));
        //create "snapshot"here
        createHTSnapshot();
        initialize();//this is the keyy must save everything then initialize
        clearBean();
        Hashtable<String,String> readmap = new Hashtable<String,String>();
        
        try {
            //getBean().setLoading(true);
            c_log.clear();

            BufferedReader in = null;
            try {
                fileObject = new TFile(runFilePathName, WepsRun);
                if (!fileObject.exists()) {
                    LOGGER.warn("Run File \"" + fileObject.getAbsolutePath() + "\" does not exist.");
                    return;
                }
                in = new BufferedReader(new TFileReader(fileObject));
                double version = 1.00;  //Default when the version of the file is not included.

                String firstLine = in.readLine();
                if (firstLine == null) {
                    return;
                }
                firstLine = firstLine.trim();
                if (firstLine.startsWith(VERSION_MARKER)) {
                    firstLine = firstLine.replace(VERSION_MARKER, "");
                    version = Double.parseDouble(firstLine);
                }
                String tmp;
                tmp = getLine(in);
                if (tmp.length() > 65) {
//                    setData(UserName, tmp.substring(0, 64));
                    readmap.put(UserName, tmp.substring(0,64));
                } else {
//                    setData(UserName, tmp);
                    readmap.put(UserName, tmp);
                }
                {
                    String temp = getLine(in);
                    StringTokenizer st = new StringTokenizer(temp, "|");
                    if (st.countTokens() < 3) {
                        if (temp.length() > 10) {
//                            setData(FarmId, temp.substring(0, 9));
                            readmap.put(FarmId, temp.substring(0, 9));
                            
                        } else {
//                            setData(FarmId, temp);
                            readmap.put(FarmId, temp);
                        }
//                        setData(TractId, "");
                        readmap.put(TractId, "");
                        
//                        setData(FieldId, "");
                        readmap.put(FieldId, "");
//                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
                        readmap.put(RunFileData.RunTypeDisp, ConfigData.Dates);
                    } else if (st.countTokens() == 3) {
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
//                            setData(FarmId, tmp.substring(0, 9));
                            readmap.put(FarmId, tmp.substring(0,9));
                        } else {
//                            setData(TractId, tmp);
                            readmap.put(TractId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
//                            setData(FieldId, tmp.substring(0, 9));
                            readmap.put(FieldId, tmp.substring(0,9));
                        } else {
//                            setData(FieldId, tmp);
                            readmap.put(FieldId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
//                            setData(FieldId, tmp.substring(0, 9));
                            readmap.put(FieldId, tmp.substring(0,9));
                        } else {
//                            setData(FieldId, tmp);
                            readmap.put(FieldId, tmp);
                        }
//                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
                        readmap.put(RunFileData.RunTypeDisp, ConfigData.Dates);
                    } else {
                        //					try {
                        String tm = st.nextToken().trim();
                        if (tm.length() > 10) {
//                            setData(FarmId, tm.substring(0, 9));
                            readmap.put(FarmId, tm.substring(0,9));
                        } else {
//                            setData(FarmId, tm);
                            readmap.put(FarmId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
//                            setData(TractId, tm.substring(0, 9));
                            readmap.put(TractId, tm.substring(0,9));
                        } else {
//                            setData(TractId, tm);
                            readmap.put(TractId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
//                            setData(FieldId, tm.substring(0, 9));
                            readmap.put(FieldId, tm.substring(0,9));
                        } else {
//                            setData(FieldId, tm);
                            readmap.put(FieldId, tm);
                        }
                        String type = st.nextToken().trim();
//                        setData(RunFileData.RunTypeDisp, type);
                        readmap.put(RunFileData.RunTypeDisp, type);
//                        setData(RotationYears, st.nextToken());
                        readmap.put(RotationYears, st.nextToken());
//                        setData(CycleCount, st.nextToken());
                        readmap.put(CycleCount, st.nextToken());
                    }
                }

                String siteString = getLine(in);
                if (version < VERSION_LOCPANEL_SITE) {
                    //old site format
                    usda.weru.weps.location.Site<?> site = upgradeSiteString(siteString);
//                    setData(Site, site != null ? site.toString() : siteString);
                    readmap.put(Site, site != null ? site.toString() : siteString);
                } else {
//                    setData(Site, siteString);
                    readmap.put(Site, siteString);
                }

                {
                    //String initializationData = getLine(in);
                    //setData(LatitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Latitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    //temp = getLine(in);
                    //setData(LongitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Longitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    String latStr = getLine(in);
                    String longStr = getLine(in);
                   // MEH need to let the lat/lon set go through
                    // so it is there for the cligen / windgen control (below).
                    // But put it in the readmap also so that restoreFromSnapshot()
                    // can use it.
                    setData(StrLatLong, latStr.trim() + ";" + longStr.trim());
                    readmap.put(StrLatLong, latStr.trim() + ";" + longStr.trim());
                    LatLong latlong = LatLong.valueOf(Double.parseDouble(latStr), Double.parseDouble(longStr), USCustomary.DEGREE_ANGLE);
                    GISLookup<Site<?>> lookup
                            = GISData.getInstance().<Site<?>>getLookup(Caster.<Class<Site<?>>>cast(Site.class));
                    List<Site<?>> results = lookup.lookup(latlong);

                    if (results.size() > 0) {
                        Comparator<Site<?>> c = new Site.LevelComparator();
                        Collections.sort(results, c);
                        Site<?> mostDetail = results.get(results.size() - 1);
                        String FIPS = mostDetail.getFIPSCode();
                        if (FIPS.substring(0, 2).equals("US")) {
                            String[] FIPSSplit = FIPS.split("_");
                            FIPS = "FIPS:" + FIPSSplit[0] + "-" + FIPSSplit[2];
                        } else {
                            FIPS = "FIPS:" + FIPS;
                        }
                        if (getLockMessage()) {
                            String[] currentRun = runFilePathName.split("\\\\", -1);
                            int runName = currentRun.length - 1;
                            //System.out.println("checking current run:");
                            //System.out.println(currentRun[runName]);
                            //System.out.println("******* checking FIPS.equals(siteString) *******");
                            setLockMessage(false);
                            if (!FIPS.equals(siteString)) {
                                
                                
                                if (continueToShowErrorMessage_latLon) {
                                    //set lock to only print unadded runfilepath
//                                    JOptionPane.showMessageDialog(null, "Site information didn't match Latitude Longitude.\n"
//                                            + "Latitude Longitude overriding the site information.",
//                                            "Location Warning", JOptionPane.WARNING_MESSAGE);
                                    int rtrnopt = JOptionPane.showConfirmDialog(null, 
                                            "The Site string in the weps.run file did not match the expected FIPS.\n" +
                                            "FIPS (expected):  " + FIPS + "\n" +
                                            "SITE (from file): " + siteString + "\n" +
                                            "FILE: " + currentRun[runName] + "\n\n" +
                                            "This may cause errors when viewing/using this run.\n\n" +
                                            "It is likely this error message is caused by an old Run file\n" +
                                            "being used in this action or in the path you selected for your Runs\n" +
                                            "directory location. You can make this Run again with the same input\n " +
                                            "files and create a current run file with updated information.\n\n" +
                                            "This error may appear everytime these old files\n" +
                                            "are scanned, would you like to see this error again if another Latitude\n" +
                                            "Longitude mismatch occurs?", "Location Warning", JOptionPane.YES_NO_OPTION);
                                    continueToShowErrorMessage_latLon = rtrnopt == JOptionPane.NO_OPTION ? false : true;
                                }
//                                setData(Site, FIPS);
                                readmap.put(Site, FIPS);
                            }
                        }
                    } else {
                    }
                }

                // This string is used to store the value of the Run's elevation value
                restoreRunElevation = getLine(in);
//                setData(Elevation, restoreRunElevation);
                readmap.put(Elevation, restoreRunElevation);

                if (version >= VERSION_LOCPANEL_REWRITE) {
                    //new format delegated to StationModeHandlers
                    //cligen
                    String cligenLine = getLine(in);
                    int cligenModeIndex = cligenLine.indexOf("|");
                    String cligenModeText = cligenLine.substring(0, cligenModeIndex);
                    String cligenText = cligenLine.length() > cligenModeIndex
                            ? cligenLine.substring(cligenModeIndex + 1) : null;

                    StationMode cligenMode = StationMode.parse(cligenModeText);
                    Station cligenStation = StationUtil.deserializeStation(cligenText);

//                    if (enableExternalActions) {
                        getBean().setCligenStationMode(cligenMode);
                        getBean().setCligenStation(cligenStation);
//                    }

                    //windgen
                    String windgenLine = getLine(in);
                    int windgenModeIndex = windgenLine.indexOf("|");
                    String windgenModeText = windgenLine.substring(0, windgenModeIndex);
                    String windgenText = windgenLine.length() > windgenModeIndex
                            ? windgenLine.substring(windgenModeIndex + 1) : null;

                    StationMode windgenMode = StationMode.parse(windgenModeText);
                    Station windgenStation = StationUtil.deserializeStation(windgenText);

//                    if (enableExternalActions) {
                        getBean().setWindgenStationMode(windgenMode);
                        getBean().setWindgenStation(windgenStation);
//                    }

                } else {
                    //Handle the old station format, only supports choice (0) or file (1) or interpolated for windgen
                    //cligen                    
                    try {
                        String cligenLine = getLine(in);
                        String cligenParts[] = cligenLine.split("\\|");
                        StationMode cligenMode = StationMode.parse(cligenParts[3]);

                        getBean().setCligenStationMode(cligenMode);

                        if (StationMode.Choice == cligenMode) {
                            //choice station
                            String name = cligenParts[0];
                            long id = Long.valueOf(cligenParts[1].trim());
                            long state = Long.valueOf(cligenParts[2].trim());
                            CligenStation station = CligenDataModel.getInstance().getStation(state, id);
                            if (station == null) {
                                LOGGER.warn("Unable to find cligen record in database. State: " + state + ", Id: " + id);
                                station = new CligenStation(name, state, id);
                            }

                            getBean().setCligenStation(station);

                        } else if (StationMode.File == cligenMode) {
                            //file station
                            String name = cligenParts[0];
                            TFile file = new TFile(runFilePathName, name);
                            FileStation station = new FileStation(file);
                            getBean().setCligenStation(station);

                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old cligen station.", e);
                        getBean().setCligenStation(null);
                    }

                    //windgen                    
                    try {
                        String windgenLine = getLine(in);
                        String windgenParts[] = windgenLine.split("\\|");
                        StationMode windgenMode = StationMode.parse(windgenParts[2]);
//                        getBean().getw
                        getBean().setWindgenStationMode(windgenMode);

                        if (StationMode.Choice == windgenMode) {
                            //choice station
                            String name = windgenParts[0];
                            if (windgenParts[1].startsWith("I~")) {
                                //this was an interpolated station
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                long id = Long.valueOf(windgenParts[1].trim());
                                WindgenStation station = WindgenDataModel.getInstance().getStation(id);
                                if (station == null) {
                                    LOGGER.warn("Unable to find windgen record in database. Id: " + id);
                                    station = new WindgenStation(null, id, null, null, name);
                                }
                                getBean().setWindgenStation(station);
                            }

                        } else if (StationMode.File == windgenMode) {
                            //file station
                            String name = windgenParts[0];
                            name = name != null ? name.trim() : name;
                            if ("Interpolated".equalsIgnoreCase(name)) {
                                //handle an interpolated file
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                TFile file = new TFile(runFilePathName, name);
                                FileStation station = new FileStation(file);
                                getBean().setWindgenStation(station);
                            }
                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old windgen station.", e);
                        getBean().setWindgenStation(null);
                    }

                }

//                setData(StartDate, getLine(in));
                readmap.put(StartDate, getLine(in));
//                setData(EndDate, getLine(in));
                readmap.put(EndDate, getLine(in));
//                setData(TimeSteps, getLine(in));
                readmap.put(TimeSteps, getLine(in));
//                setData(ClimateFile, getLine(in));
                readmap.put(ClimateFile, getLine(in));
//                setData(WindFile, getLine(in));
                readmap.put(WindFile, getLine(in));
//                setData(SubDailyFile, getLine(in));
                readmap.put(SubDailyFile, getLine(in));
                String fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFilePathName, fileName).getAbsolutePath();
                }
                final TFile soilFile = new TFile(fileName);
                if (!soilFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced soil file is missing.\n"
                                    + soilFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

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

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
//                    setData(SoilFile, "");
                    readmap.put(SoilFile, "");
                } else {
                    if (copyFilesToProjDir) {
                        // Check for file in project directory
                        fileName = copyFileToProjectDirectory(new TFile(fileName));
                    }                    
//                    setData(SoilFile, fileName);
                    readmap.put(SoilFile, fileName);
                }

                fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFilePathName, fileName).getAbsolutePath();
                }
                final TFile manFile = new TFile(fileName);
                if (!manFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced management file is missing.\n"
                                    + manFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

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

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
//                    setData(ManageFile, "");
                    readmap.put(ManageFile, "");
                } else {
                    
                    // if the man file needs to be updated,
                    // the update will move it to projects dir.
                    // So, do update now, before setData,
                    // then setData can be called with updated path
                    ManageData manData = new ManageData();
                    int result = manData.readDataFile(fileName, bypassUpdate);
                    if (result == ManageData.K_SUCCESS_UPDATED) {
                        fileName = manData.manFile.getAbsolutePath();
                        // If K_SUCCESS_UPDATED, then man file already copied
                        copyFilesToProjDir = false;
                    }
                    
                    if (copyFilesToProjDir) {
                        fileName = copyFileToProjectDirectory(new TFile(fileName));
                    }    
                    // if they have chosen not to update from it.
                    if(result == ManageData.K_FAILURE_OLD ){
                        restoreFromSnapshot();
                        return;
                    } else {
                        readmap.put(ManageFile, fileName);
                    }
                } 
                resetReadContext(readmap);
//                restoreFromSnapshot();
                setData(OutputFile, getLine(in));
                setData(ReportForm, getLine(in));
                setData(OutputPeriod, getLine(in));
                // skip over these two for now
                //setData(SubmodelOutput, getLine(in));
                //setData(DebugOutput, getLine(in));
                getLine(in);
                getLine(in);
                setData(RegionAngle, getLine(in));
                setData(SimPoint1, getLine(in));
                setData(SimPoint2, getLine(in));
                setData(Scales, getLine(in));
                setData(AccNo, getLine(in));
                setData(AccPoint1, getLine(in));
                setData(AccPoint2, getLine(in));
                setData(SubregionNo, getLine(in));
                setData(SubPoint1, getLine(in));
                setData(SubPoint2, getLine(in));
                {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(AverageSlope, val);
                }
                readRunFileBarriers(in);

                //Shape and radius information used by the user interface to approximate a rectangular field shape.
                // Placed in try in case the run file does not have the shape fields.
                try {
                    setData(Shape, getLine(in));
                } catch (NullPointerException e) {
                    setData(Shape, "rectangle");
                }

                //consume the radius line**********************************************************************************************************************************************
                try {
                    setData(Radius, getLine(in));
                } catch (NullPointerException e) {
                    setData(Radius, "0");
                }
                //getLine(in);

                //Only read the value if the correct version.
                if (version >= VERSION_WATER_EROSION) {
                    double d = 0;
                    String temp = getLine(in);
                    try {
                        temp = temp != null ? temp.trim() : null;
                        if (temp != null) {
                            d = Double.parseDouble(temp);
                        }
                    } catch (NumberFormatException e) {
                        LOGGER.debug("Unable to parse water erosion value: " + temp);
                    }

                    setData(WaterErosionLoss, String.valueOf(d));
                } else {
                    setData(WaterErosionLoss, "0");
                }

                //Only read the value if the correct version.
                if (version >= VERSION_ROCK_FRAGMENTS) {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(SoilRockFragments, val);
                } else {
                    setData(SoilRockFragments, "-1");
                }
                
//                String slpVal = getLineComment(in);//DNA
//                setData(AverageSlopeField,slpVal.split(" ")[3]);
                
//                String fragVal = getLineComment(in);//DNA
//                setData(SoilRockFragmentsField,fragVal.split(" ")[3]);

            } catch (IOException e) {
                LOGGER.error("unable to read run file: \"" + runFilePathName + "\"", e);
            } catch (java.lang.NullPointerException f) {
                JOptionPane.showMessageDialog(null,
                        "Error loading run file",
                        "Error (RFD-001)",
                        JOptionPane.ERROR_MESSAGE);
                f.printStackTrace();
                return;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                    LOGGER.error("Error closing file stream.", e);
                }
            }
            readNotesFile(runFilePathName);
            fixUpData();
            if (enableExternalActions) {
                changes.firePropertyChange(DataChanged, null, "xxx");
                fireAll();
            }
            setData(Elevation, restoreRunElevation);

            //fire that we have finished loading the data
            //getBean().setLoading(false);
        } finally {
            RelativeFileContext.exit();
            LoadingContext.exit();
        }

    }
    
    private void resetReadContext(Hashtable<String, String> readContent){
        for (Map.Entry<String, String> entry : readContent.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            setData(key,value); 
        }
    }
    
    private String copyFileToProjectDirectory(File checkFile) {
        boolean res = true;
        String checkFileName =  checkFile.getName();
        File checkFileProjDir = new File (this.curProj, checkFileName);
        
         try {             
            // Check that path exists
            if (checkFileProjDir.exists()) {
                // always copy management file from Runs dir --> Project dir
                //if trying to write over a read only let the user know
                if(Util.isReadOnly(checkFileProjDir)){
                    int response =  JOptionPane.showConfirmDialog(null,"Restore is attempting to write over the read-only project file \"" +checkFileProjDir.getAbsolutePath() +"\". Proceed with this overwrite?","proceed?",JOptionPane.YES_NO_OPTION);
                    if(response == 0){
                        //yes means 0
                        checkFileProjDir.setWritable(true);
                    } else {
                        res = false;
                    }
                }
            }
            new TFile(checkFile).cp(checkFileProjDir);
            
        } catch (Exception exception) { // To not brick the reading process if fails...
            System.out.println(exception.toString());
            System.out.println("Exception occured while trying to copy management file over to project directory.");
            res = false;
        }
         return res ? checkFileProjDir.getAbsolutePath() : "";
    }

    /**
     * This method reads the data in the RUN file meant for the WEPS DIFF from
     * the existing set of values and makes it visible on the respective
     * components of the interface.
     *
     * @param runFile The system path to the RUN file from where this data is
     * retrieved.
     */
    public void readRunFile(TFile runFile) {
        LoadingContext.enter();
        RelativeFileContext.enter(runFile.getParentFile());
        initialize();
        clearBean();
        fileObject = runFile;
        
        try {
            //getBean().setLoading(true);
            c_log.clear();

            BufferedReader in = null;
            try {
                if (!runFile.exists()) {
                    LOGGER.warn("Run File \"" + runFile.getAbsolutePath() + "\" does not exist.");
                    return;
                }
                in = new BufferedReader(new TFileReader(runFile));
                double version = 1.00;  //Default when the version of the file is not included.

                String firstLine = in.readLine();
                if (firstLine == null) {
                    return;
                }
                firstLine = firstLine.trim();
                if (firstLine.startsWith(VERSION_MARKER)) {
                    firstLine = firstLine.replace(VERSION_MARKER, "");
                    version = Double.parseDouble(firstLine);
                }
                String tmp;
                tmp = getLine(in);
                if (tmp.length() > 65) {
                    setData(UserName, tmp.substring(0, 64));
//                    readmap.put(UserName, tmp.substring(0,64));
                } else {
                    setData(UserName, tmp);
//                    readmap.put(UserName,tmp);
                }
                {
                    String temp = getLine(in);
                    StringTokenizer st = new StringTokenizer(temp, "|");
                    if (st.countTokens() < 3) {
                        if (temp.length() > 10) {
                            setData(FarmId, temp.substring(0, 9));
//                            readmap.put(FarmId, temp.substring(0, 9));
                        } else {
                            setData(FarmId, temp);
//                            readmap.put(FarmId, temp);
                        }
                        setData(TractId, "");
//                        readmap.put(TractId,"");
                        setData(FieldId, "");
//                        readmap.put(FieldId,"");
                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
//                        readmap.put(RunFileData.RunTypeDisp, ConfigData.Dates);
                        //					changes.firePropertyChange(RunFileData.RunTypeDisp, RunType,
                        //										 ConfigData.Dates);
                    } else if (st.countTokens() == 3) {
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FarmId, tmp.substring(0, 9));
//                            readmap.put(FarmId, tmp.substring(0,9));
                        } else {
                            setData(TractId, tmp);
//                            readmap.put(TractId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FieldId, tmp.substring(0, 9));
//                            readmap.put(FieldId, tmp.substring(0,9));
                        } else {
                            setData(FieldId, tmp);
//                            readmap.put(FieldId, tmp);
                        }
                        tmp = st.nextToken().trim();
                        if (tmp.length() > 10) {
                            setData(FieldId, tmp.substring(0, 9));
//                            readmap.put(FieldId,tmp.substring(0,9));
                        } else {
                            setData(FieldId, tmp);
//                            readmap.put(FieldId,tmp);
                        }
                        setData(RunFileData.RunTypeDisp, ConfigData.Dates);
//                        readmap.put(RunFileData.RunTypeDisp, ConfigData.Dates);
                        //					changes.firePropertyChange(RunFileData.RunTypeDisp, RunType,
                        //										 st.nextToken().trim());

                        //					setData(RunFileData.RunTypeDisp, type);
                    } else {
                        //					try {
                        String tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(FarmId, tm.substring(0, 9));
//                            readmap.put(FarmId, tm.substring(0,9));
                        } else {
                            setData(FarmId, tm);
//                            readmap.put(FarmId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(TractId, tm.substring(0, 9));
//                            readmap.put(TractId, tm.substring(0,9));
                        } else {
                            setData(TractId, tm);
//                            readmap.put(TractId, tm);
                        }
                        tm = st.nextToken().trim();
                        if (tm.length() > 10) {
                            setData(FieldId, tm.substring(0, 9));
//                            readmap.put(FieldId, tm.substring(0,9));
                        } else {
                            setData(FieldId, tm);
//                            readmap.put(FieldId, tm);
                        }
                        String type = st.nextToken().trim();
                        setData(RunFileData.RunTypeDisp, type);
//                        readmap.put(RunFileData.RunTypeDisp, type);
                        setData(RotationYears, st.nextToken());
//                        readmap.put(RotationYears, st.nextToken());
                        setData(CycleCount, st.nextToken());
//                        readmap.put(CycleCount, st.nextToken());
                        //					} catch (ArrayIndexOutOfBounds e) {
                        //						//System.err.println("RFD_rRF: too few tokens in id line (should be 6) " +
                        //										   initializationData);
                        //					}
                    }
                }

                String siteString = getLine(in);
                if (version < VERSION_LOCPANEL_SITE) {
                    //old site format
                    usda.weru.weps.location.Site<?> site = upgradeSiteString(siteString);
                    setData(Site, site != null ? site.toString() : siteString);
//                    readmap.put(Site, site != null ? site.toString() : siteString);
                } else {
                    setData(Site, siteString);
//                    readmap.put(Site, siteString);
                }

                {
                    //String initializationData = getLine(in);
                    //setData(LatitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Latitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    //temp = getLine(in);
                    //setData(LongitudeSign, initializationData.startsWith("-") ? "-" : "+");
                    // Added below code for second conditional statement 01/16/2004
                    //setData(Longitude, initializationData.substring(initializationData.startsWith("-") ? 1
                    //: ( initializationData.startsWith("+") ? 1 : 0 ) ));
                    String latStr = getLine(in);
                    String longStr = getLine(in);
                    setData(StrLatLong, latStr.trim() + ";" + longStr.trim());
//                    readmap.put(StrLatLong, latStr.trim() + ";" + longStr.trim());
                    LatLong latlong = LatLong.valueOf(Double.parseDouble(latStr), Double.parseDouble(longStr), USCustomary.DEGREE_ANGLE);
                    GISLookup<Site<?>> lookup
                            = GISData.getInstance().<Site<?>>getLookup(Caster.<Class<Site<?>>>cast(Site.class));
                    List<Site<?>> results = lookup.lookup(latlong);

                    if (results.size() > 0) {
                        Comparator<Site<?>> c = new Site.LevelComparator();
                        Collections.sort(results, c);
                        Site<?> mostDetail = results.get(results.size() - 1);
                        String FIPS = mostDetail.getFIPSCode();
                        if (FIPS.substring(0, 2).equals("US")) {
                            String[] FIPSSplit = FIPS.split("_");
                            FIPS = "FIPS:" + FIPSSplit[0] + "-" + FIPSSplit[2];
                        } else {
                            FIPS = "FIPS:" + FIPS;
                        }
                        if (!FIPS.equals(siteString)) {
                            JOptionPane.showMessageDialog(null, "Site information didn't match Latitude Longitude.\n"
                                    + "Latitude Longitude overriding the site information.",
                                    "Location Warning", JOptionPane.WARNING_MESSAGE);
                            setData(Site, FIPS);
//                            readmap.put(Site, FIPS);
                        }
                    } else {
                    }
                }

                // This string is used to store the value of the Run's elevation value
                restoreRunElevation = getLine(in);
                setData(Elevation, restoreRunElevation);
//                readmap.put(Elevation, restoreRunElevation);
                if (version >= VERSION_LOCPANEL_REWRITE) {
                    //new format delegated to StationModeHandlers
                    //cligen
                    String cligenLine = getLine(in);
                    int cligenModeIndex = cligenLine.indexOf("|");
                    String cligenModeText = cligenLine.substring(0, cligenModeIndex);
                    String cligenText = cligenLine.length() > cligenModeIndex
                            ? cligenLine.substring(cligenModeIndex + 1) : null;

                    StationMode cligenMode = StationMode.parse(cligenModeText);
                    Station cligenStation = StationUtil.deserializeStation(cligenText);

                    getBean().setCligenStationMode(cligenMode);
                    getBean().setCligenStation(cligenStation);

                    //windgen
                    String windgenLine = getLine(in);
                    int windgenModeIndex = windgenLine.indexOf("|");
                    String windgenModeText = windgenLine.substring(0, windgenModeIndex);
                    String windgenText = windgenLine.length() > windgenModeIndex
                            ? windgenLine.substring(windgenModeIndex + 1) : null;

                    StationMode windgenMode = StationMode.parse(windgenModeText);
                    Station windgenStation = StationUtil.deserializeStation(windgenText);

                    getBean().setWindgenStationMode(windgenMode);
                    getBean().setWindgenStation(windgenStation);

                } else {
                    //Handle the old station format, only supports choice (0) or file (1) or interpolated for windgen
                    //cligen                    
                    try {
                        String cligenLine = getLine(in);
                        String cligenParts[] = cligenLine.split("\\|");
                        StationMode cligenMode = StationMode.parse(cligenParts[3]);

                        getBean().setCligenStationMode(cligenMode);

                        if (StationMode.Choice == cligenMode) {
                            //choice station
                            String name = cligenParts[0];
                            long id = Long.valueOf(cligenParts[1].trim());
                            long state = Long.valueOf(cligenParts[2].trim());
                            CligenStation station = CligenDataModel.getInstance().getStation(state, id);
                            if (station == null) {
                                LOGGER.warn("Unable to find cligen record in database. State: " + state + ", Id: " + id);
                                station = new CligenStation(name, state, id);
                            }

                            getBean().setCligenStation(station);

                        } else if (StationMode.File == cligenMode) {
                            //file station
                            String name = cligenParts[0];
                            TFile file = new TFile(runFile.getParentFile().getAbsolutePath(), name);
                            FileStation station = new FileStation(file);
                            getBean().setCligenStation(station);

                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old cligen station.", e);
                        getBean().setCligenStation(null);
                    }

                    //windgen                    
                    try {
                        String windgenLine = getLine(in);
                        String windgenParts[] = windgenLine.split("\\|");
                        StationMode windgenMode = StationMode.parse(windgenParts[2]);

                        getBean().setWindgenStationMode(windgenMode);

                        if (StationMode.Choice == windgenMode) {
                            //choice station
                            String name = windgenParts[0];
                            if (windgenParts[1].startsWith("I~")) {
                                //this was an interpolated station
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                long id = Long.valueOf(windgenParts[1].trim());
                                WindgenStation station = WindgenDataModel.getInstance().getStation(id);
                                if (station == null) {
                                    LOGGER.warn("Unable to find windgen record in database. Id: " + id);
                                    station = new WindgenStation(null, id, null, null, name);
                                }
                                getBean().setWindgenStation(station);
                            }

                        } else if (StationMode.File == windgenMode) {
                            //file station
                            String name = windgenParts[0];
                            name = name != null ? name.trim() : name;
                            if ("Interpolated".equalsIgnoreCase(name)) {
                                //handle an interpolated file
                                getBean().setWindgenStationMode(StationMode.Interpolated);
                                getBean().setWindgenStation(new InterpolatedStation(getBean().getLatLong()));
                            } else {
                                TFile file = new TFile(runFile.getParentFile().getAbsolutePath(), name);
                                FileStation station = new FileStation(file);
                                getBean().setWindgenStation(station);
                            }
                        } else {
                            //really not supposed to get here.
                        }
                    } catch (IOException | NumberFormatException e) {
                        LOGGER.warn("Unable to read old windgen station.", e);
                        getBean().setWindgenStation(null);
                    }

                }

                setData(StartDate, getLine(in));
//                readmap.put(StartDate, getLine(in));
                setData(EndDate, getLine(in));
//                readmap.put(EndDate, getLine(in));
                setData(TimeSteps, getLine(in));
//                readmap.put(TimeSteps, getLine(in));
                setData(ClimateFile, getLine(in));
//                readmap.put(ClimateFile, getLine(in));
                setData(WindFile, getLine(in));
//                readmap.put(WindFile, getLine(in));
                setData(SubDailyFile, getLine(in));
//                readmap.put(SubDailyFile, getLine(in));
                String fileName = getLine(in);
                
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFile.getParentFile().getAbsolutePath(), fileName).getAbsolutePath();
                }
                final TFile soilFile = new TFile(fileName);
                if (!soilFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced soil file is missing.\n"
                                    + soilFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

                                @Override
                                public int getMaxCharactersPerLineCount() {
                                    return 80;
                                }
                            };
                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
                    setData(SoilFile, "");
//                    readmap.put(SoilFile, "");
                } else {
                    setData(SoilFile, fileName);
//                    readmap.put(SoilFile, fileName);
                    // Check that soil file is present in Project Directory
                    copyFileToProjectDirectory(soilFile);
                }

                fileName = getLine(in);
                if (!(new TFile(fileName)).isAbsolute()) {
                    fileName = new TFile(runFile.getParentFile().getAbsolutePath(), fileName).getAbsolutePath();
                }
                final TFile manFile = new TFile(fileName);
                if (!manFile.exists()) {
                    ExceptionEventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            JOptionPane pane = new JOptionPane("The referenced management file is missing.\n"
                                    + manFile.getAbsolutePath(), JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

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

                            JDialog dialog = pane.createDialog("Loading Run");
                            dialog.setVisible(true);
                        }
                    });
                    setData(ManageFile, "");
//                    readmap.put(ManageFile, "");
                } else {
                    setData(ManageFile, fileName);
//                    readmap.put(ManageFile, fileName);
                    // Check that managment file is present in Project Directory
                    copyFileToProjectDirectory(manFile);
                }

                setData(OutputFile, getLine(in));
                setData(ReportForm, getLine(in));
                setData(OutputPeriod, getLine(in));
                // skip over these two for now
                //setData(SubmodelOutput, getLine(in));
                //setData(DebugOutput, getLine(in));
                getLine(in);
                getLine(in);
                setData(RegionAngle, getLine(in));
                setData(SimPoint1, getLine(in));
                setData(SimPoint2, getLine(in));
                setData(Scales, getLine(in));
                setData(AccNo, getLine(in));
                setData(AccPoint1, getLine(in));
                setData(AccPoint2, getLine(in));
                setData(SubregionNo, getLine(in));
                setData(SubPoint1, getLine(in));
                setData(SubPoint2, getLine(in));
                {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(AverageSlope, val);
                }
                readRunFileBarriers(in);

                //Shape and radius information used by the user interface to approximate a rectangular field shape.
                // Placed in try in case the run file does not have the shape fields.
                try {
                    setData(Shape, getLine(in));
                } catch (NullPointerException e) {
                    setData(Shape, "rectangle");
                }

                //consume the radius line
                getLine(in);

                //Only read the value if the correct version.
                if (version >= VERSION_WATER_EROSION) {
                    double d = 0;
                    String temp = getLine(in);
                    try {
                        temp = temp != null ? temp.trim() : null;
                        if (temp != null) {
                            d = Double.parseDouble(temp);
                        }
                    } catch (NumberFormatException e) {
                        LOGGER.debug("Unable to parse water erosion value: " + temp);
                    }

                    setData(WaterErosionLoss, String.valueOf(d));
                } else {
                    setData(WaterErosionLoss, "0");
                }

                //Only read the value if the correct version.
                if (version >= VERSION_ROCK_FRAGMENTS) {
                    String val = getLine(in);
                    if(val.trim().startsWith("-1")) val = "-1";
                    setData(SoilRockFragments, val);
                } else {
                    setData(SoilRockFragments, "-1");
                }
//                String rfdval = getLine(in);//DNA
//                setData(SoilRockFragmentsField, rfdval);

            } catch (IOException e) {
                LOGGER.error("unable to read run file: \"" + runFile.getParentFile().getAbsolutePath() + "\"", e);
            } catch (java.lang.NullPointerException f) {
                JOptionPane.showMessageDialog(null,
                        "Error loading run file",
                        "Error (RFD-001)",
                        JOptionPane.ERROR_MESSAGE);
                f.printStackTrace();
                return;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException e) {
                    LOGGER.error("Error closing file stream.", e);
                }
            }
            readNotesFile(runFile.getParentFile().getAbsolutePath());
            fixUpData();
            changes.firePropertyChange(DataChanged, null, "xxx");
            fireAll();
            setData(Elevation, restoreRunElevation);

            //fire that we have finished loading the data
            //getBean().setLoading(false);
        } finally {
            RelativeFileContext.exit();
            LoadingContext.exit();
        }

    }

    private void fixUpData() {

        /* add additional factors */
        String temp1 = getData(SimPoint1);
        String temp2 = getData(SimPoint2);
        double x1 = 0.0;
        double y1 = 0.0;
        double x2 = 0.0;
        double y2 = 0.0;

        StringTokenizer st = new StringTokenizer(temp1);
        try {
            x1 = Double.parseDouble(st.nextToken());
            y1 = Double.parseDouble(st.nextToken());
            st = new StringTokenizer(temp2);
            x2 = Double.parseDouble(st.nextToken());
            y2 = Double.parseDouble(st.nextToken());
        } catch (NumberFormatException e) {
            //System.err.println("fUD: " + e);
            x1 = 0.0;
            y1 = 0.0;
            x2 = 0.0;
            y2 = 0.0;
        }
        double Xlen = Math.abs(x1 - x2);
        double Ylen = Math.abs(y1 - y2);

        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(1);
        nf.setGroupingUsed(false);

        setData(XLength, nf.format(Xlen));
        setData(YLength, nf.format(Ylen));
    }

    private String makeBarrier(String barPos, String barData) {

        if (barPos.equals(BarrierD)) {
            return "0.0 0.0" + java.lang.System.getProperty("line.separator")
                    + "0.0 0.0" + java.lang.System.getProperty("line.separator")
                    + "none" + java.lang.System.getProperty("line.separator")
                    + "0.0" + java.lang.System.getProperty("line.separator")
                    + "0.0" + java.lang.System.getProperty("line.separator")
                    + "0.0";
        }

        // get points for sim region
        String temp1 = getData(SimPoint1);
        String temp2 = getData(SimPoint2);
        double x1;
        double y1;
        double x2;
        double y2;

        StringTokenizer st = new StringTokenizer(temp1);
        try {
            x1 = Double.parseDouble(st.nextToken());
            y1 = Double.parseDouble(st.nextToken());
            st = new StringTokenizer(temp2);
            x2 = Double.parseDouble(st.nextToken());
            y2 = Double.parseDouble(st.nextToken());
        } catch (NumberFormatException e) {
            //System.err.println("RFD_mB: " + e);
            x1 = 0.0;
            y1 = 0.0;
            x2 = 0.0;
            y2 = 0.0;
            return "Error in makeBarrier -- can't get field dimensions";
        }

        st = new StringTokenizer(barData, "|");
        String type = st.nextToken();
        double widthDouble = 0.0;
        String height = st.nextToken();
        String width = st.nextToken();
        try {
            widthDouble = Double.parseDouble(width);
        } catch (NumberFormatException e) {
            //System.err.println("RFD_mB: " + e);
        }
        String porosity = st.nextToken();
        String x1s = "0.0";
        String x2s = "0.0";
        String y1s = "0.0";
        String y2s = "0.0";

        NumberFormat nf = NumberFormat.getNumberInstance();

        /* Since the fraction digits for the Simulation region co-ordinates is 2,
         ** the barrier co-ordinates SHOULD also have fraction digits of 2.
         ** Otherwise, they wont match while displaying the barriers.- added by Neha.
         */
        nf.setMaximumFractionDigits(2);
        nf.setGroupingUsed(false);
        switch (barPos) {
            case BarrierN:
                x1s = nf.format(x1);
                y1s = nf.format(y2);
                x2s = nf.format(x2);
                y2s = nf.format(y2 + widthDouble);
                break;
            case BarrierS:
                x1s = nf.format(x1);
                y1s = nf.format(y1 - widthDouble);
                x2s = nf.format(x2);
                y2s = nf.format(y1);
                break;
            case BarrierE:
                x1s = nf.format(x2);
                y1s = nf.format(y1);
                x2s = nf.format(x2 + widthDouble);
                y2s = nf.format(y2);
                break;
            case BarrierW:
                x1s = nf.format(x1 - widthDouble);
                y1s = nf.format(y1);
                x2s = nf.format(x1);
                y2s = nf.format(y2);
                break;
        }

        return x1s + " " + y1s + java.lang.System.getProperty("line.separator")
                + x2s + " " + y2s + java.lang.System.getProperty("line.separator")
                + type + java.lang.System.getProperty("line.separator")
                + height + java.lang.System.getProperty("line.separator")
                + width + java.lang.System.getProperty("line.separator")
                + porosity;
    }

    /**
     * This method writes the modifications done or text inserted to the notes
     * text field/area in the file that preserves it.
     *
     * @param dir The system path to the directory where this file exists.
     */
    public void writeNotesFile(String dir) {

        //Disabled large note files quick fix.
        //String value = getData(NotesReadonly);
        //if (value != null && value.equals("1")) return;
        PrintWriter out = null;
        try {
            out = new PrintWriter(new BufferedWriter(new TFileWriter(
                    new TFile(dir, RunFileData.NotesFileName))));

            String notes = getData(NotesText);
            out.println(notes);
        } catch (FileNotFoundException e) {
            //System.err.println("RFD_wNF: " + e);
        } finally {
            try {
                out.close();
            } catch (Exception e) {
                LOGGER.error("Error closing file stream", e);
            }
        }
    }

    /**
     * This method updates to the newly inserted date values in the dates column
     * of the interface.
     */
    public void updateDates() {
        String runType = getData(RunTypeDisp);
        if (runType.equals(ConfigData.Dates)) {
            String sD = getData(StartDate);
            // //System.out.println("RFD_uD: START DATE is :" + sD);  // TESTING
            String eD = getData(EndDate);
            // //System.out.println("RFD_uD: END DATE is :" + eD);  // TESTING
            StringTokenizer st = new StringTokenizer(sD);
            st.nextToken();
            st.nextToken();
            sD = st.nextToken();
            //System.out.println("RFD_uD: START DATE after TOKEN is :" + sD); // TESTING
            st = new StringTokenizer(eD);
            st.nextToken();
            st.nextToken();
            eD = st.nextToken();
            //System.out.println("RFD_uD: END DATE after TOKEN is :" + eD); // TESTING
            String totYrs = "" + ((Integer.parseInt(eD) - Integer.parseInt(sD)) + 1);
            //System.out.println("RFD_uD: Total Years are :" + totYrs); // TESTING
            setData(TotalYears, totYrs);
        } else {
            if (runType.equals(ConfigData.NRCS)) {
                setData(CycleCount, NRCSRunLen);
            }
            setData(StartDate, "01 01 01");
            String numYrs = getData(RotationYears);
            String numCyl = getData(CycleCount);
            int nY = Integer.parseInt(numYrs);
            int nC = Integer.parseInt(numCyl);
            setData(EndDate, "31 12 " + (nY * nC));
            String totYrs = "" + (nY * nC);
            setData(TotalYears, totYrs);
        }

    }

    public void writeRunFile(String runDirPath) {
        writeRunFile(runDirPath, false);
    }

    /**
     * This method creates the "weps.run" file in the run directory.
     *
     * @param runDirPath The system path string to this run directory.
     */
    public void writeRunFile(String runDirPath, boolean calMode) {
        PrintWriter out = null;
        TFile runDir = new TFile(runDirPath);
        RelativeFileContext.enter(runDir);
        try {
            out = new PrintWriter(new BufferedWriter(new TFileWriter(new TFile(runDir, WepsRun))));
            int count = 0;
            //First line is now a version line
            NumberFormat versionFormat = NumberFormat.getNumberInstance();
            versionFormat.setMaximumFractionDigits(2);
            out.println(VERSION_MARKER + versionFormat.format(VERSION_CURRENT));
            out.println("#------------ WEPS SIMULATION RUN FILE ------------");
            out.println("# Note: Lines beginning with '#' are comment lines.");
            out.println("#       Lines beginning with '#   RFD' are comments used by the interface.");
            out.println("#");
            out.println("# --USER INFORMATION");
            out.println("#   " + UserName);
            out.println(getData(UserName));
            out.println("#   " + FarmId + " " + TractId + " " + FieldId + " "
                    + RunTypeDisp + " " + RotationYears + " " + CycleCount);
            out.println(getData(FarmId) + " | " + getData(TractId) + " | "
                    + getData(FieldId) + " | " + getData(RunTypeDisp) + " | "
                    + getData(RotationYears) + " | " + getData(CycleCount));
            //out.println("#   " + SiteCounty + ", " + SiteState);
            //out.println(getData(SiteCounty) + ", " + getData(SiteState));
            out.println("#   " + Site);
            usda.weru.weps.location.Site<?> site = getBean().getSite();
            out.println(site != null ? site.toString() : "");
            out.println("#");
            out.println("# --SITE INFORMATION");
            //print out the parts of LatLong
            LatLong latlong = getBean().getLatLong();
            // Added digits here to see if problem still exists.
            NumberFormat latlongFormat = new DecimalFormat("+0.00000;-0.00000");
            out.println("#   Signed Latitude");
            out.println(latlongFormat.format(latlong.latitudeValue(USCustomary.DEGREE_ANGLE)));
            out.println("#   Signed Longitude");
            out.println(latlongFormat.format(latlong.longitudeValue(USCustomary.DEGREE_ANGLE)));

            out.println("#   " + Elevation + "(meters)");
            out.println(getData(Elevation));

            //cligen
            out.println("#   " + ClimateFlag + "|" + CligenStation);
            //the new station mode model handles serializing the station for each mode.
            StationMode cligenMode = getBean().getCligenStationMode();
            Station cligenStation = getBean().getCligenStation();
            if (cligenStation instanceof FileStation && cligenStation != null) {
                TFile file = ((FileStation) cligenStation).getFile();
                cligenStation = new FileStation(new TFile(runDir, file.getName()));
            }
            out.println(cligenMode.getName() + "|" + StationUtil.serializeStation(cligenStation));

            //windgen
            out.println("#   " + WindFlag + "|" + WindgenStation);
            //the new station mode model handles serializing the station for each mode.
            StationMode windgenMode = getBean().getWindgenStationMode();
            Station windgenStation = getBean().getWindgenStation();
            if (windgenStation instanceof FileStation && windgenStation != null) {
                TFile file = ((FileStation) windgenStation).getFile();
                windgenStation = new FileStation(new TFile(runDir, file.getName()));
            }
            out.println(windgenMode.getName() + "|" + StationUtil.serializeStation(windgenStation));

            out.println("#");
            out.println("# --SIMULATION PERIOD");
            out.println("#   " + StartDate + "(day month year)");
            out.println(getData(StartDate));
            out.println("#   " + EndDate + "(day month year)");
            out.println(getData(EndDate));
            out.println("#   " + TimeSteps + "(per day)");
            out.println(getData(TimeSteps));
            out.println("#");
            out.println("# --RUN FILE FILENAMES (INPUT)");
            out.println("#   " + ClimateFile);
            if (cligenStation instanceof FileStation) {
                FileStation fileStation = (FileStation) cligenStation;
                out.println(fileStation.getFile().getName());
                setData(ClimateFile, fileStation.getFile().getName());
            } else {
                out.println(DefaultCliGenName);
                setData(ClimateFile, DefaultCliGenName);
            }
            out.println("#   " + WindFile);
            //if it is a file station we use the name of the file, else we use the default name            
            if (windgenStation instanceof FileStation) {
                FileStation fileStation = (FileStation) windgenStation;
                out.println(fileStation.getFile().getName());
                setData(WindFile, fileStation.getFile().getName());
            } else if (windgenStation instanceof InterpolatedStation) {
                out.println("interpolated.win");
                setData(WindFile, "interpolated.win");
            } else {
                out.println(DefaultWinGenName);
                setData(WindFile, DefaultWinGenName);
            }
            out.println("#   " + SubDailyFile);
            out.println("none");
            out.println("#   " + SoilFile);
            out.println((new TFile(getData(SoilFile)).getName()));
            out.println("#   " + ManageFile);
            if (calMode) {
                String name = new TFile(getData(MgtCalibFile)).getName();
                String[] insert = name.split("\\.");
                if (!(insert.length >= 2)) {
                    LOGGER.warn("Management file does not have extension");
                    out.println(new TFile(getData(MgtCalibFile)).getName());
                } else if (!insert[insert.length - 1].equals("man")) {
                    LOGGER.warn("Management file does not end in .man");
                    out.println(new TFile(getData(MgtCalibFile)).getName());
                } else {
                // Trying to get the merge to work so I added this stupid comment - LEW - 3-2-23
//                    name = "";
//                    if (!insert[insert.length - 2].endsWith("_CALIB")) {
//                        insert[insert.length - 2] += "_CALIB";
//                    }
//                    for (String item : insert) {
//                        name += item + ".";
//                    }
//                    name = name.substring(0, name.length() - 1);
//                    out.println(name);
//                    out.println((new TFile(getData(ManageFile)).getName()));
                    out.println((new TFile(getData(MgtCalibFile)).getName()));
                }
            } else {
                out.println((new TFile(getData(ManageFile)).getName()));
            }
            out.println("#");
            out.println("# --WEPS OUTPUT OPTIONS");
            out.println("#   " + OutputFile);
            out.println(getData(OutputFile));
            out.println("#   " + ReportForm);
            out.println(getData(ReportForm));
            out.println("#   " + OutputPeriod);
            out.println(getData(OutputPeriod));
            out.println("#   " + SubmodelOutput);
            out.println(so.getAllSubmodelOutput());
            out.println("#   " + DebugOutput);
            out.println("0 0 0 0 0 0");
            out.println("#");
            out.println("# --SIMULATION REGION INFORMATION");
            out.println("#   " + RegionAngle + "(degrees clockwise from North)");
            out.println(getData(RegionAngle));
            out.println("#   Origin coordinates of simulation region (meters)");
            out.println("0.0  0.0");
            setData(SimPoint1, "0.0 0.0");
            out.println("#    " + XLength + "(meters)" + "  " + YLength + "(meters)");
            String xLength = getData(XLength);
            String yLength = getData(YLength);
            out.println(xLength + "  " + yLength);
            setData(SimPoint2, xLength + "  " + yLength);
            out.println("#   " + Scales + "(place holder line - needed for older versions of WEPS)");
            out.println("5.5 5.5");
            out.println("#");
            out.println("#   " + AccNo);
            out.println(getData(AccNo));
            out.println("#   Accounting region coordinates (meters)");
            out.println("    0.0  0.0");
            out.println(xLength + "  " + yLength);
            out.println("#");
            out.println("#   " + SubregionNo);
            out.println(getData(SubregionNo));
            out.println("#   Subregion region coordinates (meters)");
            out.println("0.0  0.0");
            out.println(xLength + "  " + yLength);
            out.println("#   " + AverageSlope + "(ratio m/m)");
            out.println( adjustSlopeFragStr(AverageSlope, getData(AverageSlope)));// Double.parseDouble(getData(AverageSlope)) == -1.0 ? Integer.toString(-1) : getData(AverageSlope));
            // out.println("#   Barriers");
            int barrierCnt = 0;
            if (!getData(BarrierN).startsWith("none|")) {
                barrierCnt++;
            }
            if (!getData(BarrierS).startsWith("none|")) {
                barrierCnt++;
            }
            if (!getData(BarrierE).startsWith("none|")) {
                barrierCnt++;
            }
            if (!getData(BarrierW).startsWith("none|")) {
                barrierCnt++;
            }
            out.println("#   " + BarrierNo);
            out.println(barrierCnt);
            if (barrierCnt == 0) {
                out.println(makeBarrier(BarrierD, ""));
            } else {
                String barrier = getData(BarrierN);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierN + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierN, barrier));
                }
                barrier = getData(BarrierW);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierW + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierW, barrier));
                }
                barrier = getData(BarrierE);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierE + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierE, barrier));
                }
                barrier = getData(BarrierS);
                if (barrier.length() > 0 && !barrier.startsWith("none|")) {
                    out.println("#   " + BarrierS + " coordinates (meters)" + " | type"
                            + " | height (meters)" + " | width (meters)" + " | porosity");
                    out.println(makeBarrier(BarrierS, barrier));
                }
            }
            out.println("#");
            out.println("# --CIRCULAR FIELD INFORMATION");
            out.println("# Note: These fields are not used by the weps simulation.");
            out.println("#       The shape and radius values are used by the user ");
            out.println("#       interface to approximate a rectangular field.  They");
            out.println("#       are included here so the reports can display the ");
            out.println("#       correct field shape.");
            out.println("#");
            out.println("#   " + Shape);
            out.println(getData(Shape));
            out.println("#   " + Radius);
            out.println(getData(Radius));
            out.println("#   " + WaterErosionLoss);
            out.println(getData(WaterErosionLoss));
            out.println("#   " + SoilRockFragments);
            out.println(adjustSlopeFragStr(SoilRockFragments, getData(SoilRockFragments)));
//Double.parseDouble(getData(SoilRockFragments)) == -1.0 ? Integer.toString(-1) : getData(SoilRockFragments));
//            if(getData(AverageSlopeField) == null){
//                setData(AverageSlopeField, "-1");
//            }
//            out.println("#  " + AverageSlopeField + " " + getData(AverageSlopeField));
//            if(getData(SoilRockFragmentsField) == null){
//                setData(SoilRockFragmentsField, "-1");
//            }
//            out.println("#  " + SoilRockFragmentsField + " " + getData(SoilRockFragmentsField));
            out.println("#---------- END OF SIMULATION RUN FILE ------------");
            writeNotesFile(runDirPath);
        } catch (FileNotFoundException e) {
            //System.err.println("RunFileData: " + e);
        } finally {
            RelativeFileContext.exit();
            try {
                out.close();
            } catch (Exception e) {
                LOGGER.error("Error closing stream", e);
            }
        }
        changes.firePropertyChange(WriteRunFile, null, "xxx");
    }

    /**
     * This method reads the file "weps.ini" in the project directory specified
     * in the path "runFilePathName" into hashtable "ht".
     *
     * @param runFilePathName The system path string to this run file directory.
     */
    @SuppressWarnings("unchecked") // Element.getChildren is not checked
    public void readRunData(String runFilePathName) {
        fileObject = new TFile(runFilePathName);
        TFile runData = new TFile(runFilePathName, WepsData);

        if (!runData.exists()) {
            initialize();
            writeRunDataXML(runFilePathName);
        }
        RelativeFileContext.enter(new TFile(runFilePathName));
        LoadingContext.enter();
        try {

            if (runFilePathName.length() == 0) {
                runFilePathName = curProj;
            }

            Map<String, String> initializationData = new HashMap<String, String>();
            boolean write = false;
            //first try the xml
            try {
                readRunDataXML(runData, initializationData);
                //now set all the data
            } catch (Exception e) {
                //xml failed, maybe it's really old in the binary format?
                LOGGER.info("Could not read weps.ini file as an XML document.  Will try using old binary format.");
                try {
                    readRunDataBinary(runData, initializationData);
                    write = true;
                } catch (Exception ex) {
                    //oh snap, even the binary failed.
                }
            }

            //Handle a few cases first                
            prioritySetData(initializationData, RunFileData.StrLatLong);
            prioritySetData(initializationData, RunFileData.ClimateFlag);
            prioritySetData(initializationData, RunFileData.CligenStation);
            prioritySetData(initializationData, RunFileData.WindFlag);
            prioritySetData(initializationData, RunFileData.WindgenStation);

            for (Map.Entry<String, String> entry : initializationData.entrySet()) {
                setData(entry.getKey(), entry.getValue());
            }
            //fixup the cligen/windgen modes
            String climateMode = initializationData.get(RunFileData.ClimateFlag);
            if (climateMode != null && climateMode.trim().length() == 0) {
                getBean().setCligenStationMode(null);
            }

            String windgenMode = initializationData.get(RunFileData.WindFlag);
            if (windgenMode != null && windgenMode.trim().length() == 0) {
                getBean().setWindgenStationMode(null);
            }

            if (write) {
                writeRunDataXML(runFilePathName);
            }
        } finally {
            LoadingContext.exit();
            RelativeFileContext.exit();
        }

    }

    private void prioritySetData(Map<String, String> map, String property) {
        String value = map.get(property);
        setData(property, value);
    }

    private void readRunDataXML(TFile file, Map<String, String> temp) throws Exception {
        RelativeFileContext.enter(new TFile(file.getParentFile()));
        LoadingContext.enter();
        clearBean();
        try {
            SAXBuilder in = new SAXBuilder();
            Document doc;
            Element root = null;
            //use the stream so zipped files will work
            doc = in.build(new TFileInputStream(file));
            if (doc != null) {
                root = doc.getRootElement();
            } else {
                throw new RuntimeException("no runFileData doc");
            }
            double version = 0;
            try {
                version = Double.valueOf(root.getAttributeValue("version"));
            } catch (NumberFormatException e) {
                //no version number;
                version = 0;
            }
            for (Element element : root.getChildren("key")) {
                String key = element.getAttributeValue("name");
                String value = element.getText();
                if(key.equals(AverageSlope) || key.equals(SoilRockFragments))
                {
                    if(value.trim().startsWith("-1")) value = "-1";
                    if(value.trim().startsWith("-2")) value = "-2";
                }
                temp.put(key, value);
            }

            //upgrade data
            upgradeData(temp, version);

            //clean data
            cleanData(temp);
        } finally {
            LoadingContext.exit();
            RelativeFileContext.exit();
        }
    }

    private void readRunDataBinary(TFile file, Map<String, String> temp) throws Exception {
        LoadingContext.enter();
        try {
            ObjectInputStream objStream = null;
            try {

                TFileInputStream inStream = null;
                try {
                    inStream = new TFileInputStream(file);
                } catch (java.io.FileNotFoundException fnfe) {
                    LOGGER.info("Run file data not found. " + file.getPath());
                    initialize();
                    return;
                }

                objStream = new ObjectInputStream(inStream);
                //Load the file into a initializationData location.

                // I don't think that there's a way to get
                // objStream to safely return a Hashtable
                Hashtable<String, String> tempHashtable = Caster.<Hashtable<String, String>>cast(objStream.readObject());
                for (Map.Entry<String, String> entry : tempHashtable.entrySet()) {
                    String key = entry.getKey();
                    if (key.equals(RunsLocation)) {
                        continue;
                    }
                    String value = entry.getValue();
                    temp.put(key, value);
                }
                upgradeData(temp, 0);
                cleanData(temp);

            } finally {
                try {
                    if (objStream != null) {
                        objStream.close();
                    }
                } catch (IOException e) {
                    LOGGER.error("Error closing file stream. " + file.getPath(), e);
                }
            }
        } finally {
            LoadingContext.exit();
        }
    }

    private void upgradeData(Map<String, String> map, double version) {

        //System.out.println(Arrays.asList(map));
        if (version < VERSION_LOCPANEL_REWRITE) {
            //need to upgrade the station values
            //CLIGEN
            StationMode cligenMode = StationMode.parse(map.get(ClimateFlag));

            //convert id to name
            map.put(WindFlag, cligenMode.getName());

            Station cligenStation = null;
            switch (cligenMode) {
                case Choice:
                    try {
                        long cligenId = Long.valueOf(map.get(CliGenStation));
                        long cligenState = Long.valueOf(map.get(CliGenState));
                        //try to find a station for the give id
                        cligenStation = CligenDataModel.getInstance().getStation(cligenState, cligenId);

                    } catch (NumberFormatException e) {
                        //oh snap
                    }

                    break;
                case File:
                    String cligenFilePath = map.get(WindFile);
                    if (cligenFilePath != null) {
                        cligenStation = new FileStation(new TFile(cligenFilePath));
                    }
                    break;
                default:
                    //unexpected old mode
                    break;
            }

            String cligenStationSer = StationUtil.serializeStation(cligenStation);
            map.put(CligenStation, cligenStationSer);
            //END CLIGEN

            //WINDGEN
            StationMode windgenMode = StationMode.parse(map.get(WindFlag));

            //convert id to name
            map.put(WindFlag, windgenMode.getName());

            Station windgenStation = null;
            switch (windgenMode) {
                case Choice:
                    try {
                        long windgenId = Long.valueOf(map.get(WinGenStation));
                        //try to find a station for the give id
                        windgenStation = WindgenDataModel.getInstance().getStation(windgenId);

                    } catch (NumberFormatException e) {
                        //oh snap
                    }
                    break;
                case File:
                    String windgenFilePath = map.get(WindFile);
                    if (windgenFilePath != null) {
                        windgenStation = new FileStation(new TFile(windgenFilePath));
                    }
                    break;
                default:
                    //unexpected old mode
                    break;
            }

            String windgenStationSer = StationUtil.serializeStation(windgenStation);
            map.put(WindgenStation, windgenStationSer);
            //END WINDGEN

        }

        if (version < VERSION_LOCPANEL_SITE) {
            //site

            usda.weru.weps.location.Site<?> site = upgradeSiteString(map.get(Site));
            if (site != null) {
                map.put(Site, site.toString());
            }
        }

        if (version < VERSION_RELATIVE_PATHS) {
            TFile projectFile = new TFile(curProj);

            //need to fix up paths that might not be valid for soil and management
            String soilPath = map.get(SoilFile);
            TFile soilFile = new TFile(soilPath);

            if (!soilFile.exists()) {
                soilFile = new TFile(projectFile, soilFile.getName());
                if (soilFile.exists()) {
                    map.put(SoilFile, soilFile.getPath());
                    LOGGER.info("Resolved missing absolute soil file to relative path.");
                }
            }

            String managePath = map.get(ManageFile);
            TFile manageFile = new TFile(managePath);

            if (!manageFile.exists()) {
                manageFile = new TFile(projectFile, manageFile.getName());
                if (manageFile.exists()) {
                    map.put(ManageFile, manageFile.getPath());
                    LOGGER.info("Resolved missing absolute management file to relative path.");
                }
            }

        } else {
            //Need to take the relative paths and convert to absolute so the interface still works
            TFile projectFile = new TFile(curProj);

            String soilPath = map.get(SoilFile);
            String managePath = map.get(ManageFile);
            if (soilPath.charAt(1) != ':') {
                if (!"".equals(soilPath)) {
                    if (new TFile(soilPath).getParent() == null) {
                        map.put(SoilFile, new TFile(projectFile, soilPath).getPath());
                    }
                }
            }
            if (managePath.charAt(1) != ':') {
                if (!"".equals(managePath)) {
                    if (new TFile(managePath).getParent() == null) {
                        map.put(ManageFile, new TFile(projectFile, managePath).getPath());
                    }
                }
            }
        }
        try {
            setData(Radius, map.get(Radius));
        } catch (NullPointerException e) {
             setData(Radius, "0");
        }
    }

    private usda.weru.weps.location.Site<?> upgradeSiteString(String oldSiteString) {
        String parts[] = oldSiteString.split(",");
        String countyName = parts[0].trim();
        String stateName = parts[1].trim();

        Level0 usa = Level0.UNITED_STATES;
        usda.weru.weps.location.Site<?> temp = null;
        for (usda.weru.weps.location.Site<?> state : usa.getSubDivisions()) {
            if (state.getDisplayName().equalsIgnoreCase(stateName)) {
                temp = state;
                break;
            }
        }

        if (temp != null) {
            for (usda.weru.weps.location.Site<?> county : temp.getSubDivisions()) {
                if (county.getDisplayName().equalsIgnoreCase(countyName)) {
                    temp = county;
                    break;
                }
            }
        }

        return temp;
    }

    private void cleanData(Map<String, String> map) {
        for (Field field : RunFileData.class.getFields()) {
            if (field.getType().equals(String.class) && field.isAnnotationPresent(Deprecated.class)) {
                try {
                    String key = (String) field.get(this);
                    map.remove(key);
                    LOGGER.info("Deprecated RunFileData Key: " + key);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                }
            }
        }
    }

    public void writeRunDataXML(String runFilePathName) {

        cleanData(ht);
        if (runFilePathName.length() == 0) {
            runFilePathName = curProj;
        }
        TFile runData = new TFile(runFilePathName, WepsData);
        TFile runFolder = new TFile(runFilePathName);
        RelativeFileContext.enter(runFolder);
        try {

            Element root = new Element("weps");
            //add the version number so when read in we know how to handle station values
            root.setAttribute("version", String.valueOf(VERSION_CURRENT));
            synchronized (this) {
                //create a delay so when writing the default .ini, 
                //the initializing of the cligen and windgen stations can catch
                //up.
                try {
                    this.wait(4000);
                } catch (InterruptedException inter) {
                } catch (IllegalMonitorStateException ill) {
                }
            }
            for (Map.Entry<String, String> entry : ht.entrySet()) {
                try {
                    Element param = new Element("key");
                    String key = entry.getKey();
                    
                    param.setAttribute("name", key);
                    String value = entry.getValue();
                    
                    value = adjustSlopeFragStr(key,value);
                        
                    if (!"".equals(value) && (RunFileData.SoilFile.equals(key) || RunFileData.ManageFile.equals(key))) {
                        //if soil or manage file make relative paths
                     
                        TFile valueFile = new TFile(value);
                        TFile destFile = new TFile(runFilePathName + "/" + valueFile.getName());
                        Util.copyFile(valueFile,destFile);
                        destFile = Util.resolveFileAsRelativeChildOrAbsolute(runFolder, destFile);
                        value = destFile.getPath();
                        //valueFile = Util.resolveFileAsRelativeChildOrAbsolute(runFolder, valueFile);
                        //value = valueFile.getPath();
                    }

                    param.setText(value != null ? value : "");
                    root.addContent(param);
                } catch (IllegalDataException ide) {
                    LOGGER.warn("Unable to save data element.  Some data may be missing or corrupted. "
                            + ide.getMessage());
                }
            }
            TFileOutputStream stream = null;
            try {
                XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
                stream = new TFileOutputStream(runData);
                out.output(root, stream);
                stream.close();
            } catch (IOException ex) {
                LOGGER.error("Error writing run data.", ex);
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException ex) {
                    }
                }
            }
        } finally {
            RelativeFileContext.exit();
        }
    }

    public boolean removeRunData(TFile dir) {
        return Util.deleteAll(dir);
    }

    public void showRunFileData(String msg) {
        //System.err.println("sRFD " + msg + " " + ht.size());
        Enumeration<String> e = ht.keys();
        while (e.hasMoreElements()) {
            String key = e.nextElement();
            String value = ht.get(key);
            System.err.println(key + "=" + value);
        }
    }
    
    private String adjustSlopeFragStr(String key, String value){
        if((key.equalsIgnoreCase(SoilRockFragments) || key.equalsIgnoreCase(AverageSlope)) && value.trim().startsWith("-1")){
            return "-1";
        }
        if(key.equalsIgnoreCase(AverageSlope) && value.trim().startsWith("-2")){
            return "-2";
        }
        return value;
    }
    
    private final PropertyChangeSupport changes = new PropertyChangeSupport(this);

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

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
        changes.addPropertyChangeListener(propertyName, l);
    }

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

    public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
        changes.removePropertyChangeListener(propertyName, l);
    }

    @Override
    public void propertyChange(PropertyChangeEvent e) {
        String idxstr = e.getPropertyName();
        if (!idxstr.startsWith(RFD)) { 	// not an rfd file value
            switch (idxstr) {
                case WriteRunData:
                    writeRunDataXML((String) e.getNewValue());
                    break;
                case WriteRunFile:
                    writeRunFile((String) e.getNewValue());
                    break;
                case ReadRunData:
                    readRunData((String) e.getNewValue());
                    break;
                case ReadRunFile:
                    readRunFile((String) e.getNewValue());
                    break;
                case ShowRunData:
                    showRunFileData((String) e.getNewValue());
                    break;
                case ConfigData.CurrentProj:
                    curProj = Util.parse(e.getNewValue().toString());
                    break;
                case ConfigData.NRCSRunLen:
                    NRCSRunLen = (String) e.getNewValue();
                    break;
                case ConfigData.OutputFreq:
                    setData(OutputPeriod, (String) e.getNewValue());
                    break;
                case RunFileData.ClimateFlag:
                    setData(ClimateFlag, (String) e.getNewValue());
                    break;
                case RunFileData.WindFlag:
                    setData(WindFlag, (String) e.getNewValue());
                    break;
            }

            return;
        }
        String valstr = (String) e.getNewValue();
        setData(idxstr, valstr);
        if (idxstr.equals(ManageFile)) {
            setRotationYears(valstr);
        }
    }

    public Set<String> keySet() {
        if (ht != null) {
            return ht.keySet();
        } else {
            return null;
        }
    }


    private synchronized void clearBean() {
    }

    public synchronized RunFileBean getBean() {
        if (c_bean == null) {
            c_bean = new RunFileBean();
            //link the two together
            RunFileDataBeanBridge.bridge(this, c_bean);
        }
        return c_bean;
    }

}
