/*
 * RunManager.java
 *
 * Created on January 24, 2006, 3:44 PM
 *
 */
package usda.weru.wmrm;

import java.util.List;
import usda.weru.weps.*;

import usda.weru.util.*;
import java.beans.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import com.klg.jclass.table.*;
import com.klg.jclass.table.data.JCVectorDataSource;
import de.schlichtherle.truezip.file.TFile;
import java.awt.CardLayout;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Rectangle;
import java.awt.print.PageFormat;
import java.io.IOException;
import usda.weru.weps.reports.ReportManager;
import javax.swing.JCheckBoxMenuItem;

/**
 *
 * @author joelevin
 */
public class Wmrm extends usda.weru.wmrm.gui.Wmrm_n implements JCTableDataListener,
        PropertyChangeListener, TreeSelectionListener, TreeWillExpandListener,
        KeyListener, JCResizeCellListener {

    private static final long serialVersionUID = 1L;

    private final Application c_app = Application.WMRM;
    private final TFile configFile = new TFile("wmrm/wmrm_table.xml").getCanOrAbsFile();
    private ConvertedValueCellRenderer c_convertedValueCellRenderer;
    private String c_projectsPath;
    private DataModel c_model;
    private TableMeta c_meta;
    private String c_unitsSystem;
    // keeps track of which column is being sorted by
    // initialize to -1 because there is no sorting to start off
    private int c_sortIndex = -1;
    private int c_sortDirection = -999;
    private final Weps c_weps;

    private String[] item_name;
    //   ={"Run Name","Run Location","Management Name","Soil Name",
    //         "Field Size","Gross","Net Total","Net Creep/Salt","Net Suspension","Net PM10"}; 
    protected JCheckBoxMenuItem[] view_item_box;

    /**
     * Creates a new instance of RunManager in standalone mode.
     * @param weps
     */
    public Wmrm(Weps weps) {
        super();
        if (weps == null) {
            weps = new usda.weru.weps.Weps();
        }
        c_weps = weps;

        M_runs.setEnabled(false);
        M_help1.setEnabled(false);
        LT_runs.setEnabled(false);
        JTR_groups.setEnabled(false);
        CardLayout cards = (CardLayout) loadingCardPanel.getLayout();
        cards.show(loadingCardPanel, "loading");

        setTitle("WMRM");

        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        LT_runs.setTrackCursor(false);
        LT_runs.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

        //empty data set while loading
        LT_runs.setDataSource(new JCVectorDataSource(0, 0, null, null, null));
    }

    private void assignHeadColumnName() {

        int i;
        item_name = new String[c_meta.getNumColumns()];
        for (i = 0; i < 5; i++) {
            item_name[i] = c_meta.getLabelAt(0, i);
        }
        for (i = 5; i < c_meta.getNumColumns(); i++) {
            item_name[i] = c_meta.getLabelAt(1, i);
        }
    }

    private void add_view_item() {

        jMenuDefault.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                default_load_item();
            }
        });

        view_item_box = new JCheckBoxMenuItem[10];
        int i;
        for (i = 0; i < item_name.length; i++) {
            final int t = i;
            view_item_box[i] = new JCheckBoxMenuItem();
            view_item_box[i].setText(item_name[i]);
            view_item_box[i].setSelected(true);
            view_item_box[i].addActionListener(new java.awt.event.ActionListener() {

                @Override
                public void actionPerformed(java.awt.event.ActionEvent evt) {

                    if (view_item_box[t].isSelected()) {
                        view_item_box[t].setSelected(true);
                        LT_runs.setColumnHidden(t, false);
                    } else {
                        view_item_box[t].setSelected(false);
                        LT_runs.setColumnHidden(t, true);
                    }
                }
            });
            m_view.add(view_item_box[i]);
        }
    }

    //This default function to load all columns to the table
    private void default_load_item() {

        for (int i = 0; i < item_name.length; i++) {
            view_item_box[i].setSelected(true);
            LT_runs.setColumnHidden(i, false);
        }
    }

    class InternalWorker extends SwingWorker<Boolean, Runnable> {

        private final Wmrm c_wmrm;

        public InternalWorker(Wmrm wmrm) {
            c_wmrm = wmrm;
        }

        @Override
        protected void process(List<Runnable> chunks) {
            for (Runnable process : chunks) {
                process.run();
            }
        }

        @Override
        protected Boolean doInBackground() throws Exception {

            //New Model Code, JCTable and JTree
            c_model = new DataModel();

            TFile runs = c_weps.getRunsLocation();
            if (runs != null) {
                c_model.addDirectoryToModel(runs);
            }

            c_projectsPath = ConfigData.getDefault().getDataParsed(ConfigData.ProjDir);

            TFile tempFile = new TFile(ConfigData.getDefault().getDataParsed(ConfigData.CurrentProj));
            DataModel.RunGroup tempGroup = c_model.lookupRunGroup(tempFile);
            if (tempGroup == null) {
                //Need to add the directory to the tree
                tempGroup = c_model.addDirectoryToModel(tempFile);
            }
            c_model.setCurrentProject(tempGroup);

            ConfigData.getDefault().addPropertyChangeListener(c_wmrm);
            ConfigData.getDefault().fireAll(c_wmrm);

            c_unitsSystem = ConfigData.getDefault().getData(ConfigData.Units);

            c_weps.rfd.addPropertyChangeListener(c_wmrm);
            c_weps.rfd.fireAll(c_wmrm);

            c_weps.addPropertyChangeListener(c_wmrm);
            LT_runs.addResizeCellListener(c_wmrm);

            LT_runs.addMouseMotionListener(new MouseMotionAdapter() {

                @Override
                public void mouseMoved(MouseEvent me) {

                    JCCellPosition position = LT_runs.XYToCell(me.getX(), me.getY());
                    int row = position.row;
                    row = c_meta.getDataRow(row);
                    row = row - c_meta.getNumHeaderRows();

                    //adjust row for header
                    int column = c_meta.getDataColumn(position.column);

                    String tooltip = c_model.getTableDataToolTipText(row, column);
                    if (tooltip != null) {
                        LT_runs.setToolTipText(tooltip);
                    } else {
                        LT_runs.setToolTipText(null);
                    }

                }
            });

            return true;
        }

        @Override
        protected void done() {
            //finished loading everything            

            //WMRM listens for add events to reapply the sort order.
            c_model.addTableDataListener(c_wmrm);

            c_meta = new TableMeta(configFile);

            //Link the datasource/meta to the table
            c_meta.linkTable(LT_runs);
            c_meta.setUnitsSystem(c_unitsSystem);

            LT_runs.setColumnHidden(-1, true);   //Hide row numbers
            LT_runs.setAutoscrolls(false);
            LT_runs.setAutoScroll(JCTableEnum.AUTO_SCROLL_NONE);
            LT_runs.setHorizSBPosition(JCTableEnum.POSITION_AT_SIDE);
            LT_runs.setSelectionPolicy(JCTableEnum.SELECT_RANGE);
            LT_runs.setPopupMenuEnabled(false);

            ActionInitiator initiator = new MouseActionInitiator(MouseEvent.BUTTON1, ActionInitiator.NO_MODIFIER_MASK);
            LT_runs.addAction(new TableAction(initiator, TableAction.COLUMN_SORT_ACTION));

            //Code to allow only one row to be selected.
            LT_runs.addSelectListener(new JCSelectAdapter() {

                @Override
                public void select(JCSelectEvent event) {
                    if (event.getAction() == JCSelectEvent.EXTEND && event.getStartRow() != event.getEndRow()) {
                        event.setCancelled(true);
                    }
                }
            });

            //Setup the tree
            JTR_groups.addTreeSelectionListener(c_wmrm);

            JTR_groups.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
            JTR_groups.addTreeWillExpandListener(c_wmrm);
            JTR_groups.addKeyListener(c_wmrm);

            //Make converted values use the new cell renderer
            c_convertedValueCellRenderer = new ConvertedValueCellRenderer();
            c_convertedValueCellRenderer.setUnitsSystem(c_unitsSystem);
            LT_runs.setCellRenderer(ConvertedValue.class, c_convertedValueCellRenderer);

            LT_runs.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent me) {
                    if (me.getClickCount() == 2) {
                        mouseDoubleClicked(me);
                    } else if (me.getClickCount() == 1) {
                        mouseSingleClicked(me);
                    }
                }
            });

            c_meta.setDataSource(c_model);
            JTR_groups.setModel(c_model);
            c_meta.setUnitsSystem(c_unitsSystem);
            c_model.fireDataReset();

            M_runs.setEnabled(true);
            M_help1.setEnabled(true);
            LT_runs.setEnabled(true);
            JTR_groups.setEnabled(true);

            CardLayout cards = (CardLayout) loadingCardPanel.getLayout();
            cards.show(loadingCardPanel, "table");
            loadingCircle.setActive(false);

            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            LT_runs.setTrackCursor(true);
            LT_runs.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

            //End New Model Code
            setTitle(c_app.getName() + " - " + c_app.getDescription());
            // Assign head column name and add the names to the view menu 
            assignHeadColumnName();
            add_view_item();
        }
    }

    /**
     *
     */
    public void init() {
        SwingWorker<Boolean, Runnable> worker = new InternalWorker(this);
        worker.execute();

    }

    //Property Events
    /**
     *
     * @param event
     */
    @Override
    public void propertyChange(PropertyChangeEvent event) {
        switch (event.getPropertyName()) {
            case ConfigData.ProjDir:
                c_projectsPath = new TFile(".", event.getNewValue().toString()).getPath();
                break;
            case ConfigData.Units:
                c_unitsSystem = (String) event.getNewValue();
                c_convertedValueCellRenderer.setUnitsSystem(c_unitsSystem);
                c_meta.setUnitsSystem(c_unitsSystem);
                c_model.fireDataReset();
                break;
            case ConfigData.CurrentProj:
                TFile tempFile = new TFile(Util.parse(event.getNewValue().toString()));
                DataModel.RunGroup tempGroup = c_model.lookupRunGroup(tempFile);
                if (tempGroup == null) {
                    //Need to add the directory to the tree
                    tempGroup = c_model.addDirectoryToModel(tempFile);
                }
                c_model.setCurrentProject(tempGroup);
                break;
            case Weps.WEPS_RUNCREATED:
                c_model.addRunFileToModel(null, new TFile(event.getNewValue().toString()));
                break;
            case Weps.WEPS_RUNRESTORED:
                c_model.addRunFileToModel(null, new TFile(event.getNewValue().toString()));
                break;
            case ConfigData.DefaultRunsLocation:
                break;
            case RunFileData.RunsLocation:
                c_model.addDirectoryToModel(new TFile(event.getNewValue().toString()));
                break;
        }
    }

    private void mouseDoubleClicked(MouseEvent event) {
        int rowIndex = LT_runs.getCellAreaHandler().getRow(event.getX(), event.getY());
        //Double clicked a header cell.

        if (rowIndex < c_meta.getNumHeaderRows()) {

            return;
        }
        rowIndex = c_meta.getDataRow(rowIndex) - c_meta.getNumHeaderRows();

        int columnIndex = LT_runs.getCellAreaHandler().getColumn(event.getX(), event.getY());
        TableMeta.ColumnMeta column = c_meta.getColumnMeta(columnIndex);

        RunWrapper run = c_model.getRunWrapper(rowIndex);
        takeActionOnRun(run, column.getAction());
        //  LT_runs.setColumnHidden(columnIndex,true);
    }

    private void mouseSingleClicked(MouseEvent event) {
        int rowIndex = LT_runs.getCellAreaHandler().getRow(event.getX(), event.getY());
        //Clicked a data cell.
        if (rowIndex < 0 || rowIndex >= c_meta.getNumHeaderRows()) {
            return;
        }
        int columnIndex = LT_runs.getCellAreaHandler().getColumn(event.getX(), event.getY());
        //Was a new column clicked?

        if (columnIndex != c_sortIndex) {
            //Set to default direction
            c_sortIndex = columnIndex;
            c_sortDirection = Sort.ASCENDING;
        } else {
            //Change sort direction
            switch (c_sortDirection) {
                case Sort.ASCENDING:
                    c_sortDirection = Sort.DESCENDING;
                    break;
                case Sort.DESCENDING:
                    c_sortIndex = -1;
                    c_sortDirection = -999;
            }
        }

        applySort();
    }

    private void applySort() {
        if (c_sortIndex > -1) {
            c_meta.sortByColumn(c_sortIndex, c_sortDirection);
        } else {
            c_meta.sortByColumn(c_sortIndex, c_sortDirection);
            c_meta.resetRowMap();
        }
    }

    /**
     *
     * @param run
     * @param action
     */
    public void takeActionOnRun(RunWrapper run, String action) {
        if (action.equalsIgnoreCase("open_runsummary")) {
            ReportManager.getDefault().displayReport(run.getDirectory(), ReportManager.REPORT_RUN);
        } else if (action.equalsIgnoreCase("open_cropsummary")) {
            ReportManager.getDefault().displayReport(run.getDirectory(), ReportManager.REPORT_CROPSUM);
        } else if (action.equalsIgnoreCase("open_detail")) {
            ReportManager.getDefault().displayReport(run.getDirectory(), ReportManager.REPORT_DETAIL);
        } else if (action.equalsIgnoreCase("open_managementsummary")) {
            ReportManager.getDefault().displayReport(run.getDirectory(), ReportManager.REPORT_MANAGEMENT);
        } else if (action.equalsIgnoreCase("open_soil")) {
            ReportManager.getDefault().displayReport(run.getDirectory(), ReportManager.REPORT_SOIL);
        } else if ("open_runslocation".equalsIgnoreCase(action)) {
            try {
                Desktop.getDesktop().open(run.getDirectory().getParentFile());
            } catch (IOException de) {

            }
        }
    }

    /**
     *
     * @return
     */
    public DataModel getDataModel() {
        return c_model;
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        Wmrm multipleRuns = new Wmrm(null);
        multipleRuns.setVisible(true);
    }
    private int[] c_columnSizeCache;

    private void smartColumnResize() {
        if (LT_runs.getHorizSB().isVisible()) {
            smartColumnResizeDown();
        } else {
            smartColumnResizeUp();
        }
    }
    private boolean c_ignoreCellResize;

    private void smartColumnResizeUp() {
        checkColumnSizeCache();

        //Find the target size for each column
        int totalWidthOfColumnsWantingResize = 0;
        int totalWidthOfColumns = 0;
        int totalTarget = 0;
        int[] targetWidths = new int[LT_runs.getNumColumns()];
        int[] columnWidths = new int[LT_runs.getNumColumns()];
        for (int columnIndex = 0; columnIndex < LT_runs.getNumColumns(); columnIndex++) {

            int columnWidth = 0;
            int maxTextWidth = 0;
            for (int rowIndex = 0; rowIndex < LT_runs.getNumRows(); rowIndex++) {
                Rectangle bounds = LT_runs.getCellBounds(rowIndex, columnIndex);
                columnWidth = bounds.width;
                columnWidths[columnIndex] = columnWidth;
                Font cellFont = LT_runs.getCellStyle(rowIndex, columnIndex).getFont();
                FontMetrics fm = LT_runs.getGraphics().getFontMetrics(cellFont);
                Object o = LT_runs.getDataSource().getTableDataItem(rowIndex, columnIndex);
                if (o == null) {
                    o = "";
                }
                String text = o.toString();
                int textWidth = fm.stringWidth(text);
                if (textWidth > maxTextWidth) {
                    maxTextWidth = textWidth;
                }
            }
            if (maxTextWidth > columnWidth) {
                targetWidths[columnIndex] = maxTextWidth + 15;
                totalWidthOfColumnsWantingResize += columnWidth;
                totalTarget += targetWidths[columnIndex];
            } else {
                targetWidths[columnIndex] = columnWidth;     //Dont't need to change the size;
                totalTarget += targetWidths[columnIndex];
            }
            totalWidthOfColumns += columnWidth;
        }

        //Do we have enough space to expand all the columns to their full desired width?
        if (totalTarget <= LT_runs.getWidth()) {
            //Yes we have enough space, now increase the column widths
            c_ignoreCellResize = true;
            for (int columnIndex = 0; columnIndex < LT_runs.getNumColumns(); columnIndex++) {
                int columnWidth = columnWidths[columnIndex];
                LT_runs.setPixelWidth(columnIndex, targetWidths[columnIndex]);
            }
            c_ignoreCellResize = false;
        } else {
            //Do some fancy ratio work to spread the wealth equally
            //Thus, we use a ratio to spread the wealth
            int avaliableSpace = LT_runs.getWidth() - totalWidthOfColumns;
            c_ignoreCellResize = true;
            for (int columnIndex = 0; columnIndex < LT_runs.getNumColumns(); columnIndex++) {
                int columnWidth = columnWidths[columnIndex];
                if (targetWidths[columnIndex] == columnWidth) {
                    continue;
                }
                double ratio = (double) columnWidth / (double) totalWidthOfColumnsWantingResize;
                int newWidth = (int) (ratio * avaliableSpace);
                LT_runs.setPixelWidth(columnIndex, columnWidth + newWidth);
            }
            c_ignoreCellResize = false;
        }

    }

    private void smartColumnResizeDown() {
        checkColumnSizeCache();
        for (int columnIndex = 0; columnIndex < LT_runs.getNumColumns(); columnIndex++) {
            int columnWidth = c_columnSizeCache[columnIndex];
            LT_runs.setPixelWidth(columnIndex, columnWidth);
        }
    }

    private void checkColumnSizeCache() {
        if (c_columnSizeCache == null) {
            buildColumnSizeCache();
            resetColumnSizeCache();
        }
        if (LT_runs.getNumColumns() != c_columnSizeCache.length) {
            buildColumnSizeCache();
            resetColumnSizeCache();
        }
    }

    private void buildColumnSizeCache() {
        c_columnSizeCache = new int[LT_runs.getNumColumns()];
    }

    private void resetColumnSizeCache() {
        checkColumnSizeCache();
        for (int i = 0; i < LT_runs.getNumColumns(); i++) {
            c_columnSizeCache[i] = LT_runs.getPixelWidth(i);
        }
    }

    /**
     *
     * @param args
     */
    static public void main(String args[]) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                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));

                createAndShowGUI();
            }
        });
    }

    private int getSelectedRow() {
        if (c_model.getNumRows() > 0 && LT_runs.getSelectedCells() != null && LT_runs.getSelectedCells().size() > 0) {
            JCCellRange range = (JCCellRange) LT_runs.getSelectedCells().toArray()[0];
            return range.start_row;
        } else {
            return -1;
        }
    }
    //Menu Events

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_about_ActionPerformed(java.awt.event.ActionEvent evt) {
        new usda.weru.util.AboutDialog(this, Application.WMRM).setVisible(true);
    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_close_ActionPerformed(java.awt.event.ActionEvent evt) {
        dispose();
    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_addProject_actionPerformed(java.awt.event.ActionEvent evt) {
        WepsFileChooser wfc = new WepsFileChooser(WepsFileChooser.Filetype.DIR, c_projectsPath, WepsFileChooser.OPEN);
        if (c_projectsPath != null) {
            wfc.setCurrentDirectory(new TFile(c_projectsPath).getAbsoluteFile());
        }
        wfc.homeToolTip(wfc);

        int returnValue = wfc.showOpenDialog(this);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
            TFile directory = new TFile(wfc.getSelectedFile());
            c_model.addDirectoryToModel(directory);
        }

    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_refreshTable_actionPerformed(java.awt.event.ActionEvent evt) {
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        c_model.checkRunGroup();
        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_addRun_actionPerformed(java.awt.event.ActionEvent evt) {
        WepsFileChooser wfc = new WepsFileChooser(WepsFileChooser.Filetype.RUN, c_projectsPath, WepsFileChooser.OPEN);
        if (c_projectsPath != null) {
            wfc.setCurrentDirectory(new TFile(c_projectsPath).getAbsoluteFile());
        }
        wfc.homeToolTip(wfc);

        int returnValue = wfc.showOpenDialog(this);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
            TFile file = new TFile(wfc.getSelectedFile());
            c_model.addRunFileToModel(null, file);
        }
    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_exportRun_actionPerformed(java.awt.event.ActionEvent evt) {
        int rowIndex = getSelectedRow();
        if (rowIndex < c_meta.getNumHeaderRows()) {
            JOptionPane.showMessageDialog(this, "No Run Selected",
                    Application.WMRM.getName(), JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        rowIndex = c_meta.getDataRow(rowIndex) - c_meta.getNumHeaderRows();
        RunWrapper run = c_model.getRunWrapper(rowIndex);
        RunExporter exporter = new RunExporter(run.getDirectory(), null, false);
        exporter.display(this);
    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_deleteRuns_actionPerformed(java.awt.event.ActionEvent evt) {
        try {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            int rowIndex = getSelectedRow();
            if (rowIndex < c_meta.getNumHeaderRows()) {
                JOptionPane.showMessageDialog(this, "No Run Selected",
                        Application.WMRM.getName(), JOptionPane.INFORMATION_MESSAGE);
                return;
            }
            rowIndex = c_meta.getDataRow(rowIndex) - c_meta.getNumHeaderRows();
            if(rowIndex > c_model.getNumRows()) return;
            RunWrapper run = c_model.getRunWrapper(rowIndex);
            c_weps.deleteRun(run.getDirectory());
            c_model.fireDataReset();
        } finally {
            setCursor(Cursor.getDefaultCursor());
        }

    }

    /**
     *
     * @param event
     */
    @Override
    protected void MI_reloadRun_ActionPerformed(java.awt.event.ActionEvent event) {
        int rowIndex = getSelectedRow();
        if (rowIndex < c_meta.getNumHeaderRows()) {
            JOptionPane.showMessageDialog(this, "No Run Selected",
                    Application.WMRM.getName(), JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        rowIndex = c_meta.getDataRow(rowIndex) - c_meta.getNumHeaderRows();
        RunWrapper run = c_model.getRunWrapper(rowIndex);
        c_weps.restoreRun(run.getDirectory());
    }

    /**
     *
     * @param evt
     */
    @Override
    protected void MI_printAction_performed(java.awt.event.ActionEvent evt) {
        JCPrintTable pt = new JCPrintTable(LT_runs);
        PageFormat format = pt.getPageFormat();
        if (format == null) {
            format = new PageFormat();
        }
        format.setOrientation(PageFormat.LANDSCAPE);
        pt.setPageFormat(format);
        pt.showPrintPreview("Multiple Run Manager");
    }
    //Tree Events

    /**
     *
     * @param event
     */
    @Override
    public void valueChanged(TreeSelectionEvent event) {
        try {
            //c_model.selectRunGroup((DataModel.RunGroup) event.getNewLeadSelectionPath().getLastPathComponent());
            DataModel.RunGroup[] groups = new DataModel.RunGroup[JTR_groups.getSelectionPaths().length];
            int i = 0;
            for (TreePath path : JTR_groups.getSelectionPaths()) {
                groups[i] = (DataModel.RunGroup) path.getLastPathComponent();
                i++;
            }
            c_model.selectRunGroups(groups);
        } catch (NullPointerException npe) {
        }
    }

    /**
     *
     * @param event
     * @throws ExpandVetoException
     */
    @Override
    public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
        if (event.getPath().getLastPathComponent() == c_model.getRoot()) {
            throw new ExpandVetoException(event);
        }
    }

    /**
     *
     * @param event
     */
    @Override
    public void treeWillExpand(TreeExpansionEvent event) {
    }
    //Key Events

    /**
     *
     * @param event
     */
    @Override
    public void keyPressed(KeyEvent event) {
        if (event.getSource() == JTR_groups) {
            //Tree keyboard events
            if (event.getKeyCode() == 127) {
                //Pressed the delete key
                //We don't delete the root or it's direct children.
                Object selectedObject = JTR_groups.getSelectionPath().getLastPathComponent();
                if (c_model.getRoot() == selectedObject) {
                    return;
                }
                int selectedIndex = c_model.getIndexOfChild(c_model.getRoot(), selectedObject);
                if (selectedIndex >= 0) {
                    return;                //make sure the user wants to delete the node.
                }
                int result = JOptionPane.showConfirmDialog(this, "Are you sure you want to remove "
                        + selectedObject.toString() + "?\nThis will not remove the physical file.  "
                        + "Only the display will be changed.", Application.WMRM.getName(),
                        JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
                if (result == JOptionPane.YES_OPTION) {
                    JTR_groups.setSelectionPath(c_model.getPathToNode(((DataModel.RunGroup) selectedObject).getParent()));
                    c_model.removeRunGroupFromModel((DataModel.RunGroup) selectedObject);
                }

            }
        }
    }

    /**
     *
     * @param event
     */
    @Override
    public void keyReleased(KeyEvent event) {
    }

    /**
     *
     * @param event
     */
    @Override
    public void keyTyped(KeyEvent event) {
    }
    //Window events

    /**
     *
     * @param evt
     */
    @Override
    protected void form_windowClosed(java.awt.event.WindowEvent evt) {
        if (c_model != null) {
            c_model.cleanup();
        }
    }
    //JCTableDataListener Events

    @Override
    public void dataChanged(JCTableDataEvent e) {
        int command = e.getCommand();
        if (command == JCTableDataEvent.ADD_ROW || command == JCTableDataEvent.RESET
                || command == JCTableDataEvent.NUM_ROWS || command == JCTableDataEvent.REMOVE_ROW) {
            applySort();
        }
    }

    //Component events
    /**
     *
     * @param evt
     */
    @Override
    protected void LT_runs_componentResized(java.awt.event.ComponentEvent evt) {
        //smartColumnResize();
    }
    //Cell Resize

    @Override
    public void beforeResizeCell(JCResizeCellEvent event) {
    }

    @Override
    public void resizeCell(JCResizeCellEvent event) {
    }

    @Override
    public void afterResizeCell(JCResizeCellEvent event) {
        if (c_ignoreCellResize) {
            return;
        }
        checkColumnSizeCache();
        int columnIndex = event.getColumn();
        if (columnIndex == JCTableEnum.NOVALUE) {
            return;
        }
        c_columnSizeCache[columnIndex] = event.getNewColumnWidth();

    }
}
