package usda.weru.soil;

import de.schlichtherle.truezip.file.TFile;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import java.beans.*;
import java.io.File;
import java.io.FileNotFoundException;
import javax.help.*;
import usda.weru.util.About;
import usda.weru.util.AboutDialog;
import usda.weru.util.ConfigData;
import usda.weru.util.Help;
import usda.weru.util.Util;
import usda.weru.util.wepsFileChooser2.WepsFileChooser2;
import usda.weru.util.wepsFileChooser2.WepsFileTypes2;
import usda.weru.weps.RunFileData;
import usda.weru.weps.Weps;


final public class Soil extends usda.weru.soil.gui.SoilUI_n implements PropertyChangeListener {

    private static final long serialVersionUID = 1L;

    public static final String WindowClosing = "Soil-WindowClosing";
    IFC ifcptr;    //variables for help system
    public HelpBroker hb_soil;
    private String projectsPath = "";
    String inputSoilName;
    String viewitem;
    String dbName = "";
    String prjName = "";
    private final String soiluiid = "WEPS Soil User Interface";
    private boolean selFlg;
    private boolean c_readonly = false;
    private boolean c_estimate = false;
    Grid GridID = null;
    Grid GridSurfProp = null;
    Grid GridLayrProp = null;
    private static double rockFrag = 0.0;
    private static double slope = 0.0;
    
    String workingDirectory = "sweep";
    String soilDB = "db/soil";
//    static private String cfgFile = "cfg/sweep.cfg";
    SoilChooser c_soilChooser = null;
    
    int initflg = 0;
    
    static {
        openSoilWindows = new Vector<>();
    }
    static Vector<Soil> openSoilWindows;

    public static boolean isOpen() {
        return Soil.openSoilWindows.size() > 0;
    }


    public Soil(String fileName) {
        this(fileName, "", "");
    }

    public Soil(String fileName, String prjName, String dbName) {
        super();
        if (Soil.openSoilWindows.contains(this) == false) {
            Soil.openSoilWindows.add(this);
        }
        this.prjName = prjName;
        this.dbName = dbName;
        this.changes = new PropertyChangeSupport(this);


        setResizable(true);

        setLocation(50, 50);

        Dimension d = getSize();
        d.height -= 60;
        d.width -= 10;
        //Setting the Icon Image in the title bar
        super.setIconImage(About.getWeruIconImage());

        addPopupMenu();
        Util.loadToolTips((Container) this, new TFile("cfg", "soiltooltips.cfg"));
        addHelp();  //make addHelp active by JG
        
        initializeGui(fileName);
    }
    
    protected void initializeGui (String fileName) {
        inputSoilName = fileName;
        setTitle(soiluiid + "Initial Field Conditions " + inputSoilName);
        
        ifcptr = new IFC();
        try {
            ifcptr.readIfc(inputSoilName);
            setMenuEnable("Save", true);
            setMenuEnable("Save As", true);
            setMenuEnable("Print", true);
            slope = ifcptr.surfaceSlope;
            if (ifcptr.fractionRock != null) {
                rockFrag = ifcptr.fractionRock[0];
            }
        } catch (FileNotFoundException e) {
        }
        
        setLayerData();
        repaint();
        validate();
    }
    
    protected void clearGui () {
        JP_soilIdentity.removeAll();
        JP_soilSurfaceProp.removeAll();
        JP_soilLayerProp.removeAll();
    }

    public static double getRockFrag() {
        return rockFrag;
    }
    
    public static void setRockFrag(double newFrag) {
        rockFrag = newFrag;
    }
    
    public static double getSlope() {
        return slope;
    }
    
    public static void setSlope(double newSlope) {
        slope = newSlope;
    }
    
    @Override
    public void setVisible(boolean b) {
        if (inputSoilName == null || inputSoilName.trim().length() == 0) {
            newFile();
        }
        super.setVisible(b);
    }

    private void commitEdits() {
        GridID.commitEdit(true);
        GridLayrProp.commitEdit(true);
        GridSurfProp.commitEdit(true);
    }

    public void updateEstimateButtons() {
        boolean estimate = c_estimate && selFlg && !c_readonly;

        JB_estimate.setEnabled(estimate);
        estimateItem.setEnabled(estimate);
    }

    public void setReadonly(boolean readonly) {
        if (readonly) {
            Soil.openSoilWindows.remove(this);
        } else {
            if (Soil.openSoilWindows.contains(this) == false) {
                Soil.openSoilWindows.add(this);
            }
        }
        c_readonly = readonly;
        //Buttons
        JB_open.setEnabled(!readonly);
        JB_open.setVisible(!readonly);
        JB_save.setEnabled(!readonly);
        JB_save.setVisible(!readonly);
        JB_copy.setEnabled(!readonly);
        JB_copy.setVisible(!readonly);
        JB_cut.setEnabled(!readonly);
        JB_cut.setVisible(!readonly);
        JB_paste.setEnabled(!readonly);
        JB_paste.setVisible(!readonly);
        openItem.setEnabled(!readonly);
        openItem.setVisible(!readonly);
        JB_estimate.setVisible(!readonly);

        //Menus
        M_edit.setEnabled(!readonly);
        M_edit.setVisible(!readonly);

        //Menu Items
        newItem.setEnabled(!readonly);
        newItem.setVisible(!readonly);
        
        //Larry wants these items visible and enabled regardless of read-only mode being enabled or not -DB
        //saveAsItem.setEnabled(!readonly);
        //saveAsItem.setVisible(!readonly);
        //saveAsTemplateItem.setEnabled(!readonly);
        //saveAsTemplateItem.setVisible(!readonly);
        
        saveItem.setVisible(!readonly);
        saveItem.setVisible(!readonly);
        openRemoteDB.setEnabled(!readonly);
        openRemoteDB.setVisible(!readonly);

        //Pass to tables
        if (GridID != null) {
            GridID.setReadonly(readonly);
        }
        if (GridLayrProp != null) {
            GridLayrProp.setReadonly(readonly);
        }
        if (GridSurfProp != null) {
            GridSurfProp.setReadonly(readonly);
        }
    }

    public boolean getReadonly() {
        return c_readonly;
    }

    public void refreshPanels() {
        Weps.getInstance().getSimulationPanel().updateSoilValues(RunFileData.SoilFile);
        Weps.getInstance().getSimulationPanel().setRockFragValue(rockFrag);
        Weps.getInstance().getSimulationPanel().setSoilSlopeValue(slope);
        Weps.getInstance().getAuxPanel().repaint();
        Weps.getInstance().getAuxPanel().revalidate();
        Weps.getInstance().getSimulationPanel().repaint();
        Weps.getInstance().getSimulationPanel().revalidate();
        
    }
    
    protected void newFile() {
        setMenuEnable("Save", false);
        setMenuEnable("Save As", true);
        setMenuEnable("print", true);
//        ifcptr = new IFC(1);
//        viewLayers();
        if (JB_estimate.isVisible()) {
            selFlg = true;
            updateEstimateButtons();
            if (GridLayrProp != null) {
                GridID.displayColumns("select");
                GridSurfProp.displayColumns("select");
                GridLayrProp.displayColumns("select");
            }
            all.setState(!selFlg);
            select.setState(selFlg);
        }
        initializeGui ("");
        setTitle(soiluiid + "Initial Field Conditions New File");
    }

    protected void openFile() {
        WepsFileChooser2 wfc = new WepsFileChooser2(WepsFileTypes2.Soil, projectsPath, WepsFileChooser2.Action.Open);
        wfc.disableNewFolder(wfc);
        wfc.setSoilChooser();
        wfc.setDBDir(new File(Util.getProperty("weps.database_dir") + "/soil"));
        wfc.enableLocalTButtonOnly();
        wfc.setCurrentDirectory(projectsPath);
        if (wfc.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            initializeGui (wfc.getSelectedFile().getAbsolutePath());
            setMenuEnable("Save", true);
            setMenuEnable("Save As", true);
            setMenuEnable("print", true);
        }
    }

    public void progExit() {
        Soil.openSoilWindows.remove(this);
        if (changes != null) {
            changes.firePropertyChange(WindowClosing, null, "true");
//            changes.firePropertyChange(RunFileData.SoilFile, null, inputSoilName);
            if(!c_readonly && changed) {
                Object[] options = {"Save Changes", "Exit Without Saving"};
                int n = JOptionPane.showOptionDialog(this,
                "Would you like to save your changes prior to exiting?", "Save Soil Changes",
                JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
                null, options, options[1]);
                if(n == 0) {
                    saveIfc();
                    System.out.println("Rock/Slope Values: " + rockFrag + ", " + slope);
                    Weps.getInstance().getSimulationPanel().setRockFragValue(rockFrag);
                    Weps.getInstance().getSimulationPanel().setSoilSlopeValue(slope);
                }
            }
        }
        changed = false;
        dispose();
        Util.debugPrint("exit called");
    }

    public void saveIfc() {
        System.err.println("Universal save method?");
        if (inputSoilName == null || inputSoilName.trim().isEmpty()) {
            saveAsIfc();
            return;
        }
        commitEdits();
        Util.debugPrint(true, "<< " + inputSoilName);
        String dir = "";
        String outputSoilNm = "";
        if (ifcptr != null && inputSoilName != null) {
            int index = inputSoilName.lastIndexOf('\\');
            if (index > 0) {
                dir = inputSoilName.substring(0, index);
                outputSoilNm = inputSoilName.substring(index);
            }
            Util.debugPrint("SoilUI : saveIfc : Dir name is : " + dir);
            Util.debugPrint("SoilUI : saveIfc : Soil Name ONLY is : " + outputSoilNm);
            Util.debugPrint("SoilUI : saveIfc : Soil Name is : " + inputSoilName);
//            ifcptr.writeNewIfc(new TFile(dir, outputSoilNm).getAbsolutePath(), changes);
            TFile soilFile = new TFile (inputSoilName);
            if (soilFile != null) {
                ifcptr.writeNewIfc(soilFile.getAbsolutePath(), changes);
            }
            rockFrag = ifcptr.fractionRock[0];
            slope = ifcptr.surfaceSlope;
        }
        refreshPanels();
    }

    public void saveAsIfc() {
        commitEdits();
        WepsFileChooser2 wfc = new WepsFileChooser2(WepsFileTypes2.Soil, prjName, WepsFileChooser2.Action.Save);
        wfc.setSoilChooser();
        wfc.setDBDir(new File(Util.getProperty("weps.database_dir") + "/soil"));
        wfc.enableLocalTButtonOnly();
        wfc.setCurrentDirectory(prjName);
        TFile soilFile;
        if (inputSoilName == null || inputSoilName.trim().isEmpty()) {
            soilFile = Util.incrementFileName(new TFile(prjName, "new_soil.ifc"));
        } else {
            soilFile = Util.incrementFileName(new TFile(inputSoilName));
        }

        wfc.setPersistSelectedFile(true);
        wfc.setSelectedFile(soilFile);
        wfc.setText(soilFile.getName());
        wfc.setApproveButtonText(WepsFileChooser2.ApproveText.SAVE);
        if (wfc.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            inputSoilName = wfc.getSelectedFile().getAbsolutePath();
            if (ifcptr != null && inputSoilName != null) {
                ifcptr.writeNewIfc(inputSoilName, changes);
                setTitle(soiluiid + "  " + inputSoilName);
            } else {
            }
        }
        refreshPanels();
    }

    public void saveAsIfcTemplate() {
        commitEdits();
        WepsFileChooser2 wfc = new WepsFileChooser2(WepsFileTypes2.Soil, ConfigData.getDefault().getDataParsed(ConfigData.LocalSoilDB), WepsFileChooser2.Action.Save);
        wfc.setSoilChooser();
        wfc.setDBDir(new File(Util.getProperty("weps.database_dir") + "/soil"));
        wfc.enableLocalTButtonOnly();
        String soilDbPath = ConfigData.getDefault().getDataParsed(ConfigData.LocalSoilDB);

        wfc.setCurrentDirectory(soilDbPath);
        TFile soilFile;

        if (inputSoilName == null || inputSoilName.trim().isEmpty()) {
            soilFile = Util.incrementFileName(new TFile(soilDbPath, "new_soil.ifc"));
        } else {
            soilFile = Util.incrementFileName(new TFile(soilDbPath, new TFile(inputSoilName).getName()));
        }

        wfc.setPersistSelectedFile(true);
        wfc.setSelectedFile(soilFile);
        wfc.setText(soilFile.getName());
        if (wfc.showDialog(this) == WepsFileChooser2.APPROVE_OPTION) {
            inputSoilName = wfc.getSelectedFile().getAbsolutePath();
            if (ifcptr != null && inputSoilName != null) {
                ifcptr.writeNewIfc(inputSoilName, changes);
                setTitle(soiluiid + "  " + inputSoilName);
            }
        }
        refreshPanels();
    }

    void getSQL() {
        if (dbName.length() == 0) {
            dbName = JOptionPane.showInputDialog(this, "Enter database name (" + this.dbName + ")");
            if (dbName.length() == 0) {
                Util.debugPrint("SUI_gSQL: return null");
                return;
            }
        }
        SoilChooser sc = new SoilChooser(this, new TFile(prjName), new TFile(dbName), changes);
        sc.setVisible(true);
    }

    @Override
    protected void openRemoteDBActionPerformed(java.awt.event.ActionEvent evt) {
        if (c_soilChooser == null) {
            System.out.println("soilDB " + (new TFile(soilDB)).getAbsolutePath());
            System.out.println("working " + (new TFile(workingDirectory)).getAbsolutePath());
            c_soilChooser = new SoilChooser(this, new TFile(workingDirectory), new TFile(soilDB), changes);
        }
        c_soilChooser.setSize(new java.awt.Dimension(500, 500));
        c_soilChooser.setVisible(true);
    }

    protected void editDelete() {
        if (GridLayrProp.showPopup()) {
            GridLayrProp.deleteRow();
            //	pack();
            validate();
            repaint();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    protected void editBeforeInsert() {
        if (GridLayrProp.showPopup()) {
            GridLayrProp.insertRowBefore();
            //	pack();
            validate();
            repaint();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    protected void editAfterInsert() {
        if (GridLayrProp.showPopup(true)) {
            GridLayrProp.insertRowAfter();
            //	pack();
            validate();
            repaint();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    protected void editCut() {
        if (GridLayrProp.showPopup()) {
            GridLayrProp.cutRow();
            //	pack();
            validate();
            repaint();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    protected void editCopy() {
        if (GridLayrProp.showPopup()) {
            GridLayrProp.copyRow();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    protected void editBeforePaste() {
        if (GridLayrProp.showPopup()) {
            GridLayrProp.pasteBeforeRow();
            validate();
            repaint();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    protected void editAfterPaste() {
        if (GridLayrProp.showPopup(true)) {
            GridLayrProp.pasteAfterRow();
            validate();
            repaint();
        } else {
            JOptionPane.showMessageDialog(this,
                    "Invalid selection", "Error editing layers", JOptionPane.ERROR_MESSAGE);
        }
    }

    @Override
    public void HelpJMI_actionPerformed(java.awt.event.ActionEvent evt) {
        //implementing via addHelp
    }

    @Override
    public void AboutJMI_actionPerformed(java.awt.event.ActionEvent evt) {
        AboutDialog JAboutDialog1 = new AboutDialog(this, usda.weru.util.Application.SOILUI);
        JAboutDialog1.setModal(true);
        JAboutDialog1.setVisible(true);
    }

    protected void addHelp() {
        //Skip loading the helpset if we already have it in memory
        if (Help.hasHelpSet("SOIL") == false) {
            loadHelp();
        }

        addCSH(Help.getHelpSet());
    }

    private void loadHelp() {
        String dirFilePath = "help/soil1/soil.hs";
        String soilJarPath = "jar/SoilHelp.jar";
        String jarFilePath = "jar/MasterHelp.jar";

        if (Help.loadJar(jarFilePath, "soil1/soil.hs")) {
            return;
        } else if (Help.loadJar(soilJarPath)) {
            return;
        } else if (Help.loadDirectory(dirFilePath)) {
            return;
        }
    }

    private void addCSH(HelpSet hs_soil) {
        hb_soil = hs_soil.createHelpBroker();
        hb_soil.enableHelpKey(getRootPane(), "SoilIntro_html", hs_soil);
        hb_soil.enableHelpOnButton(helpJMI, "SoilIntro_html", hs_soil);
        hb_soil.enableHelpOnButton(JB_help, "SoilIntro_html", hs_soil);
        ActionListener helper = new CSH.DisplayHelpFromSource(hb_soil);
        //System.out.println("I am in the SOIL addHelp()" + helper);
        helpJMI.addActionListener(helper);

        //contextsensitive help
        JB_CSH.addActionListener(new CSH.DisplayHelpAfterTracking(hs_soil, "javax.help.SecondaryWindow", null));
        CSH.setHelpIDString(MB_main, "soilMenuBar_html");
        CSH.setHelpIDString(M_file, "soilMenuFile_html");
        CSH.setHelpIDString(M_edit, "soilMenuEdit_html");
        CSH.setHelpIDString(M_view, "soilMenuView_html");
        CSH.setHelpIDString(M_help, "soilMenuHelp_html");
        CSH.setHelpIDString(toolbar, "soilButtonBar_html");
        CSH.setHelpIDString(JTB_main, "soilButtonBar_html");
        CSH.setHelpIDString(JB_open, "SoilbuttonOpen_html");
        CSH.setHelpIDString(JB_save, "SoilbuttonSave_html");
        CSH.setHelpIDString(JB_cut, "SoilbuttonCut_html");
        CSH.setHelpIDString(JB_copy, "SoilbuttonCopy_html");
        CSH.setHelpIDString(JB_paste, "SoilbuttonPaste_html");
        CSH.setHelpIDString(JB_print, "SoilbuttonPrint_html");
        CSH.setHelpIDString(JB_estimate, "SoilbuttonEST_html");
        CSH.setHelpIDString(JB_help, "SoilbuttonHelp_html");
        CSH.setHelpIDString(JB_close, "SoilbuttonClose_html");
        CSH.setHelpIDString(JP_soilIdentity, "soilIdentification_html");
        CSH.setHelpIDString(JP_soilSurfaceProp, "soilSurface_html");
        CSH.setHelpIDString(JP_soilLayerProp, "soilLayer_html");
        CSH.setHelpIDString(JSP_text, "soilTextArea_html");
        CSH.setHelpIDString(JTA_warningText, "soilTextArea_html");

    }

//    public void viewLayers(String fileName) {
//        inputSoilName = filnam;
//        viewLayers();
//        initializeGui(fileName);
//    }

    public void setLayerData() {
        clearGui ();
        
        if (ifcptr == null) {
            return;
        }
        if (ifcptr.nsl == 0) {
            return;
        }
        setTitle(soiluiid + "  " + inputSoilName);

        //		tables.removeAll();
//        JP_soilIdentity.removeAll();
        GridID = new Grid(ifcptr, 1);
        //tables.add(GridID, BorderLayout.NORTH);
        JP_soilIdentity.add(GridID, BorderLayout.CENTER);

//        JP_soilSurfaceProp.removeAll();
        GridSurfProp = new Grid(ifcptr, 2);
        //tables.add(GridSurfProp, BorderLayout.NORTH);
        JP_soilSurfaceProp.add(GridSurfProp, BorderLayout.CENTER);

//        JP_soilLayerProp.removeAll();
        GridLayrProp = new Grid(ifcptr, 3);
        //tables.add(GridLayrProp, BorderLayout.NORTH);
        JP_soilLayerProp.add(GridLayrProp, BorderLayout.CENTER);
        JP_soilLayerProp.addMouseListener(popupListener);
        GridLayrProp.addMouseListener(popupListener);

//		JTA_warningText.removeAll();
        JTA_warningText.setText(ifcptr.errorsInIfcFile);
//		JSP_text.getVerticalScrollBar().setValue(0);
//		JTA_warningText.insert("", 0);
//		JViewport jvt = JSP_text.getViewport();
//		jvt.setViewPosition(new java.awt.Point(0,0));
        ifcptr.setGrids(GridID, GridSurfProp, GridLayrProp, JTA_warningText);

        getContentPane().invalidate();
        getContentPane().validate();
        getContentPane().repaint();

        JSP_text.getVerticalScrollBar().setValue(0);
        setReadonly(c_readonly);
    }

    public static void main(String[] args) {
        System.setProperty("line.separator", "\n");	// make file line separator unix compatible
        String x = "";
        String mainConfig = "cfg/weps.cfg";
        String userConfig = null;
        //if the user config is not set use the name of the main config file
        if (userConfig == null) {
            userConfig = About.getUserWeps().getAbsolutePath() + "/" + new TFile(mainConfig).getName();
        }
        ConfigData.getDefault().load(new TFile(mainConfig), new TFile(userConfig));

        new Soil(x).setVisible(true);
    }

    @Override
    public void addNotify() {
        // Record the size of the window prior to calling parents addNotify.
        super.addNotify();
    }

    protected void printIfc() {
        PrintJob pj = getToolkit().getPrintJob(this,
                "Print IFC file", new Properties());
        if (pj == null) {
            return;
        }
        ifcptr.printIfc(pj);
        pj.end();
    }

    void setMenuEnable(String nam, boolean enabled) {
        JMenuBar mb = this.MB_main;
        for (int idx = 0; idx < mb.getMenuCount(); idx++) {
            JMenu menu = mb.getMenu(idx);
            for (int jdx = 0; jdx < menu.getItemCount(); jdx++) {
                JMenuItem mi = menu.getItem(jdx);
                try {
                    if (nam.equalsIgnoreCase(mi.getActionCommand())) {
                        mi.setEnabled(enabled);
                        return;
                    }
                } catch (java.lang.NullPointerException e) {
                }
            }
        }
    }

    @Override
    public void propertyChange(PropertyChangeEvent e) {
        if (e.getPropertyName().equals(ConfigData.SoilDB)) {
            //dbName = new String((String) e.getNewValue());
        } else if (e.getPropertyName().equals(ConfigData.CurrentProj)) {
            prjName = Util.parse(e.getNewValue().toString());
        } else if (e.getPropertyName().equals(ConfigData.ProjDir)) {
            projectsPath = (String) e.getNewValue();
            projectsPath = new TFile(Util.parse(projectsPath)).getAbsolutePath();
        } else if (e.getPropertyName().equals(ConfigData.SoilEstimate)) {
            if (e.getNewValue().toString().equals("1")) {
                c_estimate = true;
            } else {
                c_estimate = false;
            }
            updateEstimateButtons();
        } else if (e.getPropertyName().equals(ConfigData.SoilDB)) {
            soilDB = (String) e.getNewValue();
        } else if (e.getPropertyName().equals(ConfigData.SWEEPWorkDir)) {
            workingDirectory = (String) e.getNewValue();
        }
    }
    private PropertyChangeSupport changes = new PropertyChangeSupport(this);

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

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

    @Override
    protected void JBClose_ActionPerformed(java.awt.event.ActionEvent evt) {
        progExit();
    }

    protected void SoilUI_componentResized(java.awt.event.ComponentEvent evt) {
    }

    @Override
    protected void MI_new_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        newFile();
    }

    @Override
    protected void MI_open_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        openFile();
    }

    @Override
    protected void MI_save_ActionPerformed(java.awt.event.ActionEvent evt) {
        saveIfc();
    }

    @Override
    protected void MI_saveAs_ActionPerformed(java.awt.event.ActionEvent evt) {
        saveAsIfc();
    }

    @Override
    protected void saveAsTemplateItem_actionPerformed(ActionEvent evt) {
        saveAsIfcTemplate();
    }

    @Override
    protected void MI_print_ActionPerformed(java.awt.event.ActionEvent evt) {
        printIfc();
    }

    protected void MI_getSQL_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        getSQL();
    }

    protected void MI_batch_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
    }

    @Override
    protected void MI_exit_ActionPerformed(java.awt.event.ActionEvent evt) {
        progExit();
    }

    @Override
    protected void MI_cut_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editCut();
    }

    @Override
    protected void MI_copy_ActionPerformed(java.awt.event.ActionEvent evt) {
        editCopy();
    }

    @Override
    public void pasteBeforeJMI_actionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editBeforePaste();
    }

    @Override
    protected void MI_pasteAfter_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editAfterPaste();
    }

    @Override
    protected void insertBeforeItem_actionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editBeforeInsert();
    }

    @Override
    protected void insertAfterItem_actionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editAfterInsert();
    }

    @Override
    protected void deleteItem_actionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editDelete();
    }

    protected void MI_help_ActionPerformed(java.awt.event.ActionEvent evt) {

    }

    @Override
    protected void JB_open_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        openFile();
    }

    @Override
    protected void JB_save_ActionPerformed(java.awt.event.ActionEvent evt) {
        saveIfc();
    }

    @Override
    protected void JB_cut_ActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        editCut();
    }

    @Override
    protected void JB_copy_ActionPerformed(java.awt.event.ActionEvent evt) {
        editCopy();
    }

    @Override
    protected void JB_paste_ActionPerformed(java.awt.event.ActionEvent evt) {
        //This is called when the tool button Paste is clicked.
        changed = true;
        editBeforePaste();
    }

    @Override
    protected void JB_print_ActionPerformed(java.awt.event.ActionEvent evt) {
        printIfc();
    }

    @Override
    protected void exitForm(java.awt.event.WindowEvent evt) {
        progExit();
    }

    @Override
    protected void selectItemStateChanged(java.awt.event.ItemEvent evt) {
        changed = true;
        if (evt.getStateChange() != java.awt.event.ItemEvent.SELECTED) {
            return;
        }
        selFlg = true;
        updateEstimateButtons();
        if (GridLayrProp != null) {
            GridID.displayColumns("select");
            GridSurfProp.displayColumns("select");
            GridLayrProp.displayColumns("select");
        }
    }

    @Override
    protected void allItemStateChanged(java.awt.event.ItemEvent evt) {
        changed = true;
        if (evt.getStateChange() != java.awt.event.ItemEvent.SELECTED) {
            return;
        }
        selFlg = false;
        updateEstimateButtons();
        if (GridLayrProp != null) {

            setLayerData();
            GridID.displayColumns("all");
            GridSurfProp.displayColumns("all");
            GridLayrProp.displayColumns("all");
        }
    }

    @Override
    protected void JB_estimateActionPerformed(java.awt.event.ActionEvent evt) {
        changed = true;
        commitEdits();
        try {
            ifcptr.estimateFactors();
        } catch (IllegalStateException ise) {
            return;
        }
        selFlg = false;
        updateEstimateButtons();
        all.setState(!selFlg);
        select.setState(selFlg);
        if (GridLayrProp != null) {
            setLayerData();
            GridID.displayColumns("all");
            GridSurfProp.displayColumns("all");
            GridLayrProp.displayColumns("all");
        }
    }
    private JPopupMenu popup, headerPopup;
    private Vector<MenuElement> popupVec;
    private MouseListener popupListener;

    private void addPopupMenu() {
        MenuElement[] menuElements;

        popup = new JPopupMenu();

        popupVec = new Vector<>();

        JMenuItem jmi = new javax.swing.JMenuItem();
        // Now follws multiple row operations
        jmi.setText("Cut Row");
        jmi.setActionCommand("Cut ");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editCut();
            }
        });
        popup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Copy Row");
        jmi.setActionCommand("Copy");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editCopy();
            }
        });
        popup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Paste Before Row");
        jmi.setActionCommand("Paste Before Row");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editBeforePaste();
            }
        });
        popup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Paste After Row");
        jmi.setActionCommand("Paste After Row");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editAfterPaste();
            }
        });
        popup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Insert Before Row");
        jmi.setActionCommand("Insert Before Row");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editBeforeInsert();
            }
        });
        popup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Insert After Row");
        jmi.setActionCommand("Insert After Row");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editAfterInsert();
            }
        });
        popup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Delete Row");
        jmi.setActionCommand("Delete Row");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editDelete();
            }
        });
        popup.add(jmi);

        //header popup
        headerPopup = new JPopupMenu();

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Paste");
        jmi.setActionCommand("Paste");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editAfterPaste();
            }
        });
        headerPopup.add(jmi);

        jmi = new javax.swing.JMenuItem();
        jmi.setText("Insert");
        jmi.setActionCommand("Insert");
        jmi.addActionListener(new java.awt.event.ActionListener() {

            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editAfterInsert();
            }
        });
        headerPopup.add(jmi);

        menuElements = popup.getSubElements();
        popupVec.addAll(Arrays.asList(menuElements));

        Util.debugPrint(true, "popup menu added");
        popupListener = new PopupListener();
        JP_soilLayerProp.addMouseListener(popupListener);
    }

    class PopupListener extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {

            //System.out.println("Mcrew: mousepressed:");
            maybeShowPopup(e);
            Util.debugPrint(true, "mouse pressed -- current row " + GridLayrProp.getCurrentRow());
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            //System.out.println("Mcrew: released:");
            maybeShowPopup(e);
        }

        private void maybeShowPopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
                e.consume();
                //Show the popup menu only when the entire row is selected - neha
                if (GridLayrProp.showPopup()) {
                    popup.show(e.getComponent(), e.getX(), e.getY());
                } else if (GridLayrProp.showHeaderPopup()) {
                    headerPopup.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        }
    }
}
