package usda.weru.util.wepsFileChooser2;

import de.schlichtherle.truezip.file.TFile;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import static java.awt.Cursor.getPredefinedCursor;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import static javax.swing.JOptionPane.*;
import static javax.swing.JOptionPane.showConfirmDialog;
import javax.swing.ListSelectionModel;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileSystemView;
import usda.weru.remoteDataAccess.csip.CsipLmodUtil;
import usda.weru.remoteDataAccess.csip.CsipLmodUtil.lmodType;
import usda.weru.remoteDataAccess.remoteFiles.RemoteFile;
import usda.weru.remoteDataAccess.remoteFiles.dbFile.soil.mdb.MdbSoilFileDatabase;
import usda.weru.remoteDataAccess.remoteFiles.dbFile.soil.soilDataMart.SDMFileDatabase;
import usda.weru.remoteDataAccess.remoteFiles.inetFile.CrLmodFile;
import usda.weru.remoteDataAccess.remoteFiles.inetFile.CsipSoilFile;
import usda.weru.util.About;
import usda.weru.util.ConfigData;
import usda.weru.util.Util;
import static usda.weru.util.Util.getProperty;
import usda.weru.weps.RunFileData;

/**
 *
 * @author mhaas
 */
/* ===== NOTE FOR THOSE USING ===== 
    I added a method to generate a basic and functional WepsFileChooser2 instance that
    in its' parameters has/sets all the basic information to generate a functional
    fileChooser without much knowledge of the class. Also added documentation to some
    of the more commonly used methods. Just generate an instance of file chooser through 
    whatever constructor is most applicable:

    WepsFileChooser2 fileChooser = new WepsFileChooser2(your choice of constructor);
                               Ex: new WepsFileChooser2(WepsFileTypes2.File, "", WepsFileChooser2.Action.Select);

    fileChooser.createBasicFileChooser(null, null, null, null, null, null);

    int response = .showDialog(parentComponent); // This displays the filechooser and the integer corresponds to success of choice

    -----------------------------------------------------------------------------------
    Every single argument can be null and will still generate a functional file chooser.
    adding in actual arguments will fine-tune the file chooser to more closely fit your
    needed use. -CKM
 */
public class WepsFileChooser2 extends WepsFileChooser2_n {

    static final long serialVersionUID = 1L;

//    private static final Logger LOGGER = LogManager.getLogger(WepsFileChooser2.class);

    private static final Logger LOGGER = LogManager.getLogger(Thread.currentThread().getStackTrace()[0].getClassName() );
    
    public static enum Action {

        Open("Open", "Open a "), Save("Save", "Save a "), Delete("Delete", "Delete a "), Create("Create", "Create a "), Select("Select", "Select a ");

        private final String labelTxt;
        private final String description;

        private Action(String labelTxt, String description) {
            this.labelTxt = labelTxt;
            this.description = description;
        }

        public String getLabelTxt() {
            return labelTxt;
        }

        public String getDescription() {
            return description;
        }
    }

    public static enum SelectionType {
        FILES_ONLY,
        DIRECTORIES_ONLY,
        FILES_AND_DIRECTORIES
    }

    private static final Map<String, WepsFileTypes2> HT_propertyToType = new HashMap<>();

    static {
        //start new properties
        HT_propertyToType.put(ConfigData.opRecordsCRLMOD, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.cropRecordsCRLMOD, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.residueRecordsCRLMOD, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.localResidueRecords, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.cligenDataCRLMOD, WepsFileTypes2.CliDB);
        HT_propertyToType.put(ConfigData.cligenIndexCRLMOD, WepsFileTypes2.CliIdx);
        HT_propertyToType.put(ConfigData.prismNormalsCRLMOD, WepsFileTypes2.File);
        HT_propertyToType.put(ConfigData.windgenDataCRLMOD, WepsFileTypes2.WindDB);
        HT_propertyToType.put(ConfigData.windgenIndexCRLMOD, WepsFileTypes2.WindIdx);
        //end new properties
        HT_propertyToType.put(ConfigData.WepsExe, WepsFileTypes2.Executable);
        HT_propertyToType.put(ConfigData.CliExe, WepsFileTypes2.Executable);
        HT_propertyToType.put(ConfigData.WinExe, WepsFileTypes2.Executable);
        HT_propertyToType.put(ConfigData.WindInterp1EXE, WepsFileTypes2.Executable);
        HT_propertyToType.put(ConfigData.WindInterp2EXE, WepsFileTypes2.Executable);
        HT_propertyToType.put(ConfigData.SWEEPExe, WepsFileTypes2.Executable);
        HT_propertyToType.put(ConfigData.WinData, WepsFileTypes2.WindDB);
        HT_propertyToType.put(ConfigData.WinIndex, WepsFileTypes2.WindIdx);
        HT_propertyToType.put(ConfigData.CliData, WepsFileTypes2.CliDB);
        HT_propertyToType.put(ConfigData.CliIndex, WepsFileTypes2.CliIdx);
        HT_propertyToType.put(ConfigData.ManTemp, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.LocalManDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.ManSkel, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.SystemOpDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.SystemCropDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.LocalSDMDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.LocalCropDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.SharedManDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.LocalOpDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.LocalSoilDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.MCREW, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.SoilDB, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.ProjDir, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.DefaultRunsLocationTemplate, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.McrewDataConfigFile, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.SkelTranslationFile, WepsFileTypes2.File);
        HT_propertyToType.put(ConfigData.ReportFileName, WepsFileTypes2.File);
        HT_propertyToType.put(ConfigData.DetailTableFilterFile, WepsFileTypes2.File);
        HT_propertyToType.put(ConfigData.GISData, WepsFileTypes2.Dir);
        HT_propertyToType.put(ConfigData.SoilOrganicFile, WepsFileTypes2.Soil);
        HT_propertyToType.put(ConfigData.BarriersFile, WepsFileTypes2.File);
        HT_propertyToType.put(ConfigData.CurrentProj, WepsFileTypes2.Project);
        HT_propertyToType.put(ConfigData.FuelDatabase, WepsFileTypes2.XML);
        HT_propertyToType.put(ConfigData.WindgenInterpolationBoundaryFile, WepsFileTypes2.Pol);
    }

    // Return values from file/directory selction
    public static final int APPROVE_OPTION = JFileChooser.APPROVE_OPTION;
    public static final int CANCEL_OPTION = JFileChooser.CANCEL_OPTION;
    public static final int ERROR_OPTION = JFileChooser.ERROR_OPTION;

    public static String propChangeCmdStrFetchCompleted = "WFC_MainDialog_fetchCompleted";

    protected Action action;
    protected File selectedFile;
    protected File[] selectedFiles;
    protected boolean allowNewDir;
    protected SelectionType selectionMode;
    protected boolean multiSelection;
    protected ArrayList<WepsFileTypes2> chooserTypeList;
    protected WepsFileTypes2 chooserType;
    protected boolean allowDirectorySelection;
    protected String extensionString;

    // Constructors from JFileChooser
    public WepsFileChooser2() {
        super();
    }

    public WepsFileChooser2(File currentDirectory) {
        super();
        //System.out.println("dir");
        init(null, Action.Select, currentDirectory, WepsFileTypes2.Any);
    }

    public WepsFileChooser2(File currentDirectory, FileSystemView fsv) {
        super();
        //System.out.println("dir + fsv");
        init(null, Action.Select, currentDirectory, WepsFileTypes2.Any);
    }

    public WepsFileChooser2(FileSystemView fsv) {
        super();
        //System.out.println("fsv");
        init(null, Action.Select, new File(System.getProperty("user.dir")), WepsFileTypes2.Any);
    }

    public WepsFileChooser2(String currentDirectoryPath) {
        super();
        //System.out.println("path");
        TFile initialDir = new TFile(Util.parse(currentDirectoryPath));
        //System.out.println("Parsed file: " + initialDir.getAbsolutePath());
        init(null, Action.Select, initialDir, WepsFileTypes2.Any);
    }

    public WepsFileChooser2(String currentDirectoryPath, FileSystemView fsv) {
        super();
        //System.out.println("path + fsv");
        init(null, Action.Select, new File(currentDirectoryPath), WepsFileTypes2.Any);
    }

    // Constructors from WepsFileChooser
    public WepsFileChooser2(WepsFileTypes2 type, String homeDirPath, Action action) {
        super();
//        System.out.println("type + path + action");
        init(null, action, new File(Util.parse(homeDirPath)), type);
    }
    
    // Constructors from WepsFileChooser no initial type
    public WepsFileChooser2(WepsFileTypes2 type, String homeDirPath, Action action, boolean isRun) {
        super();
        if(isRun){
            if(type==WepsFileTypes2.RunDirLocNew){
                init(null, action, new File(Util.parse(homeDirPath)), WepsFileTypes2.RunDirLocNew);
            }
            else if(type==WepsFileTypes2.RunDir){
                init(null, action, new File(Util.parse(homeDirPath)), WepsFileTypes2.RunDir);
            }else if(type==WepsFileTypes2.ManagementWeps){
                init(null, action, new File(Util.parse(homeDirPath)), WepsFileTypes2.ManagementWeps);
            }else if(type==WepsFileTypes2.Soil){
                init(null, action, new File(Util.parse(homeDirPath)), WepsFileTypes2.Soil);
            }
        }else{
            init(null, action, new File(Util.parse(homeDirPath)), type);
        }
//        System.out.println("type + path + action");
        
    }

    //-ihaas- allows multiple types
    public WepsFileChooser2(WepsFileTypes2[] types, String homeDirPath, Action action) {
        super();
        //System.out.println("type + path + action");
        init(null, action, new File(homeDirPath), types);
    }

    public WepsFileChooser2(WepsFileTypes2[] types, File homeDirPath, Action action) {
        super();
        //System.out.println("type + path + action");
        init(null, action, homeDirPath, types);
    }

    // Constructors from WepsFileChooser
    public WepsFileChooser2(WepsFileTypes2 type, File homeDir, Action action) {
        super();
        //System.out.println("type + dir + action");
        init(null, action, homeDir, type);
    }

    public WepsFileChooser2(String property, Action action) {
        try {
            //System.out.println("property + action");
            WepsFileTypes2 thisFiletype = HT_propertyToType.get(property);
            init(null, action, new File("."), thisFiletype);

        } catch (NullPointerException npe) {
            System.err.println("WFC: property not defined " + property);
            init(null, action, new File("."), WepsFileTypes2.File);
        }
    }

    // Create from WepsFileChooser
    public static WepsFileChooser2 create(Action action, TFile home, WepsFileTypes2 type) {
        //System.out.println("action + file + type");
        return create(action, home, false, false, null, type);
    }

    public static WepsFileChooser2 create(Action action, TFile home, boolean allFilter, boolean groupFilter,
            String groupName, WepsFileTypes2... types) {
        WepsFileChooser2 wfc = new WepsFileChooser2();
        wfc.init(null, action, home, types);
        wfc.setAcceptAllFileFilterUsed(allFilter);
        //System.out.println("action + file + filter1 + filter2 + name + type...s");
        return wfc;
    }

    /**
     * This function is designed to set up a fileChooser as quickly as possible
     * to accomplish selecting file(s) or directory(s)
     *
     * @param type The type of file you wish to select from enum (File, dir or
     * both) if null, will be both
     * @param filter A File filter that is used to only display allowed files,
     * if null set to all files
     * @param setMultipleFileSelect Whether the user is allowed to select
     * multiple files by highlighting, or only a single file. if null, defaults
     * to false
     * @param informationText The text that appears between top of fileChooser
     * and path selection bar.
     * @param topText The text that appears in the gray top bar, generally
     * purpose of file chooser. If null selection will simply display ("WEPS
     * File Chooser") Usually basic instructions on what to select. If null,
     * will reflect type
     * @param initDirectory The initial directory that the fileChooser will be
     * pointing to. If null, sets to DataBase directory
     */
    public void createBasicFileChooser(SelectionType type, javax.swing.filechooser.FileFilter filter, Boolean setMultipleFileSelect, String informationText,
            String topText, String initDirectory) {

        // set type
        if (type != null) {
            this.setFileSelectionMode(type);
            if (type == SelectionType.DIRECTORIES_ONLY || type == SelectionType.FILES_AND_DIRECTORIES) {
                this.setAllowDirectorySelection(true);
            } else {
                this.setAllowDirectorySelection(false);
            }
        } else {
            this.setFileSelectionMode(SelectionType.FILES_AND_DIRECTORIES); // accept either
            this.setAllowDirectorySelection(true);
        }
        this.setFileFilter(new WepsFileFilter());
        // filter
        if (filter != null) {
            this.setFileFilter(filter);
        } 

        // setMultiple 
        if (setMultipleFileSelect != null) {
            this.setMultiSelectionEnabled(setMultipleFileSelect);
        } else {
            this.setMultiSelectionEnabled(false); // default to false
        }

        // top file chooser text
        if (topText != null) {
            this.setDialogTitle(topText);
        } else {
            this.setDialogTitle("WEPS File Chooser");
        }

        // instruction text
        if (informationText != null) {
            this.setText(informationText);
        } else {
            // set based on type
            switch (this.selectionMode) {
                case FILES_ONLY:
                    this.setText("Select File");
                    break;
                case DIRECTORIES_ONLY:
                    this.setText("Select Directory");
                    break;
                default:
                    // both
                    this.setText("Select a File or Directory");
                    break;
            }
        }

        if (initDirectory != null) {
            this.setCurrentDirectory(initDirectory);
            this.setDefaultDirectory(new TFile(initDirectory));
        } else {
            /* THIS WAY USES XMLConstants TO SET ---
            String dir = MCREWConfig.getDirectoryName(XMLConstants.sDBdir);
            TFile ddir = new TFile(dir);
            this.setCurrentDirectory(ddir);
             */
            JCB_Path.selectDbDir();  // This sets the path and the display to the set db directory
            this.setDefaultDirectory(JCB_Path.getSelectedDir());

        }

        this.action = Action.Select;

    }

    public void setAllowDirectorySelection(boolean selectionChoice) {
        allowDirectorySelection = selectionChoice;
    }
    
    public boolean isRecurive(){
        return jCheckBoxRecursive.isSelected();
    }
    
    public boolean isInPlace(){
        return jCheckBoxInPlace.isSelected();
    }

    protected void init(String message, Action action, File initialDir, WepsFileTypes2... types) {

        this.action = action;
        selectedFile = null;
        selectedFiles = null;
        allowNewDir = false;
        selectionMode = SelectionType.DIRECTORIES_ONLY;
        setMultiSelectionEnabled(false);

        setIconImage(About.getWeruIconImage());
        setLocationRelativeTo(null);

        addPropertyChangeListener(this);

        // load the initial paths into the paths combo
        if (initialDir != null) {
            //System.out.println("pre parsed directory: " + initialDir.getAbsolutePath());
            // check for replaceable parameters in the file name
            initialDir = new File(Util.parse(initialDir.getPath()));
            //initialDir = new File(Util.parse(initialDir.getAbsolutePath()));
            //System.out.println("post parsed directory: " + initialDir.getAbsolutePath());
            TFile tf = new TFile(initialDir.getAbsolutePath());
            if (!tf.exists()) {
                tf.mkdirs();
            }
            JCB_Path.addItem(tf);
        }

        for (java.nio.file.Path p : FileSystems.getDefault().getRootDirectories()) {
            JCB_Path.addItem(new TFile(p.toString()));
        }
//        JCB_FileTypes.addItem(new WepsFileFilter("Default", types));
//        JCB_FileTypes.addItem(new WepsFileFilter());
        chooserTypeList = new ArrayList<>();

        for (WepsFileTypes2 type : types) {
            //System.out.println("Type: " + type.getDescription());

            if(type.equals(WepsFileTypes2.Project)){//|| !type.equals(WepsFileTypes2.ManagementWeps)){
            JCB_FileTypes.addItem(type.getFileFilter());
            
            }
            chooserTypeList.add(type);
            
            // check if this type should allow the newDir button
            if (type.isEnableNewDir()) {
                allowNewDir = true;
            }
            if (type.isDirectory()) {
                //System.out.println("Allowing directory selection");
                setAllowDirectorySelection(true);
            } else {
                //System.out.println("Not allowing directory selection");
                setAllowDirectorySelection(false);
            }

        }
        if(JCB_FileTypes.getItemCount()<1 && types[0].equals(WepsFileTypes2.ProjDir)){
            JCB_FileTypes.addItem(types[0].getFileFilter());
        }
        JCB_FileTypes.addItem(new WepsFileFilter()); // All Files filter
        
        
        chooserType = chooserTypeList.get(0);

        boolean crlmodLoad = ConfigData.checkParmValue(ConfigData.crlmodEnabled, "1");
        for (WepsFileTypes2 type : types) {
            if (type.isManagement()) {
                if (!action.equals(Action.Save)) { // adds the CrLmod Management to the dropdown of locations if it is an open action, not a save action
                    if (crlmodLoad) {
                        System.out.println("Enabling CRLMOD databases");
                        JCB_Path.addItem(new CrLmodFile(lmodType.lmodManagement));
                    } else {
                        System.out.println("Not enabling CRLMOD databases");
                    }
                }
                // Temp during dev? MEH.
                if (ConfigData.checkParmValue("CD-WS-csip-crlmod-Management-ShowMCacheItem", "1")) {
                    JCB_Path.addItem(new TFile(About.getWepsCacheDir(), CsipLmodUtil.WepsCacheDirNameMan));
                }
                break;
            }
        }
        for (WepsFileTypes2 type : types) {
            if (type.isCrop()) {
                JCB_Path.addItem(new CrLmodFile(lmodType.lmodCrop));
                JCB_Path.addItem(new CrLmodFile(lmodType.lmodCropResidue));
                // Temp during dev? MEH.
                if (ConfigData.checkParmValue("CD-WS-csip-crlmod-Crop-ShowCacheItem", "1")) {
                    JCB_Path.addItem(new TFile(About.getWepsCacheDir(), CsipLmodUtil.WepsCacheDirNameCrop));
                }
                break;
            }
        }
        for (WepsFileTypes2 type : types) {
            if (type.isOperation()) {
                JCB_Path.addItem(new CrLmodFile(lmodType.lmodOperation));
                // Temp during dev? MEH.
                if (ConfigData.checkParmValue("CD-WS-csip-crlmod-Operation-ShowCacheItem", "1")) {
                    JCB_Path.addItem(new TFile(About.getWepsCacheDir(), CsipLmodUtil.WepsCacheDirNameOp));
                }
                break;
            }
        }
        for (WepsFileTypes2 type : types) {
            if (type.isSoil()) {
                JCB_Path.addItem(new SDMFileDatabase());

                CsipSoilFile csipSoilFile = new CsipSoilFile();
                csipSoilFile.setLatLonToCurrentUserVal();
                JCB_Path.addItem(csipSoilFile);
                // Temp during dev? MEH. // not used anymore to my knowledge CKM
//                if (ConfigData.checkParmValue("CD-WS-csip-Soil-ShowCacheItem","1")) {
//                    JCB_Path.addItem(new TFile(About.getWepsCacheDir(),CsipLmodUtil.WepsCacheDirNameSoil));
//                }

                TFile file = new TFile(ConfigData.getDefault().getDataParsed(ConfigData.SoilDB), "WEPS_baseline.mdb");
                if (file.exists()) {
                    JCB_Path.addItem(new MdbSoilFileDatabase(file));
                }

                break;
            }
        }

        //JB_Select.setText(action.getLabelTxt());
        setApproveButtonToolTipText(action.getDescription() + types[0].getButtonToolTip());
        this.setFileSelectionMode(WepsFileChooser2.SelectionType.FILES_AND_DIRECTORIES);
        // set default message if needed
        if (message == null || message.length() <= 0) {
            message = action.getDescription() + types[0].getChooserTitle();
            if (message.contentEquals("Select a Any File")) {
                message = "Select a file";
            }
        }
        setMessage(((message != null) && (message.length() > 0)) ? message
                : action.getDescription() + types[0].getChooserTitle());

        if (action == Action.Save || action == Action.Create) {
            allowNewDir = true;
            setPersistSelectedFile(true);
        }
        allowNewDir(allowNewDir);
        enableRecCheckbox(false);
    }

    public void closeChooser() {
        setVisible(false);
        dispose();
    }
    
    //The following is used to hide the inplace option from users when updating
    // a remote management file
    private boolean isUpdatingFileChooser = false;
    public void setIsUpdatingManFileChooser(boolean bolan){
        isUpdatingFileChooser = bolan;
    }
    
    public WfcPathComboBox getPath() {
        return JCB_Path;
    }

    public File showChooser() {
        // set initial path
//        TFile uncatFolder = new TFile(About.getOpDirUncat());
//        this.setCurrentDirectory(uncatFolder.getAbsolutePath());
//        this.setDefaultCurrentDirectory(uncatFolder.getAbsolutePath());
//        this.setCurrentDirectory(uncatFolder.getCanOrAbsPath());
//        System.out.println("here" + uncatFolder.getAbsolutePath());
        Display_path_label.setText(JCB_Path.getSelectedDir().getAbsolutePath());
        
        setVisible(true);
       
        return selectedFile;
    }
    
    public void setFileText(String text) {
        JTF_SelectedFile.setText(text);
    }

    public int showDialog(Component parent) {
        setLocationRelativeTo(parent);
        if (showChooser() != null) {
            return APPROVE_OPTION;
        } else {
            return ERROR_OPTION;
        }
    }

    public void homeToolTip(WepsFileChooser2 jfc) {
        java.util.Hashtable<String, String> ht = new java.util.Hashtable<>();
        ht.put("Desktop", "Home");
        Util.loadToolTips(jfc, ht);
    }
    
   /**
     * Set the text of the approve button to some pre configured options that
     * dynamically change the size of the buttons to fit.
     *
     * @param option
     */
    public void setFileFolderText(ApproveText option) {
        // MAX WIDTH IS 200 CURRENTLY
        // If adding an enum and case, please test button so it functions and set
        // the correct width and color for desired text.

        int width = 70, height = 25;
        float fontSize = 12f;
        String text = "Select"; // default value
        String typeText = "Filter type:";
        Color color = Color.BLACK;

        switch (option) {
            case FILE:
                text = "File:";
                break;
            case FOLDER:
                text = "Folder:";
//                typeText = "Folder type:";
                break;
            default:
                break;
        }
        jLabel3.setText(text);
        jLabel5.setText(typeText);
//        JB_Select.setText(text);
//        Dimension dim = new Dimension(width, height);
//        JB_Select.setPreferredSize(dim);
//        JB_Select.setFont(JB_Select.getFont().deriveFont(fontSize));
//        JB_Select.setSize(dim);
//        JB_Select.setForeground(color);
    }

    /**
     * Changes the tooltip (Hover-over) text for the 'Select' button on the
     * filechooser
     *
     * @param toolTipText
     */
    public void setApproveButtonToolTipText(String toolTipText) {
        JB_Select.setToolTipText(toolTipText);
    }

    /**
     * Used to set the approve button's text. This would be the "select" button
     * on the file chooser by default.
     */
    public static enum ApproveText {
        SELECT,
        SAVE,
        SAVE_AS,
        DELETE,
        OPEN_SELECTED_PROJECT,
        DELETE_SELECTED_PROJECT,
        OPEN_SELECTED_RUN,
        DELETE_SELECTED_RUN,
        SELECT_RUN_LOC,
        FILE,
        FOLDER
    }

    /**
     * Set the text of the approve button to some pre configured options that
     * dynamically change the size of the buttons to fit.
     *
     * @param option
     */
    public void setApproveButtonText(ApproveText option) {
        // MAX WIDTH IS 200 CURRENTLY
        // If adding an enum and case, please test button so it functions and set
        // the correct width and color for desired text.

        int width = 70, height = 25;
        float fontSize = 12f;
        String text = "Select"; // default value
        Color color = Color.BLACK;

        switch (option) {
            case SAVE:
                text = "Save";
                break;
            case SAVE_AS:
                text = "Save As";
                break;
            case DELETE:
                text = "Delete";
                color = Color.RED;
                break;
            case OPEN_SELECTED_PROJECT:
                text = "Open Selected Project";
                width = 160;
                break;
            case DELETE_SELECTED_PROJECT:
                text = "Delete Selected Project";
                width = 170;
                color = Color.RED;
                break;
            case OPEN_SELECTED_RUN:
                text = "Open Selected Run";
                width = 140;
                break;
            case DELETE_SELECTED_RUN:
                text = "Delete Selected Run";
                width = 150;
                color = Color.RED;
                break;
            case SELECT_RUN_LOC:
                text = "Select Run Loc";
                width = 150;
                break;
            case SELECT:
            default:
                break;
        }
        JB_Select.setText(text);
        Dimension dim = new Dimension(width, height);
        JB_Select.setPreferredSize(dim);
        JB_Select.setFont(JB_Select.getFont().deriveFont(fontSize));
        JB_Select.setSize(dim);
        JB_Select.setForeground(color);
    }

    /**
     * Set the text on the outermost frame of the filechooser. Appends to the
     * String "Weps File Chooser : " and should be used to provide location data
     * about where the chooser originates from.
     *
     * @param additionalText
     */
    public void setTitleText(String additionalText) {
        if (additionalText == null) {
            super.setTitle("Weps File Chooser");
        } else {
            super.setTitle("Weps File Chooser : " + additionalText);
        }
    }

    public boolean accept(File f) {
        return (JCB_FileTypes.getSelectedItem()).accept(f);
    }

    public void allowNewDir(boolean allowNewDir) {
        this.allowNewDir = allowNewDir;
    }

    public void enableDbButton(boolean enable) {
        JB_dbDir.setVisible(enable);
    }
    
    public void enableRecCheckbox(boolean enable) {
        jCheckBoxRecursive.setVisible(enable);
    }
    
    public void enableInPlaceCheckBox(boolean enable){
        jCheckBoxInPlace.setVisible(enable);
    }
    
    public void enableCfgDefLocButton(boolean enable){
        JB_DefaultDir.setVisible(enable);
    }
    
    public void enableSysTButton(boolean enable){
        systemp_button.setVisible(enable);
    }
    
    public void enableLocalTButton(boolean enable){
        loctemp_button.setVisible(enable);
    }
    
    public void enableSharedTButton(boolean enable){
       sharetemp_button.setVisible(enable);
    }
    public void enableCRMLMODTButton(boolean enable){
        crlmod_button.setVisible(enable);
    }
    
    public void enableAllManButtons(ConfigData cfd){
        if(cfd.getData(ConfigData.sysManTemp).equals("1")){
            enableSysTButton(true);
        }
        if(cfd.getData(ConfigData.locManTemp).equals("1")){
            enableLocalTButton(true);
        }
        if(cfd.getData(ConfigData.shaManTemp).equals("1")){
            enableSharedTButton(true);
        }
    }
    
    public void disableAllManButtons(){
            enableSysTButton(false);
            enableLocalTButton(false);
            enableSharedTButton(false);
    }
    // Legacy interface from WepsFileChooser.
    public void disableNewFolder(WepsFileChooser2 wfc) {
        allowNewDir(false);
    }

    public void setSelectedFile(File newFile) {
        if (newFile.getParentFile() == null) {
            newFile = new File(JCB_Path.getSelectedDir(), newFile.getName());
        } else {
            JCB_Path.addItem(newFile.getParentFile());
        }
        JTF_SelectedFile.setText(newFile.getName());
    }

    /**
     * Sets what type of selection is allowed from the SelectionType enum [
     * FILES_ONLY, DIRECTORIES_ONLY, FILES_AND_DIRECTORIES ]
     *
     * @param selectionMode - type of selection(s) permitted
     */
    public void setFileSelectionMode(SelectionType selectionMode) {
        this.selectionMode = selectionMode;
        JT_dirList.setSelectType(selectionMode);
//        if(selectionMode)
    }

    /**
     * Sets wether user can highlight and select multiple files/dir or only
     * select a single file/dir
     *
     * @param multiSelection true - select multiple files
     */
    public void setMultiSelectionEnabled(boolean multiSelection) {
        this.multiSelection = multiSelection;
        if (multiSelection) {
            JT_dirList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        } else {
            JT_dirList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        }
    }

    public void setAcceptAllFileFilterUsed(boolean b) {
        JCB_FileTypes.setAllFileFilterUsed(b);
    }

    /**
     * This sets the text present at the light gray bar at the top of the
     * fileChooser. Typically used to describe the purpose of the fileChooser.
     *
     * @param dialogTitle
     */
    public void setDialogTitle(String dialogTitle) {
        setTitle("WEPS File Chooser : " + dialogTitle);
    }

    public void setMessage(String message) {
        JL_CustomMessage.setText(message);
    }

    /**
     * Sets the large, bold font that appears between the top bar of the window
     * and the drop down menu bar that displays the path. Generally used to
     * describe what action should be taking place in the fileChooser (Select
     * File/Select Directory...etc)
     *
     * @param text
     */
    public void setText(String text) {
        setMessage(text);
    }

    /**
     * Adds a file filter that can be selected and applied on the user interface
     * from the drop down menu of available file filters
     *
     * @param filter
     */
    public void addChoosableFileFilter(javax.swing.filechooser.FileFilter filter) {
        WepsFileFilter wepsFilter = new WepsFileFilter(filter);
        JCB_FileTypes.addItem(wepsFilter);
    }

    /**
     *
     * @return The currently selected file filter for this fileChooser
     */
    public javax.swing.filechooser.FileFilter getFileFilter() {
        return JCB_FileTypes.selectedItem;
    }
    
    public String getFileFilterString(){
//        if(JCB_FileTypes.selectedItem.description.getFilters().length>0){
//            return JCB_FileTypes.selectedItem.getFilters()[0];
//        }
        return "empty";
    }

    /**
     * Applies and selects the filter, and adds to list of available file
     * filters
     *
     * @param filter Filter to be applied and added
     */
    public void setFileFilter(WepsFileFilter filter) {
        /* RIP to the memory, but while the .setSelctedItem actually applies the 
        *  file filter to the files displayed, it always displays whatever is FIRST
        *  added to the list. Which is always 'Default(*)' due to init(). Hence the 
        *  brutal switch here
         */

        ArrayList<WepsFileFilter> oldFilters = new ArrayList<>();
        // Cycles though and adds all file filters to temp arraylist
        for (int i = 0; i < JCB_FileTypes.getItemCount(); i++) {
            oldFilters.add(JCB_FileTypes.getItemAt(i));
        }
        // Clear all items
        JCB_FileTypes.removeAllItems();
        // add back, but first on the list 
        JCB_FileTypes.addItem(filter);

        oldFilters.forEach(ff -> {
            JCB_FileTypes.addItem(ff);
        });

        oldFilters.clear(); // I mean... 
//        JCB_FileTypes.setSelectedItem(filter);
    }

    /**
     * Applies and selects the filter, and adds to list of available file
     * filters
     *
     * @param filter Filter to be applied and added
     */
    public void setFileFilter(javax.swing.filechooser.FileFilter filter) {
        WepsFileFilter wepsFilter = new WepsFileFilter(filter);
        setFileFilter(wepsFilter);
    }
    
    /**
     * Same functionality for setCurrentDirectory(), but for remote files.
     *
     * @param dir
     */
    public void setCurrentDirectory_remote_file(File dir) {
        JCB_Path.addAndSelectItem(new TFile(dir.getAbsolutePath()));
        JCB_Path.setDefaultDir(new TFile(dir));
        
    }

    /**
     * Parses and sets the directory filechooser is pointing at
     *
     * @param dir
     */
    public void setCurrentDirectory(String dir) {
//        JCB_Path.setDefaultDir(new TFile(dir));
        JCB_Path.addAndSelectItem(new TFile(Util.parse(dir)));
    }
    
    public String getStartDirectory(){
        return JCB_Path.selectedItem.file.getAbsolutePath();
    }
    

    /**
     * Set the directory for clicking the "Def Loc" or default location button
     * in the file chooser. Does not set the initial directory the file chooser
     * opens up into!
     *
     * @param file
     */
    public void setDefaultDirectory(File file) {
        JCB_Path.setDefaultDir(file);
        JCB_Path.addAndSelectItem(new TFile(file));
        JCB_Path.selectDir(file.getAbsolutePath());
    }
    
    /**
     * Set the directory for clicking the "Def Loc" or default location button
     * in the file chooser. Does not set the initial directory the file chooser
     * opens up into!
     *
     * @param file
     */
    public void setCfgDefaultDirectory(File file) {
        JCB_Path.setDefaultDir(file);
        JCB_Path.addAndSelectItem(new TFile(file));
    }

    /**
     * Adds and selects File 'dir', but removes all previous file paths that
     * appear in drop down.
     *
     * @param dir
     */
    public void setCurrentDirectory_deleteOtherItems(String dir) {
        JCB_Path.deleteAll();
        JCB_Path.addAndSelectItem(new TFile(Util.parse(dir)));
        JCB_Path.setDefaultDir(new TFile(dir));
    }
    
    /**
     * Sets the default current directory for the fileChooser
     *
     * @param name
     */
    public void setDefaultCurrentDirectory(String name) {
        TFile dir = lookupDefaultDirectory(name);
        if (dir != null) {
            setCurrentDirectory(dir.getAbsolutePath());
        }
    }

    public void setAccessory(JComponent newAccessory) {
        JP_Accessory.add(newAccessory);
    }

    // From JFileChooser.
    public void updateUI() {

    }

    // From WepsFileChooser.
    public void approveSelection() {
        try {
            TFile dir = new TFile(getSelectedFile().getAbsolutePath());
            TFile runfile = dir;

            if (action == Action.Save || action == Action.Create) {		// any file name is accepted for new
                if (dir.exists()) {
                    JOptionPane.showMessageDialog(this, dir.getName()
                            + " already exists.\nPlease choose another file name.", "WEPS", JOptionPane.WARNING_MESSAGE);
                    return;
                } else if (dir.getInnerArchive() != null) {
                    //This file would be in an archive, Naughty You!!
                    JOptionPane.showMessageDialog(this, "Archives are read-only.\n"
                            + "Please choose another file location.", "WEPS", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                closeChooser();
            } else {
                if (runfile != null) {
                    //If type is PROJDIR/DIR/RUNDIR means that we are just selecting
                    //a (project) directory here and this is not a file type
                    if ((chooserType == WepsFileTypes2.ProjDir || chooserType == WepsFileTypes2.Dir
                            || chooserType == WepsFileTypes2.RunDir) && runfile.canRead()) {
                        closeChooser();
                    } //If the type is SOILDB and the currently selected filter is
                    //soilSilter, then approve the selection (directory) - neha
                    else if (chooserType == WepsFileTypes2.SoilDB) {
                        closeChooser();
                    } else if (chooserType == WepsFileTypes2.Management && runfile.canRead()
                            && (runfile.getName().toLowerCase().endsWith(chooserType.getExtension()))
                            || runfile.getName().toLowerCase().endsWith(WepsFileTypes2.XML.getExtension())) {
                        closeChooser();
                    } else if (chooserType == WepsFileTypes2.Project
                            && runfile.getName().toLowerCase().endsWith(RunFileData.ProjectSuffix)
                            && dir.getInnerArchive() != null) {
                        JOptionPane.showMessageDialog(this,
                                "Opening projects inside an archive is not allowed.\n"
                                + "Please choose a different project.", "WEPS", JOptionPane.WARNING_MESSAGE);
                        return;
                    } else if (chooserType == WepsFileTypes2.Error) {
                        //new code
                        closeChooser();
                    } else if (runfile.canRead() && runfile.getName().toLowerCase().endsWith(chooserType.getExtension())) {
                        closeChooser();
                    }
                }
            }
            //If the user selects a Directory and hits "Select" button, then that
            //Directory should be opened by setting the current dir to that dir
            // except when we want to SELECT A DIRECTORY- neha
            if (action == Action.Select && runfile.canRead() && runfile.isDirectory() && !typeIsDirectory(chooserType)) {
                setCurrentDirectory(runfile.getAbsolutePath());

            }
        } catch (HeadlessException e) {
            //System.err.println("WepsFileChooser:approveSelection:"+e);
        }
    }

    private boolean typeIsDirectory(WepsFileTypes2 type) {
        return type == WepsFileTypes2.ProjDir || type == WepsFileTypes2.Dir || type == WepsFileTypes2.RunDir;
    }

    /**
     * Returns the currently selected file/directory
     *
     * @return
     */
    public File getSelectedFile() {
        return selectedFile;
    }

    /**
     * Returns the currently selected file/directory
     *
     * @return
     */
    public TFile getSelectedTFile() {
        return (selectedFile == null) ? null : new TFile(selectedFile.getAbsolutePath());
    }

    /**
     *
     * @return a list of the currently selected files. This list can be
     * populated by enabling multiSelect
     */
    public File[] getSelectedFiles() {
        selectedFiles = JT_dirList.getCurrentSelections();
        return selectedFiles;
    }

    // From WepsFileChooser
    public static WepsFileTypes2 getType(String pTypeName) {

        if (pTypeName == null) {
            //System.err.println("WepsFileChooser:getType: " + " NullPointerException");
            return WepsFileTypes2.Error;
        }

        if (!pTypeName.startsWith(".")) {
            pTypeName = "." + pTypeName;
        }

        for (WepsFileTypes2 wft : WepsFileTypes2.values()) {
            if (wft.getExtension().contains(pTypeName)) {
                return wft;
            }
        }

        return WepsFileTypes2.values()[0];
    }

    @Override
    protected void doSelectButtonAction() {
        switch (action) {
            case Open:
            case Select:
            case Delete:
                this.doSelectFile();
                break;
            case Save:
            case Create:
                this.doNewFile();
                break;
        }
    }

    @Override
    protected void fileTypesAction() {
        JCB_FileTypes.repaint();
        JCB_FileTypes.revalidate();
        String oldName = "";
        String description = JCB_FileTypes.selectedItem.description;
        // System.out.println("Description: " + description);
        LOGGER.info("Filename Description is: " + description);
        String extension = "";
        if (description.contains(".") && description.contains(")")) {
            extension = description.substring(description.lastIndexOf('.'), description.lastIndexOf(')'));
            // System.out.println("Extension: " + extension);
            LOGGER.info("Filename Extension is: " + extension);
        } else {
            extension = "";
            // System.out.println("No Extension");
            LOGGER.info("No filename Extension specified");
        }
        
        
        // This block of code purges extensions from the file selection box.
        // Not sure why we want it, but for now i am changed it per a ticket -CKM
//        if(JTF_SelectedFile.getText().contains(".")) {
//            //oldName = JTF_SelectedFile.getText().substring(0, JTF_SelectedFile.getText().lastIndexOf('.'));
//            //System.out.println("oldName Period: " + oldName);
//        } else {
//            oldName = JTF_SelectedFile.getText();
//            //System.out.println("oldName No Period: " + oldName);
//        }

        oldName = JTF_SelectedFile.getText();
        if(oldName.endsWith(extension)){
            extension = "";
            //removes multiextensions (ie. .pdf.pdf.pdf
        }
        JTF_SelectedFile.setText(oldName + extension);
        //System.out.println("New Name: " + JTF_SelectedFile.getText());
    }
    
    /**
     * This is meant to remove the extra \Runs folder 
     * */
    private String removeExtraRun(String strDir, String fileStr){
        if(strDir.endsWith(fileStr)){return "";}
        return fileStr;
    }
    
    public void printThing(){
        System.out.println("herepac" + JCB_Path.getSelectedDir());
    }
    
    public void setToOperation(){
        File rootFile;
         boolean uncategorized = ConfigData.checkParmValue(ConfigData.noCat,"1");
            if(uncategorized){
                TFile uncatFolder = new TFile(About.getOpDirUncat());
                JCB_Path.addAndSelectItem(uncatFolder);
            }else{
                rootFile = new CrLmodFile("CRLMOD Operations", lmodType.lmodOperation);
                rootFile.listFiles();
                JCB_Path.addAndSelectItem(rootFile);
            }
    }
    
    /**
     * This will help when selecting a folder with specific extensions
     */
    private boolean correctExtension(String selectedFile){
        if(selectedFile.contains(".")){
            switch (selectedFile.substring(selectedFile.lastIndexOf('.'))){
                case ".wpj":
                    return true;
                case ".wjr":
                    return true;
                default:
                    return false;
            }
        }
        return true;
    }

    private boolean remoteOverride = false;

    /**
     * Fired when 'Select' button is hit on a file. Global variables hold the
     * location and String name of the selected file, and are used to
     * instantiate the selected file.
     */
    protected void doSelectFile() {
        String clickedFile = removeExtraRun(JCB_Path.getSelectedDir().getAbsolutePath(), JTF_SelectedFile.getText());
        selectedFile = new TFile(JCB_Path.getSelectedDir(), clickedFile);
        if(!correctExtension(selectedFile.toString())){
            selectedFile = new TFile(JCB_Path.getSelectedDir(),JTF_SelectedFile.getText());
        }//else{
//            selectedFile = new TFile(JCB_Path.getSelectedDir(), JTF_SelectedFile.getText());
//        }
//        if (this.selectionMode.compareTo(SelectionType.DIRECTORIES_ONLY) == 0 && !selectedFile.exists()) {
//            selectedFile = new TFile(JCB_Path.getSelectedDir());
//        }
        if (!allowDirectorySelection && selectedFile.isDirectory()) {
            JOptionPane.showMessageDialog(null,
                    "You have attempted to select a directory.",
                    "Directory Selected",
                    JOptionPane.WARNING_MESSAGE);
            return;
        }

        if ((selectedFile.getAbsolutePath().contains("CrLmod Managements") || selectedFile.getAbsolutePath().contains("CrLmod Operations")
                || selectedFile.getAbsolutePath().contains("CRLMOD Managements") || selectedFile.getAbsolutePath().contains("CRLMOD Operations"))
                && !selectedFile.getAbsolutePath().contains("uncat")) {
            String partialPath = "";
            if (!selectedFile.getAbsolutePath().contains("CrLmod")) {
                partialPath = selectedFile.getAbsolutePath().substring(selectedFile.getAbsolutePath().indexOf("CRLMOD"));
            } else {
                partialPath = selectedFile.getAbsolutePath().substring(selectedFile.getAbsolutePath().indexOf("CrLmod"));
            }
            String[] parts = partialPath.split("\\\\");
            if (parts.length <= 1) {
                // have to do system dependant path splitting.
                System.out.println("[CRLMOD] attempting to split path using \"/\" for *nix and OSX systems.");
                parts = partialPath.split("/");
            }

            ArrayList<CrLmodFile> files = new ArrayList<>();
            CrLmodFile rootFile;
            if (partialPath.contains("Managements")) {
                rootFile = new CrLmodFile(parts[0], lmodType.lmodManagement);
            } else if (partialPath.contains("Operations")) {
                rootFile = new CrLmodFile(parts[0], lmodType.lmodOperation);
            } else {
                System.out.println("Unknown CRLMOD Type.");
                return;
            }
            rootFile.listFiles();

            for (int i = 1; i < parts.length; i++) {
                if (i == 1) {
                    CrLmodFile firstChild = new CrLmodFile(rootFile, parts[i]);
                    files.add(firstChild);
                } else {
                    CrLmodFile laterChild = new CrLmodFile(files.get(i - 2), parts[i]);
                    files.add(laterChild);
                }
            }

            if (files.size() > 0) {
                selectedFile = files.get(files.size() - 1);
            } else {
                JOptionPane.showMessageDialog(null,
                        "Remote file not found from available data.",
                        "Remote File Error",
                        JOptionPane.ERROR_MESSAGE);
                return;
            }
            remoteOverride = true;
        }

        if (selectedFile != null && checkSelectedFileType(selectedFile)) {
            try {
                if ((selectedFile instanceof RemoteFile && selectedFile.isFile()) || remoteOverride) {

                    mainDlg.getContentPane().setCursor(getPredefinedCursor(Cursor.WAIT_CURSOR));
                    (new SwingWorker<File, Void>() {
                        @Override
                        protected File doInBackground() throws Exception {
                            File newFile = null;
                            try {
                                if (selectedFile.exists()) {
                                    newFile = selectedFile;
                                } else {
                                    System.out.println("Starting the download.");
                                    newFile = ((RemoteFile) selectedFile).downloadFile();
                                    System.out.println("Download complete.");
                                }
                            } catch (IOException e) {
                                System.err.println("Download failed.");
                            }
                            return newFile;
                        }

                        @Override
                        protected void done() {
                            try {
                                mainDlg.getContentPane().setCursor(Cursor.getDefaultCursor());
                                selectedFile = get();
                                if (selectedFile != null) {
                                    mainDlg.firePropertyChange(WepsFileChooser2.propChangeCmdStrFetchCompleted, 0, 1);
                                }
                            } catch (InterruptedException | ExecutionException ignore) {
                            }
                        }
                    }).execute();
                } else {
                    if (selectedFile instanceof TFile) {
                        if (((TFile) selectedFile).isEntry()) {
                            // If the file is in an archive ( isEntry() ), then make a new file copied out from the archive
                            File newFile = new File(getProperty("project.directory"), selectedFile.getName());
                            ((TFile) selectedFile).cp_r(newFile);
                            selectedFile = newFile;
                        }
                    }
                    // Otherwise, it should already be a file on disk, just return it.

                    if (selectedFile != null && selectedFile.exists()) {
                        File asFile = new File(selectedFile.getAbsolutePath());
                        switch (selectionMode) {
                            case FILES_ONLY:
                                System.out.println("Is it files only?");
                                if (!asFile.isFile()) {
                                    showMessageDialog(this, "Please select file, not a directory", "Invalid selection", JOptionPane.ERROR_MESSAGE);
                                } else {
                                    close();
                                }
                                break;
                            case DIRECTORIES_ONLY:
                                if (!asFile.isDirectory()) {
                                    showMessageDialog(this, "Please select directory, not a file", "Invalid selection", JOptionPane.ERROR_MESSAGE);
                                } else {
                                    close();
                                }
                                break;
                            case FILES_AND_DIRECTORIES:
                            default:
                                close();
                        }
                    } else {
                        //showMessageDialog(this, "Please make a selection", "No selection", JOptionPane.ERROR_MESSAGE);
                        close();
                    }
                }

            } catch (HeadlessException | IOException ex) {
                // LogManager.getLogger(WepsFileChooser2.class.getName()).log(Level.SEVERE, null, ex);
                LOGGER.error("doSelectFile Exception " + ex);
            }
        }
    }

    protected boolean checkSelectedFileType(File selectedFile) {
        boolean retVal = true;
        WepsFileFilter defaultFilter = JCB_FileTypes.getDefaultItem();

        if (defaultFilter != null && !defaultFilter.accept(selectedFile)) {
            int userVal;
            userVal = showConfirmDialog(this, "The file you selected does not match the requested file type.  Continue and use this file anyway?",
                    "File types mismatch", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            retVal = (userVal == JOptionPane.YES_OPTION);
        }
        return retVal;
    }

    /**
     * File filter string only used when selecting a directory, and the dir has
     * a specific pattern that allows double clicks to be used in lieu of select
     * button
     */
    private String selectFilter;

    /**
     * Whether or not the double click option is set.
     */
    private boolean doDoubleClickSelect = false;

    /**
     * Sets this instance of the file chooser to be able to select directories
     * that match the file filter with a double click. Make sure
     * DIRECTORIES_ONLY is used, or else this can potentially double paths
     *
     * @param doDoubleClick - turn on double click functionality
     * @param filterString - used to check the file extension. EX: ".wpj"
     */
    public void setDoubleClickSelect(boolean doDoubleClick, String filterString) {
        // TODO this works for now with just a string for our purposes... but 
        // could be better with a regex or some other pattern matching. FileFilters wern't working..... CKM
        doDoubleClickSelect = doDoubleClick;
        selectFilter = filterString;
    }

    // try file filter against selected file
    private boolean validDoubleClick(File file) {
        try {
            if(this.getFileFilter().toString().contains("All Files")){return false;}
            return file.getAbsolutePath().endsWith(selectFilter);
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    protected void createNewDirectory() {
        String directory = JOptionPane.showInputDialog(this, "Please specify a "
                + "name for the new directory", "Specify a new directory", JOptionPane.OK_CANCEL_OPTION);

        if (directory != null) {
            File newDir = new File(JCB_Path.getSelectedDir().getAbsoluteFile(), directory);

            if (!newDir.mkdir()) {
                showMessageDialog(this, "Cannot create the specificed directory,"
                        + " please re-specify", "Error", JOptionPane.ERROR_MESSAGE);
            }

            JCB_Path.addAndSelectItem(newDir);
            JT_dirList.doRefreshAndSelectDir(newDir);
//            JTF_SelectedFile.setText("");
        }
    }

    protected void doNewFile() {
        if (JTF_SelectedFile.getText().length() > 0) {

            selectedFile = new File(JCB_Path.getSelectedDir(), JTF_SelectedFile.getText());

            if (selectedFile.exists()) {
                int response = showConfirmDialog(this, "File already exists. Replace?", "Warning", JOptionPane.WARNING_MESSAGE);
                if (response != YES_OPTION && response != OK_OPTION) {
                    selectedFile = null;
                }
            } else {
                WepsFileFilter f = (WepsFileFilter) this.getFileFilter();
                // Need to check if the extension is not being typed in
                for (String filter : f.getFilters()) {
                    if (filter.compareTo("*") == 0) {
                        // all filters
                        for (String filepath : JCB_Path.getSelectedDir().list()) {
                            String filename = filepath;
                            if (filepath.contains(".")) {
                                filename = filepath.substring(0, filepath.lastIndexOf("."));
                            }
                            if (filename.equals(JTF_SelectedFile.getText())) {
                                selectedFile = new File(JCB_Path.getSelectedDir(), filepath);
                            }
                        }
                    } else { // not all filters!
                        // if filter has a * match ex: *.wpj
                        String fileSelected = JTF_SelectedFile.getText();
                        if (filter.contains("*")) {
                            filter = filter.substring(1);
                        }

                        if (!fileSelected.toLowerCase().contains(filter)) {
                            fileSelected = fileSelected + filter;
                        } else {
                            fileSelected = fileSelected.substring(0, fileSelected.length() - 4) + filter;
                        }

                        selectedFile = new TFile(JCB_Path.getSelectedDir(), fileSelected);
                    }
                }
            }
        }
        close();
    }

    // From WepsFileChooser
    public TFile lookupDefaultDirectory(String name) {

        //a few tricky cases, when MCREW_CFG should be the parent
        if (ConfigData.SkelTranslationFile.equals(name) || ConfigData.McrewDataConfigFile.equals(name)) {
            String path = ConfigData.getDefault().getDataParsed(ConfigData.MCREW);
            if (path != null) {
                return new TFile(path);
            }
        } else {
            ConfigData.FileConfigurationOption option = ConfigData.getDefault().getFileConfigurationOption(name);
            if (option != null) {
                String path = option.defaultLocation();
                if (path != null && path.length() > 0) {
                    return new TFile(path);
                }
            }
        }

        return null;
    }

    /**
     * Helper method to return the appropriate text to set Display_path_label to
     * based on the files being looked at
     *
     * @return String of text to set for path
     */
    private String pathHelper() {
        File current_dir = JT_dirList.getDisplayingDir();
        if (current_dir instanceof RemoteFile) {
            //not letting user update remote file in place
            if(isUpdatingFileChooser){ 
                jCheckBoxInPlace.setVisible(false);
                jCheckBoxInPlace.setSelected(false);
            }
            if (current_dir.getAbsolutePath().equals("CrLmod Managements") || current_dir.getAbsolutePath().equals("CRLMOD Managements")) {
                return current_dir.getAbsolutePath() + " (remote file)";
            } else if (current_dir.getAbsolutePath().startsWith("CrLmod Managements") || current_dir.getAbsolutePath().startsWith("CRLMOD Managements")) {
                return current_dir.getAbsolutePath().substring(19) + " (remote file)";
            } else // default remote file behavior
            {
                return current_dir.getAbsolutePath() + " (remote file)";
            }
        } else {
            if(isUpdatingFileChooser){jCheckBoxInPlace.setVisible(true);}
            
            // default regular file behavior
            return current_dir.getAbsolutePath();
        }
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        
        if (evt.getPropertyName().equals(WepsFileChooser2.propChangeCmdStrFetchCompleted)) {
            // This is triggered when a remote file is finished downloading
            close();
        } else if (evt.getPropertyName().equals(WfcFileListTable.propChangeCmdSetFilename)) {
            Display_path_label.setText(pathHelper());
            if (Display_path_label.getText().length() > 70) {
                // once the path gets too long, call pack on the window to fit all
                this.pack();
            }
            super.propertyChange(evt); // pass up the chain still
        } else if (evt.getPropertyName().equals(WfcFileListTable.singleClickSelect)) {
            // set the text of the selected file box for use and saving
            File f = (File) evt.getNewValue();
            JTF_SelectedFile.setText(f.getName());
            if (f.getName().length() > 68) {
                /// This helps if a user single clicks a file, and the name
                // is longer than the chooser itself.
                this.pack();
            }
            super.propertyChange(evt); // pass up the chain still
        } else if (evt.getPropertyName().equals(WfcFileListTable.doubleClickSelect)) {
            // set the text of the selected file box for use and saving
            File f = (File) evt.getNewValue();
            if (doDoubleClickSelect) {
                if (validDoubleClick( f.getAbsoluteFile())) //doSelectFile();
                {
                    doSelectButtonAction();
                }
            }
            super.propertyChange(evt);
            
        } else if (WfcPathComboBox.propChangeCmdStrUpdatePath.equals(evt.getPropertyName())) {
            // double click into dir
            if (doDoubleClickSelect) {
                if (validDoubleClick((File) evt.getNewValue())) //doSelectFile();
                {
                    doSelectButtonAction();
                }
            }
            super.propertyChange(evt);
        } else {
            super.propertyChange(evt);
        }
    }

}
