
/**
 * InstruView.java
 *
 * Created: Dec 25, 2003
 *
 * @author Nathan Stevens
 * @version 0.6 2/14/2009
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;

public class InstruView extends JPanel implements ChangeListener, XYDataImporter {

    public static int width = 580; // width of the main window
    public static int height = 410; // height of the main window
    public static Properties properties = null;
    public static InstruViewFrame instruViewFrame = null; // The main frame
    public static XYInstrumentLoader xyInstrumentLoader = null;
    public static InstruViewPluginLoader instruViewPluginLoader = null;
    public MessageConsole console = null;
    public static String homeDirectoryName = null;
    public static String imageDirectory = null;
    public static String standardDataDirectory = null;
    public static String dataDirectoryName = null;
    public static String xyiDirectoryName = null;
    public static String pluginDirectoryName = null;
    public Properties plotProperties = null; // stores properties for the displayed plots
    public ExperimentPanel experimentPanel = null;
    public AbsorptionPanel absorptionPanel = null;
    public EmissionPanel emissionPanel = null;
    public RamanPanel ramanPanel = null;
    public StreakCameraPanel streakCameraPanel = null;
    public PumpProbePanel pumpProbePanel = null;
    public XYDataPanel xydataPanel = null;
    public static ExperimentData datafolder = null; // holds experimental data
    private DataViewDialog dataViewDialog = null;
    private WorksheetDialog worksheetDialog = null;
    private PlotDialog plotDialog = null;
    private DataEditDialog dataEditDialog = null;
    private EmissionViewDialog emissionViewDialog = null;
    private StreakViewDialog streakViewDialog = null;
    private PumpProbeView pumpProbeView = null;
    private DataSortDialog dataSortDialog = null;
    private DataRenameDialog dataRenameDialog = null;
    private XYDataImporterDialog xydataImporterDialog = null;
    private static IgorTalkServer iserver = null; // simple server to allow communcation with igor program
    private int wcount = 1;  // variables to hold instrument correction files
    public static String ICFfilename = "ICF.sdl";  // the tabb pane that holds the experiment panels
    JTabbedPane experimentDataPane = null;  // The mouse listener for the experiment panels
    ExperimentPanelMouseListener epmListener = null;  // profile direction used for time resolved data
    public final static int HORIZONTAL_PROFILE = 0;
    public final static int VERTICAL_PROFILE = 1;

    public InstruView() {
        // set the layout
        setLayout(new BorderLayout());

        // Some gui things
        JPanel panel;
        JLabel label;

        epmListener = new ExperimentPanelMouseListener(); // the mouse listener

        // Add the data pane
        experimentDataPane = new JTabbedPane();
        experimentDataPane.addChangeListener(this);

        // initialize the experiment panels
        absorptionPanel = new AbsorptionPanel(this);
        absorptionPanel.setMouseListener(epmListener);
        //absorptionPanel.setExperimentData(getDummyData("absorption")); //debug code

        emissionPanel = new EmissionPanel(this);
        emissionPanel.setMouseListener(epmListener);
        //emissionPanel.setExperimentData(getDummyData("emission")); //debug code

        ramanPanel = new RamanPanel(this);
        ramanPanel.setMouseListener(epmListener);
        //ramanPanel.setExperimentData(getDummyData("raman")); //debug code

        streakCameraPanel = new StreakCameraPanel(this);
        streakCameraPanel.setMouseListener(epmListener);
        //streakCameraPanel.setExperimentData(getDummyData("streak")); //debug

        pumpProbePanel = new PumpProbePanel(this);
        pumpProbePanel.setMouseListener(epmListener);
        //pumpProbePanel.setExperimentData(getDummyData("pump-probe")); //debug

        // experimental panel to hold general XY data
        xydataPanel = new XYDataPanel(this);
        xydataPanel.setMouseListener(epmListener);

        addExperimentPanels();

        add(experimentDataPane, "Center");

        // initialize some stuff now
        experimentPanel = absorptionPanel;

        console = new MessageConsole(this);
        console.pack();

        xydataImporterDialog = new XYDataImporterDialog(this);
        xydataImporterDialog.pack();
        //xydataImporterDialog.setVisible(true);  // debug code

        // initialize the plot properties object and add some default valaues
        // In the future these may be read in from a file
        plotProperties = new Properties();
        plotProperties.setProperty("log", "no");
        plotProperties.setProperty("antialias", "no");
        plotProperties.setProperty("crosshair", "yes");

        // start the igortalk server
        getIgorTalkServer();
    }
    // Method to add experement panels

    private void addExperimentPanels() {
        if (properties.getProperty("show.absorption", "no").equals("yes")) {
            experimentDataPane.addTab("Absorption", null, absorptionPanel,
                    "Absorption Data Files"); //tooltip text
        }

        if (properties.getProperty("show.emission", "no").equals("yes")) {
            experimentDataPane.addTab("Emission", null, emissionPanel,
                    "Emission Data Files"); //tooltip text
        }

        if (properties.getProperty("show.ir", "no").equals("yes")) {
            // code
            //experimentDataPane.addTab("Emission", null, emissionPanel,
            //"FT-IR Data Files"); //tooltip text
        }

        if (properties.getProperty("show.raman", "no").equals("yes")) {
            experimentDataPane.addTab("Raman", null, ramanPanel,
                    "Raman Data Files"); //tooltip text
        }

        if (properties.getProperty("show.streak", "no").equals("yes")) {
            experimentDataPane.addTab("Streak Camera", null, streakCameraPanel,
                    "Streak Camera Data Files"); //tooltip text
        }

        if (properties.getProperty("show.pump-probe", "no").equals("yes")) {
            experimentDataPane.addTab("Pump-Probe", null, pumpProbePanel,
                    "Pump-Probe Data Files"); //tooltip text
        }

        if (properties.getProperty("show.xydata", "no").equals("yes")) {
            experimentDataPane.addTab("XY Data", null, xydataPanel,
                    "General XY Data Files"); //tooltip text
        }
    }

    public void stateChanged(ChangeEvent ce) {
        JTabbedPane tabbedPane = (JTabbedPane) ce.getSource();
        Component component = tabbedPane.getSelectedComponent();
        String name = component.getName();

        if (name.equals("absorption")) {
            experimentPanel = absorptionPanel;
        } else if (name.equals("emission")) {
            experimentPanel = emissionPanel;
        } else if (name.equals("raman")) {
            experimentPanel = ramanPanel;
        } else if (name.equals("streak")) {
            experimentPanel = streakCameraPanel;
        } else if (name.equals("pump-probe")) {
            experimentPanel = pumpProbePanel;
        } else if (name.equals("xydata")) {
            experimentPanel = xydataPanel;
        } else {
            experimentPanel = null;
            System.err.println("No such experiment panel " + name);
        }
    }
    // method to initialize the data folder

    public void initializeDataFolder() {
        String[] meta = new String[5];
        meta[0] = InstruView.getProperty("organization");
        meta[1] = InstruView.getProperty("laboratory");
        meta[2] = InstruView.getProperty("owner");
        meta[3] = InstruView.getProperty("email");
        meta[4] = "mm-dd-yyyy";

        datafolder = new ExperimentData("worksheet", meta);
    }
    // Method to load a spectra data list file from a file.

    public void loadSDL(File file) {
        if (file != null && file.exists()) {
            Object object = BinaryFileManager.getObjectFromFile(file);
            ExperimentData edata = (ExperimentData) object;
            if (checkSaved(edata.getType())) {
                loadSDL(edata, file);
            }
        }
    }
    // Method to load a spectra data list file into a particular experimental panel

    public void loadSDL(ExperimentData edata) {
        String exptype = edata.getType();

        if (exptype.equals("absorption")) {
            absorptionPanel.setExperimentData(edata);
        } else if (exptype.equals("emission")) {
            emissionPanel.setExperimentData(edata);
        } else if (exptype.equals("raman")) {
            ramanPanel.setExperimentData(edata);
        } else if (exptype.equals("streak")) {
            streakCameraPanel.setExperimentData(edata);
        } else if (exptype.equals("pump-probe") || exptype.equals("oodata")) {
            pumpProbePanel.setExperimentData(edata);
        } else if (exptype.equals("xydata")) {
            xydataPanel.setExperimentData(edata);
        } else if (exptype.equals("worksheet")) {
            showWorksheetDialog(edata, null);
        } else {
            System.err.println("Unkown experiment file not loading anything");
        }
    }
    // Method load an sdl file, and set the file

    public void loadSDL(ExperimentData edata, File file) {
        String exptype = edata.getType();

        if (exptype.equals("absorption")) {
            absorptionPanel.setExperimentData(edata);
            absorptionPanel.setSpectraDataListFile(file);
        } else if (exptype.equals("emission")) {
            emissionPanel.setExperimentData(edata);
            emissionPanel.setSpectraDataListFile(file);
        } else if (exptype.equals("raman")) {
            ramanPanel.setExperimentData(edata);
            ramanPanel.setSpectraDataListFile(file);
        } else if (exptype.equals("streak")) {
            streakCameraPanel.setExperimentData(edata);
            streakCameraPanel.setSpectraDataListFile(file);
        } else if (exptype.equals("pump-probe") || exptype.equals("oodata")) {
            pumpProbePanel.setExperimentData(edata);
            pumpProbePanel.setSpectraDataListFile(file);
        } else if (exptype.equals("xydata")) {
            xydataPanel.setExperimentData(edata);
            xydataPanel.setSpectraDataListFile(file);
        } else if (exptype.equals("worksheet")) {
            showWorksheetDialog(edata, file);
        } else {
            System.err.println("Unkown experiment file. Not loading anything...");
        }
    }
    // Method to load a single SpectraData object

    public void loadSpectraData(String exptype, SpectraData sd) {
        if (exptype.equals("absorption")) {
            absorptionPanel.addSpectraData(sd);
        } else if (exptype.equals("emission")) {
            emissionPanel.addSpectraData(sd);
        } else if (exptype.equals("raman")) {
            ramanPanel.addSpectraData(sd);
        } else if (exptype.equals("streak")) {
            streakCameraPanel.addSpectraData(sd);
        } else if (exptype.equals("pump-probe") || exptype.equals("oodata")) {
            pumpProbePanel.addSpectraData(sd);
        } else if (exptype.equals("xydata")) {
            xydataPanel.addSpectraData(sd);
        } else {
            System.err.println("Unkown experiment file.  Not loading anything...");
        }
    }
    // Method to load an array of SpectraData objects

    public void loadSpectraData(String exptype, SpectraData[] sda) {
        if (exptype.equals("absorption")) {
            absorptionPanel.addSpectraData(sda);
        } else if (exptype.equals("emission")) {
            emissionPanel.addSpectraData(sda);
        } else if (exptype.equals("raman")) {
            ramanPanel.addSpectraData(sda);
        } else if (exptype.equals("streak")) {
            streakCameraPanel.addSpectraData(sda);
        } else if (exptype.equals("pump-probe") || exptype.equals("oodata")) {
            pumpProbePanel.addSpectraData(sda);
        } else if (exptype.equals("xydata")) {
            xydataPanel.addSpectraData(sda);
        } else {
            System.err.println("Unkown experiment file. Not loading anything...");
        }
    }
    // only for the data source interface.

    public void setSpectraData(String exptype, SpectraData[] sda) {
        loadSpectraData(exptype, sda);
    }
    // Method to load files from a particular instrument into a particular experiment

    public void loadInstrumentData(String instrumentName, File[] files) {
        if (instrumentName.equals("lambda18")) {
            new Lambda18FileReader(absorptionPanel, files, 0).start();
        } else if (instrumentName.equals("lambda18drs")) {
            new Lambda18FileReader(absorptionPanel, files, 1).start();
        } else if (instrumentName.equals("cary")) {
            new CaryFileReader(absorptionPanel, files).start();
        } else if (instrumentName.equals("tau2")) {
            new Tau2FileReader(emissionPanel, files, false).start();
        } else if (instrumentName.equals("tau2ref")) {
            if (files.length % 2 == 0) {
                new Tau2FileReader(emissionPanel, files, true).start();
            } else {
                String message = "In order to load reference data\nall data files must have a pair.";
                instruViewFrame.showErrorDialog("Tau2 File Import Error", message);
            }
        } else if (instrumentName.equals("hr4000")) {
            new HR4000FileReader(emissionPanel, files).start();
        } else if (instrumentName.equals("lsfluorescence")) {
            new LSFluorescenceFileReader(experimentPanel, files).start();
        } else if (instrumentName.equals("raman")) {
            new RamanFileReader(ramanPanel, files).start();
        } else if (instrumentName.equals("labram")) {
            new LabRamFileReader(ramanPanel, files).start();
        } else if (instrumentName.equals("streak")) {
            if (files.length % 2 == 0) {
                new StreakCameraFileReader(streakCameraPanel, files).start();
            } else {
                String message = "Streak Camera data files must be loaded in pairs.";
                instruViewFrame.showErrorDialog("Streak Camera File Import Error", message);
            }
        } else if (instrumentName.equals("streakdata")) {
            new StreakCameraDataFileReader(streakCameraPanel, files).start();
        } else if (instrumentName.equals("f900")) {
            new F900FileReader(streakCameraPanel, files).start();
        } else if (instrumentName.equals("oodata")) {
            new OOFileReader(pumpProbePanel, files, "oodata").start();
        } else if (instrumentName.equals("pump-probe")) {
            if (files.length % 2 == 0) {
                new OOFileReader(pumpProbePanel, files, "pump-probe").start();
            } else {
                String message = "Pump-Probe data files must be loaded in pairs.";
                instruViewFrame.showErrorDialog("Pump-Probe File Import Error", message);
            }
        } else if (instrumentName.equals("xydata")) {
            xydataImporterDialog.setVisible(true);
            xydataImporterDialog.setFiles(files);
        } else if (instrumentName.indexOf("-xyi") != -1) {
            loadXYInstrumentData(instrumentName, files);
        } else {
            System.err.println("Unknown instrument. Unable to import data files");
        }
    }
    // Method to load an XY Instrument file

    private void loadXYInstrumentData(String instrumentName, File[] files) {
        String[] sa = instrumentName.split("-");
        XYDataInstrument xydataInstrument = (XYDataInstrument) XYInstrumentLoader.xyInstruments.get(sa[0]);
        if (xydataInstrument != null) {
            new XYDataFileReader(this, files, xydataInstrument).start();
        } else {
            System.err.println("Can't load XY Instrument Files, no reader found");
        }
    }
    // Method to show the add spectra dialog

    public void showAddSpectraDataDialog() {
        ExperimentPanel exp_panel = null;
        String exptype = experimentPanel.getName();

        String title = "None";

        if (exptype.equals("absorption")) {
            title = "Add Absorption Data";
            exp_panel = absorptionPanel;
        } else if (exptype.equals("emission")) {
            title = "Add Emission Data";
            exp_panel = emissionPanel;
        } else if (exptype.equals("raman")) {
            title = "Add Raman Data";
            exp_panel = ramanPanel;
        } else if (exptype.equals("streak")) {
            title = "Add Streak Camera Data";
            exp_panel = streakCameraPanel;
        } else if (exptype.equals("pump-probe")) {
            title = "Add Pump-Probe Data";
            exp_panel = pumpProbePanel;
        } else if (exptype.equals("xydata")) {
            title = "Add XY Data";
            exp_panel = xydataPanel;
        } else {
            System.err.println("Unkown experiment type.  Not showing add Dialog...");
            return;
        }

        AddSpectraDataDialog addSpectraDataDialog = new AddSpectraDataDialog(this, title,
                exp_panel);
        //addSpectraDataDialog.pack();
        addSpectraDataDialog.setSize(350, 190);
        addSpectraDataDialog.setVisible(true);
    }
    // Method to show the data view dialog

    public void showDataViewDialog() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda != null) {
            dataViewDialog = new DataViewDialog(sda[0].toString(), sda[0]);
            dataViewDialog.pack();
            dataViewDialog.setVisible(true);
        }
    }
    // Method to display the worksheet dialog

    public void showWorksheetDialog() {
        String title = "Worksheet (" + wcount + ")";
        wcount++;

        worksheetDialog = new WorksheetDialog(this, title);
        worksheetDialog.setSize(560, 345);

        // add data if any
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda != null) {
            worksheetDialog.addSpectraData(sda);
        }

        worksheetDialog.setVisible(true);
    }
    // Method to display the worksheet dialog for experiment data that was opened from a file

    public void showWorksheetDialog(ExperimentData edata, File file) {
        String title = "Worksheet (" + wcount + ")";
        wcount++;

        worksheetDialog = new WorksheetDialog(this, title);
        worksheetDialog.setSize(560, 345);

        // display the data now
        worksheetDialog.setExperimentData(edata);
        worksheetDialog.setSpectraDataListFile(file);
        worksheetDialog.setVisible(true);
    }

    // Method to display the igor talk dialog
    public void showIgorTalkDialog() {
        IgorTalkDialog igorTalkDialog = new IgorTalkDialog(this, false);
        igorTalkDialog.setVisible(true);
    }

    // Method to show the db4o dialog to allow datatransfer to db40 server
    public void showDB4ODialog() {
        DB4ODialog db4oDialog = new DB4ODialog(this, false);
        db4oDialog.setVisible(true);
    }

    // Method to display the plot dialog
    public void showPlotDialog() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        String exptype = experimentPanel.getName();
        if (sda != null) {
            showPlotDialog(exptype, sda);
        }
    }

    // Method to display the plot dialog
    public void showPlotDialog(String exptype, SpectraData[] sda) {
        String title = "";

        if (exptype.equals("absorption")) {
            title = "Absorption Plot";
        } else if (exptype.equals("emission")) {
            title = "Emission Plot";
        } else if (exptype.equals("raman")) {
            title = "Raman Plot";
        } else if (exptype.equals("streak")) {
            title = "Streak Camera Profile";
        } else if (exptype.equals("pump-probe")) {
            title = "Pump-Probe Plot";
        } else if (exptype.equals("xydata")) {
            title = "XY Data Plot";
        } else {
            title = "Spectra Plot";
        }

        plotDialog = new PlotDialog(title, exptype, sda, plotProperties);
        plotDialog.setSize(550, 450);
        plotDialog.setVisible(true);
    }
    // Method to show the data view dialog

    public void showDataEditDialog() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda != null) {
            if (sda[0].is3D()) {
                String message = "Unable to edit 3D data. Use StreakView instead...";
                instruViewFrame.showErrorDialog("Data Edit Error", message);
                return;
            }

            dataEditDialog = new DataEditDialog(sda[0].toString(), experimentPanel, sda[0]);
            dataEditDialog.pack();
            dataEditDialog.setVisible(true);
        }
    }
    // Method to display the EmissionView Dialog

    public void showEmissionViewDialog() {
        emissionViewDialog = new EmissionViewDialog(this);
        //emissionViewDialog.setSize(480, 380);
        emissionViewDialog.pack();
        emissionViewDialog.setVisible(true);
    }
    // Method to display the streak view dialog

    public void showStreakViewDialog() {
        SpectraData[] sda = streakCameraPanel.getSelectedSpectraData();
        if (sda != null && sda[0].is3D()) {
            String title = "Streak View (" + sda[0].getName() + ")";
            streakViewDialog = new StreakViewDialog(this, title, sda[0]);
            streakViewDialog.pack();
            //streakViewDialog.setSize(400, 350);
            streakViewDialog.setVisible(true);
        }
    }
    // Method to display the streak view dialog

    public void showLifeTimeFitDialog() {
        SpectraData sd = streakCameraPanel.getSpectraData();
        if (sd != null && !sd.is3D()) {
            String title = "Decay Profile";
            LifeTimeFitDialog lifetimeFitDialog = new LifeTimeFitDialog(title, streakCameraPanel, plotProperties);
            lifetimeFitDialog.pack();
            lifetimeFitDialog.setVisible(true);

            // set the data now
            lifetimeFitDialog.setSpectraData(sd);
        } else if (xydataPanel.getSpectraData() != null) { // maybe it is xydata

            String title = "XYData Profile";
            LifeTimeFitDialog lifetimeFitDialog = new LifeTimeFitDialog(title, xydataPanel, plotProperties);
            lifetimeFitDialog.pack();
            lifetimeFitDialog.setVisible(true);

            // set the data now
            lifetimeFitDialog.setSpectraData(xydataPanel.getSpectraData());
        }
    }
    // Method to display the PumpProbeView dialog

    public void showPumpProbeViewDialog() {
        String title = "Pump-Probe View";

        // get the file name of the pump probe file name
        String ppfilename = "Not Saved";
        File ppfile = pumpProbePanel.getSpectraDataListFile();

        if (ppfile != null) {
            ppfilename = ppfile.getName();
        }

        // now open the window
        pumpProbeView = new PumpProbeView(this, title, ppfilename);
        pumpProbeView.pack();
        //pumpProbeView.setSize(425, 275);

        // add any data selected in the pump-probe panel
        SpectraData[] sda = pumpProbePanel.getSelectedSpectraData();
        if (sda != null) {
            pumpProbeView.setSpectraData(sda);
        }

        pumpProbeView.setVisible(true);
    }
    // Method to show the data sort dialog

    public void showDataSortDialog() {
        ExperimentData experimentData = experimentPanel.getExperimentData();

        if (experimentData != null && experimentData.getDataCount() >= 2) {
            String exptype = experimentPanel.getName();
            String title = "( Unkown )";

            if (exptype.equals("absorption")) {
                title = "Sort ( Absorption )";
            } else if (exptype.equals("emission")) {
                title = "Sort ( Emission )";
            } else if (exptype.equals("raman")) {
                title = "Sort ( Raman )";
            } else if (exptype.equals("streak")) {
                title = "Sort ( Streak Camera )";
            } else if (exptype.equals("pump-probe")) {
                title = "Sort ( Pump-Probe )";
            } else if (exptype.equals("xydata")) {
                title = "Sort ( XY Data )";
            } else {
                return;
            }

            dataSortDialog = new DataSortDialog(title, experimentPanel);
            dataSortDialog.pack();
            dataSortDialog.setVisible(true);
        }
    }
    // Method to show data rename dialog

    public void showDataRenameDialog() {
        ExperimentData experimentData = experimentPanel.getExperimentData();

        if (experimentData != null && experimentData.getDataCount() > 0) {
            String exptype = experimentPanel.getName();
            String title = "( Unkown )";

            if (exptype.equals("absorption")) {
                title = "Rename ( Absorption )";
            } else if (exptype.equals("emission")) {
                title = "Rename ( Emission )";
            } else if (exptype.equals("raman")) {
                title = "Rename ( Raman )";
            } else if (exptype.equals("streak")) {
                title = "Rename ( Streak Camera )";
            } else if (exptype.equals("pump-probe")) {
                title = "Rename ( Pump-Probe )";
            } else if (exptype.equals("xydata")) {
                title = "Rename ( XY Data )";
            } else {
                return;
            }

            dataRenameDialog = new DataRenameDialog(title, experimentPanel);
            dataRenameDialog.pack();
            dataRenameDialog.setVisible(true);
        }
    }
    // Method to display the console

    public void showMessageConsole() {
        if (!console.isVisible()) {
            console.setVisible(true);
        }
    }
    // Method to spectra data to the data folder

    public void addSpectraDataToFolder() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda != null) {
            for (int i = 0; i < sda.length; i++) {
                datafolder.addData(sda[i]);
            }
        }
    }
    // Method to add a spectra to the data folder

    public void addSpectraDataToFolder(SpectraData sd) {
        if (sd != null) {
            datafolder.addData(sd);
        }
    }
    // Method to add a spectra to the data folder from a spectra data list and index

    public void addSpectraDataToFolder(File file, int index) {
        if (file != null && file.exists()) {
            Object object = BinaryFileManager.getObjectFromFile(file);
            ExperimentData edata = (ExperimentData) object;
            addSpectraDataToFolder(edata.getData(index));
        }
    }
    // Method to get the istance of the igortalk server

    public IgorTalkServer getIgorTalkServer() {
        if (iserver == null) {
            iserver = new IgorTalkServer();
            (new Thread(iserver, "IgorServer Thread")).start();
        }
        return iserver;
    }
    // Method to stop the igortalk server

    public void stopIgorTalkServer() {
        if (iserver != null) {
            iserver.closeSocket();
            iserver = null;
        }
    }
    // Method to copy the selected spectra data running instance of igor

    public void copySpectraDataToIgor() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda != null && iserver != null) {
            iserver.copySpectraDataToIgor(sda);
        }
    }

    // Method to plot the selected spectra data that
    public void plotSpectraDataUsingIgor() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda != null && iserver != null) {
            iserver.plotSpectraDataUsingIgor(sda);
        }
    }

    // Method to plot a waterfall plot using igor on the currently select 3D data
    public void plotWaterfallUsingIgor() {
        SpectraData[] sda = experimentPanel.getSelectedSpectraData();
        if (sda[0].is3D()) { // plot only 3D data one at a time
            iserver.plotWaterfallUsingIgor(sda[0]);
        }
    }
    // Method to return if a dialog experimental panel was save or not

    public boolean isSaved(String epname) {
        if (epname.equals("absorption")) {
            return absorptionPanel.isSaved();
        } else if (epname.equals("emission")) {
            return emissionPanel.isSaved();
        } else if (epname.equals("raman")) {
            return ramanPanel.isSaved();
        } else if (epname.equals("streak")) {
            return streakCameraPanel.isSaved();
        } else if (epname.equals("pump-probe")) {
            return pumpProbePanel.isSaved();
        } else if (epname.equals("xydata")) {
            return xydataPanel.isSaved();
        } else if (epname.equals("worksheet")) {
            return true;
        } else {
            System.err.println("Unknown experiment. Returning true...");
            return true;
        }
    }
    // Method to set the data saved

    public void setSaved() {
        experimentPanel.setSaved(true);
    }
    // Method to check to see if a data file was saved amd if not how to proceed

    public boolean checkSaved(String expname) {
        if (!isSaved(expname)) {

            int n = JOptionPane.showConfirmDialog(
                    this, "Data not saved (" + expname + "). Continue anyway?",
                    "UnSaved Data",
                    JOptionPane.YES_NO_OPTION);
            if (n == JOptionPane.YES_OPTION) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }
    // Method to get a properties for the program

    public static String getProperty(String key) {
        return properties.getProperty(key, "Not Set");
    }
    // Method to save the properties file

    public void storeProperties() {
        String initFileName = System.getProperty("user.home") +
                System.getProperty("file.separator") + "instruview.ini";

        File initFile = new File(initFileName);

        try {
            FileOutputStream output = new FileOutputStream(initFile);
            properties.store(output, "---InstruView 0.6* Properties File---");
        } catch (IOException ioe) {
            System.err.println("Error Saving Program Properties");
        }
    }
    // The print method that is implemented for XYDataImporter

    public void print(String message) {
        System.out.println(message);
    }
    // The main method

    public static void main(String args[]) {
        System.out.println("InstruView Working Directory = " +
                System.getProperty("user.dir"));


        // set the home, image and data directory names
        homeDirectoryName = System.getProperty("user.dir") + "/";
        imageDirectory = homeDirectoryName + "images/";
        standardDataDirectory = homeDirectoryName + "data/";

        // set the initiation file names
        String defaultInitFileName = homeDirectoryName + "instruview.ini";
        File defaultInitFile = new File(defaultInitFileName);

        String initFileName = System.getProperty("user.home") +
                System.getProperty("file.separator") + "instruview.ini";
        File initFile = new File(initFileName);

        if (defaultInitFile.exists()) {
            try {
                Properties defaultProperties;
                Properties userProperties;

                FileInputStream fis = new FileInputStream(defaultInitFile);
                defaultProperties = new Properties();
                defaultProperties.load(fis);
                fis.close();

                if (initFile.exists()) {
                    fis = new FileInputStream(initFile);
                    userProperties = new Properties();
                    userProperties.load(fis);
                    fis.close();

                    // now compare the default properties and this to see if new keys should be added
                    Enumeration e = defaultProperties.propertyNames();
                    while (e.hasMoreElements()) {
                        String key = (String) e.nextElement();
                        String value = defaultProperties.getProperty(key);

                        if (userProperties.getProperty(key) == null) {
                            userProperties.setProperty(key, value);
                        }
                    }

                    properties = userProperties;
                } else {
                    properties = defaultProperties;
                }
            } catch (IOException e) {
                System.err.println("Unable to open initiation file.\nProgram exiting...");
                System.exit(-1);
            }
        } else {
            System.err.println("Can't open initiation file.\nProgram exiting...");
            System.exit(-1);
        }

        // initialize the data directory name
        dataDirectoryName = properties.getProperty("data.directory", "Not Set");

        // load any xy data instruments files now (*.xyi)
        xyiDirectoryName = homeDirectoryName + "xyi/";
        xyInstrumentLoader = new XYInstrumentLoader(xyiDirectoryName);

        // load any plugins now
        pluginDirectoryName = homeDirectoryName + "plugins/";
        instruViewPluginLoader = new InstruViewPluginLoader(pluginDirectoryName,
                Thread.currentThread().getContextClassLoader());

        // set the width for the window depending on the operating system
        if (System.getProperty("mrj.version") != null) {
            height = 420; // set the propery for mac
            width = 680;
        } else {
            height = 410; // set the default height and values
            width = 580;
        }

        // create the instruview object
        InstruView instruView = new InstruView();
        instruView.initializeDataFolder();
        instruViewFrame = new InstruViewFrame(instruView);
        instruViewFrame.setSize(width, height);

        // open any data files that make exist
        if (args.length != 0 && args[0].indexOf(".sdl") != -1) {
            File sdlfile = new File(args[0]);
            instruView.loadSDL(sdlfile);
        }

        // now finally display the program
        instruViewFrame.setVisible(true);
    }

    /**
    Class to handel mouse events from the JList in the expermentPanel
     */
    public class ExperimentPanelMouseListener implements MouseListener {

        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
            int clicks = e.getClickCount();
            if (clicks == 2) {
                showDataRenameDialog();
            }
        }
    } // --end class ExperimentPanelMouseListener
  /*Method to generate dummy data.  MUST REMOVE LATER
    private ExperimentData getDummyData(String type) {
    String[] meta = new String[5];
    meta[0] = InstruView.getProperty("organization");
    meta[1] = InstruView.getProperty("laboratory");
    meta[2] = InstruView.getProperty("owner");
    meta[3] = InstruView.getProperty("email");
    meta[4] = "00-00-2004";
    ExperimentData edata = new ExperimentData(type, meta);
    SpectraData sdata;
    float[][] data;
    String exptype;
    String ctype;

    if(type.equals("absorption")) {
    for(int i = 0; i < 10; i++) {
    String dmeta[] = new String[8];
    dmeta[0] = InstruView.getProperty("organization");
    dmeta[1] = InstruView.getProperty("laboratory");
    dmeta[2] = InstruView.getProperty("owner");
    dmeta[3] = InstruView.getProperty("email");
    dmeta[4] = InstruView.getProperty("instrument.absorption");
    dmeta[5] = "00-00-2004";
    dmeta[6] = "" + (i + 20) ;

    String header[] = {"230.0", "750.0", "260", "Unknown", "10", "None " + i};

    if(i == 2 || i == 5 || i == 9) {
    exptype = "reflectance";
    }
    else {
    exptype = "transmission";
    }

    if(i == 2 || i == 5 || i == 9) {
    data = getXYData(230f, 750f);
    sdata = new SpectraData("scan00"+i, exptype, header, dmeta, data, data);
    edata.addData(sdata);
    }
    else {
    data = getXYData(230f, 750f);
    sdata = new SpectraData("scan00"+i, exptype, header, dmeta, data, null);
    edata.addData(sdata);
    }
    }
    }
    else if(type.equals("emission")) {
    for(int i = 0; i < 10; i++) {
    String dmeta[] = new String[8];
    dmeta[0] = InstruView.getProperty("organization");
    dmeta[1] = InstruView.getProperty("laboratory");
    dmeta[2] = InstruView.getProperty("owner");
    dmeta[3] = InstruView.getProperty("email");
    dmeta[4] = InstruView.getProperty("instrument.emission");
    dmeta[5] = "00-01-2004";
    dmeta[6] = "" + (i + 20) ;

    String header[] = {"500.0", "750.0", "260", "RA", "0.3", "400", "Unknown", "None " + i};

    if(i == 2 || i == 5 || i == 9) {
    exptype = "Em";
    }
    else {
    exptype = "Ex";
    }

    data = getXYData(500f, 750f);
    sdata = new SpectraData("em00"+i, exptype, header, dmeta, data, null);
    edata.addData(sdata);
    }
    }
    else if(type.equals("raman")) {
    for(int i = 0; i < 10; i++) {
    String dmeta[] = new String[8];
    dmeta[0] = InstruView.getProperty("organization");
    dmeta[1] = InstruView.getProperty("laboratory");
    dmeta[2] = InstruView.getProperty("owner");
    dmeta[3] = InstruView.getProperty("email");
    dmeta[5] = "00-01-2004";
    dmeta[6] = "" + (i + 20) ;

    String header[] = {"200.0", "2000.0", "2500", "487.98", "60.0", "Unknown", "None " + i};

    if(i == 2 || i == 5 || i == 9) {
    exptype = "micro";
    dmeta[4] = InstruView.getProperty("instrument.mraman");
    }
    else {
    exptype = "macro";
    dmeta[4] = InstruView.getProperty("instrument.raman");
    }

    data = getXYData(200f, 2000f);
    sdata = new SpectraData("rm00"+i, exptype, header, dmeta, data,null);
    edata.addData(sdata);
    }
    }
    else if(type.equals("streak")) {
    for(int i = 0; i < 10; i++) {
    String dmeta[] = new String[8];
    dmeta[0] = InstruView.getProperty("organization");
    dmeta[1] = InstruView.getProperty("laboratory");
    dmeta[2] = InstruView.getProperty("owner");
    dmeta[3] = InstruView.getProperty("email");
    dmeta[4] = InstruView.getProperty("instrument.streak");
    dmeta[5] = "00-02-2004";
    dmeta[6] = "" + (i + 30) ;

    String header[] = {"500.0", "650.0", "0", "1000", "307200",
    "480", "33", "10000", "Unknown", "None " + i};

    data = get3Data(500.0f, 600.0f, 0f, 1000f);
    sdata = new SpectraData("sr00"+i, "streak", header, dmeta, data,null);
    sdata.set3D(true);
    edata.addData(sdata);
    }
    }
    else if(type.equals("pump-probe")) {
    for(int i = 0; i < 10; i++) {
    String dmeta[] = new String[8];
    dmeta[0] = InstruView.getProperty("organization");
    dmeta[1] = InstruView.getProperty("laboratory");
    dmeta[2] = InstruView.getProperty("owner");
    dmeta[3] = InstruView.getProperty("email");
    dmeta[4] = InstruView.getProperty("instrument.pump-probe");
    dmeta[5] = "00-04-2004";
    dmeta[6] = "" + (i + 40) ;

    int delay = i*100;
    String delays = delay + "";
    String name = "pp";
    String[] header;
    String[] header1 = {"450", "800.0", "350", delays, "200", "10", "550.0", "Unknown", "None " + i};
    String[] header2 = {"-400", "100000", "350", delays, "200", "10", "550.0", "Unknown", "None " + i};
    if(i == 2 || i == 5 || i == 9) {
    exptype = "oodata";
    header = header1;
    }
    else if(i == 3 || i == 7) {
    exptype = "pump-probeTP";
    header = header2;
    }
    else {
    exptype = "pump-probe";
    header = header1;
    }

    if(exptype.equals("pump-probe")) {
    data = getXYData(450f, 800f);
    sdata = new SpectraData(name, exptype, header, dmeta, data, data);
    sdata.setDelay(delays);
    edata.addData(sdata);
    }
    else if(exptype.equals("pump-probeTP")) {
    data = getXYData(450f, 800f);
    sdata = new SpectraData(name, exptype, header, dmeta, data, data);
    sdata.setDelay(delays);
    sdata.setProfileDirection(1);
    edata.addData(sdata);
    }
    else {
    name = "oodata";
    data = getXYData(450f, 800f);
    sdata = new SpectraData(name, exptype, header, dmeta, data, null);
    edata.addData(sdata);
    }
    }
    }

    return edata;
    }

    // Method to return random data ***Remove Later***
    private float[][] getXYData(float min, float max) {
    int count = 250;
    float increment = (max - min)/250;
    float xvalue = 0f;
    float yvalue = 0f;

    float[][] data = new float[count][2];

    for(int i = 0; i < count; i++) {
    if(i ==0) {
    xvalue  = min;
    }
    else {
    xvalue += increment;
    }
    yvalue = (float)Math.random() * xvalue * 10.0f;

    data[i][0] = xvalue;
    data[i][1] = yvalue;
    }
    return data;
    }

    // Method to get 3D data
    private float[][] get3Data(float minwl, float maxwl, float mint, float maxt) {
    float[][] data = new float[481][641];
    float dwl = (maxwl-minwl)/640f;
    float dt = (maxt - mint)/480f;
    float wl = minwl;
    float tm = mint;

    // generate the wavelength axis
    data[0][0] = 0f;
    for(int i = 1; i < data[0].length; i++) {
    data[0][i] = wl;
    wl += dwl;
    }

    // generate the time axis
    for(int i = 1; i < data.length; i++) {
    data[i][0] = tm;
    tm += dt;
    }

    // now add the data
    for(int i = 1; i < data.length; i++) {
    for(int j = 1; j < data[0].length; j++) {
    data[i][j] = (float)Math.random()*1000.0f;
    }
    }

    return data;
    }*/
} // --end class InstruView
