/**
 * FRETViewPlotDialog.java
 * Contains the graphs to plot the data.
 * Created: June 28, 2006
 *
 * @author Nathan Stevens
 * @version 0.1 9/27/2006 
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.util.*;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.renderer.*;
import org.jfree.chart.renderer.xy.*;

public class FRETViewPlotDialog extends JFrame implements ActionListener, 
ChangeListener, ChartChangeListener {
  private DataPointSelectedListener dsListener = null; // the current x, y location gets passed to this object
  private JLabel xposLB = null;
  private JLabel yposLB = null;
  private ChartPanel chartPanel = null;
  private String xunits = " nm";
  private String yunits = " a.u.";
  private String xlabel = null;
  private String ylabel = null;
  private JSlider xJS = null;
  
  // variables below used for plotting simulated spectra
  private float[][] donor_intensity = null;
  private float[][] acceptor_intensity = null;
  private float[][] donor_ems = null;
  private float[][] acceptor_ems = null;
  private XYSeriesCollection sim_data = null; // stores the simulated data
  private JFreeChart sim_chart = null; // plots the simulated data
  String x_axis = null;
  private float minX = 0.0f;
  private float maxX = 0.0f;
  private float dx = 0.0f;
  private int index = 0;
  
  // this constructor is note used
  public FRETViewPlotDialog() { }
  
  // constructore for plotting the donor and acceptor spectra
  public FRETViewPlotDialog(DyeSpectra donorDye, DyeSpectra acceptorDye,
  boolean[] spectra) {
    // create the series
    XYSeriesCollection plotdata = new XYSeriesCollection();
    SpectraData sd = null;
    XYSeries series = null;
    float[][] xydata = null;
    
    if(spectra[0] && donorDye != null) { // plot donor absorption
      sd = donorDye.getAbsorption();
      series = getSeries(sd.getData(), "Donor Absorption");
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None");
      plotdata.addSeries(series);
    }
    
    if(spectra[1] && donorDye != null) { // plot donor emission
      sd = donorDye.getEmission();
      series = getSeries(sd.getData(), "Donor Emission");
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None");
      plotdata.addSeries(series);
    }
    
    if(spectra[2] && acceptorDye != null) { // plot donor absorption
      sd = acceptorDye.getAbsorption();
      series = getSeries(sd.getData(), "Acceptor Absorption");
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None");
      plotdata.addSeries(series);
    }
    
    if(spectra[3] && acceptorDye != null) { // plot donor emission
      sd = acceptorDye.getEmission();
      series = getSeries(sd.getData(), "Acceptor Emission");
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None");
      plotdata.addSeries(series);
    }
    
    // create the chart now
    xlabel = "Wavelength (nm)";
    ylabel = "Intensity/Absorbance (a.u.)";
    
    JFreeChart chart = ChartFactory.createXYLineChart("Donor/Acceptor Spectra", xlabel, ylabel, 
                                                          plotdata,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    
    chart.setBackgroundPaint(Color.white);
    chart.addChangeListener(this);
    chart.setAntiAlias(false); // will allow to be modifies
    
    XYPlot plot = (XYPlot)chart.getPlot();
    plot.setOutlinePaint(Color.black);
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(false);
    //plot.setDomainGridlinesVisible(false);
    //plot.setRangeGridlinesVisible(false);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setAutoRangeIncludesZero(false);
    axis.setAutoRangeMinimumSize(1.0);
    
    // get the rederies to modify the colors
    XYLineAndShapeRenderer r1 = (XYLineAndShapeRenderer)plot.getRenderer();
    
    BasicStroke stroke = new BasicStroke(2.0f);
    BasicStroke dash = new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
    1.0f, new float[] {2.0f, 6.0f}, 0.0f);
    
    r1.setSeriesPaint(0, Color.blue);
    r1.setSeriesStroke(0, stroke);
    r1.setSeriesVisible(0, new Boolean(spectra[0]));
    
    r1.setSeriesPaint(1, Color.blue);
    r1.setSeriesStroke(1, dash);
    r1.setSeriesVisible(1, new Boolean(spectra[1]));
    
    r1.setSeriesPaint(2, Color.red);
    r1.setSeriesStroke(2, stroke);
    r1.setSeriesVisible(2, new Boolean(spectra[2]));
    
    r1.setSeriesPaint(3, Color.red);
    r1.setSeriesStroke(3, dash);
    r1.setSeriesVisible(3, new Boolean(spectra[3]));
    
    chartPanel = new ChartPanel(chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
    
    // create the user interface
    createGui();
  }
  
  // Constructor to plot used when plot simulated spectra
  public FRETViewPlotDialog(DyeSpectra donorDye, DyeSpectra acceptorDye, 
  float[][] donor_intensity, float[][] acceptor_intensity, int index, String x_axis) {
    this.donor_intensity = donor_intensity;
    this.acceptor_intensity = acceptor_intensity;
    this.x_axis = x_axis;
    this.index = index;
    
    SpectraData donor_sd = donorDye.getEmission();
    SpectraData acceptor_sd = acceptorDye.getEmission();
    donor_ems = donor_sd.getData();
    acceptor_ems = acceptor_sd.getData();
    
    String title = "Simulated Spectra ";
    ylabel = "Intensity (a.u)";
    xlabel = "Wavelength (nm)";
    
    float d_intensity = 1.0f;
    float a_intensity = 1.0f;
    
    if(x_axis.equals("Distance")) {
      d_intensity = donor_intensity[index][1];
      a_intensity = acceptor_intensity[index][1];
      
      minX = donor_intensity[0][1];
      maxX = donor_intensity[0][donor_intensity[0].length - 1];
      dx = donor_intensity[0][2] - donor_intensity[0][1];
      
      title += "Exciting @ " + donor_intensity[index][0] + " nm";
    }
    else { // must be wavelength
      d_intensity = donor_intensity[1][index];
      a_intensity = acceptor_intensity[1][index];
      
      minX = donor_intensity[1][0];
      maxX = donor_intensity[donor_intensity.length - 1][0];
      dx = donor_intensity[2][0] - donor_intensity[1][0];
      
      title += "D-A Distance @ " + donor_intensity[0][index] + " Angs";
    }
    
    // get the donor series, acceptor series and total series
    sim_data = new XYSeriesCollection();
    XYSeries d_series = getDonorSeries(donor_ems, d_intensity);
    XYSeries a_series = getAcceptorSeries(acceptor_ems, a_intensity);
    XYSeries s_series = getSumSeries(donor_ems, acceptor_ems, d_intensity, a_intensity);
    
    sim_data.addSeries(d_series);
    sim_data.addSeries(a_series);
    sim_data.addSeries(s_series);
    
    sim_chart = ChartFactory.createXYLineChart(title, xlabel, ylabel, 
                                                          sim_data,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    // construct the chart now
    sim_chart.setBackgroundPaint(Color.white);
    sim_chart.addChangeListener(this);
    sim_chart.setAntiAlias(false); // will allow to be modifies
    
    XYPlot plot = (XYPlot)sim_chart.getPlot();
    plot.setOutlinePaint(Color.black);
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(true);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setRange(0.0, 100.0);
    
    XYLineAndShapeRenderer r1 = (XYLineAndShapeRenderer)plot.getRenderer();
    BasicStroke stroke = new BasicStroke(2.0f);
    BasicStroke dash = new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
    1.0f, new float[] {2.0f, 6.0f}, 0.0f);
    
    r1.setSeriesPaint(0, Color.blue);
    r1.setSeriesStroke(0, dash);
    
    r1.setSeriesPaint(1, Color.red);
    r1.setSeriesStroke(1, dash);
    
    r1.setSeriesPaint(2, Color.green);
    r1.setSeriesStroke(2, stroke);
    
    chartPanel = new ChartPanel(sim_chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
    
    // construct the slider
    int min = (int)minX;
    int max = (int)maxX;
    int spacing = (max - min)/10;
    
    xJS = new JSlider(JSlider.HORIZONTAL, min, max, min);
    xJS.addChangeListener(this);
    xJS.setMajorTickSpacing(spacing);
    //xJS.setMinorTickSpacing(1);
    xJS.setPaintTicks(true);
    xJS.setPaintLabels(true);
    xJS.setBorder(BorderFactory.createEmptyBorder(0,0,10,0));
    
    // create the user interface
    createGui();
  }
  
  // Method to plot FRET parameters
  public FRETViewPlotDialog(String plot, String xlabel, float[][] data, boolean[] spectra) {
    if(plot.equals("plot1")) {
      createPlot1(xlabel, data, spectra);
    }
    else if(plot.equals("plot2")) {
      createPlot2(xlabel, data, spectra);
    }
    else if(plot.equals("plot3")) {
      createPlot3(xlabel, data, spectra);
    }
    else if(plot.equals("plot4")) {
      createPlot4(xlabel, data, spectra);
    }
    createGui();
  }
  
  // Method to create Plot 1 (Wavelenght or r vs E, Fd, Fa, Ft)
  private void createPlot1(String xlabel, float[][] data, boolean[] spectra) {
    // create the series
    XYSeriesCollection plotdata = new XYSeriesCollection();
    XYSeries series = null;
    float[][] xydata = null;
    
    if(spectra[0]) { // plot the efficiency
      series = getSeries(data, "E", 1);
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None", 0);
      plotdata.addSeries(series);
    }
    
    if(spectra[1]) { // plot donor intensity
      series = getSeries(data, "Fd", 2);
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None", 0);
      plotdata.addSeries(series);
    }
    
    if(spectra[2]) { // plot acceptor intensity
      series = getSeries(data, "Fa", 3);
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None", 0);
      plotdata.addSeries(series);
    }
    
    
    if(spectra[3]) { // plot total intensity
      series = getSeries(data, "Ft", 4);
      plotdata.addSeries(series);
    }
    else {
      series = getSeries(null, "None", 0);
      plotdata.addSeries(series);
    }
    
    // create the chart now
    ylabel = "Efficiency/Intensity (a.u.)";
    
    JFreeChart chart = ChartFactory.createXYLineChart("FRET Parameters", xlabel, ylabel, 
                                                          plotdata,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    
    chart.setBackgroundPaint(Color.white);
    chart.addChangeListener(this);
    chart.setAntiAlias(false); // will allow to be modifies
    
    XYPlot plot = (XYPlot)chart.getPlot();
    plot.setOutlinePaint(Color.black);
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(true);
    //plot.setDomainGridlinesVisible(false);
    //plot.setRangeGridlinesVisible(false);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setAutoRangeIncludesZero(false);
    axis.setAutoRangeMinimumSize(1.0);
    
    // get the rederies to modify the colors
    XYLineAndShapeRenderer r1 = (XYLineAndShapeRenderer)plot.getRenderer();
    BasicStroke stroke = new BasicStroke(3.0f);
    
    r1.setSeriesPaint(0, Color.magenta);
    r1.setSeriesStroke(0, stroke);
    r1.setSeriesVisible(0, new Boolean(spectra[0]));
    
    r1.setSeriesPaint(1, Color.blue);
    r1.setSeriesStroke(1, stroke);
    r1.setSeriesVisible(1, new Boolean(spectra[1]));
    
    r1.setSeriesPaint(2, Color.red);
    r1.setSeriesStroke(2, stroke);
    r1.setSeriesVisible(2, new Boolean(spectra[2]));
    
    r1.setSeriesPaint(3, Color.green);
    r1.setSeriesStroke(3, stroke);
    r1.setSeriesVisible(3, new Boolean(spectra[3]));
    
    chartPanel = new ChartPanel(chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
  }
  
  // Method to create Plot 2 (Wavelenght or r vs E, Fa/Fd
  private void createPlot2(String xlabel, float[][] data, boolean[] spectra) {
    // create the series
    XYSeriesCollection plotdata1 = new XYSeriesCollection();
    XYSeriesCollection plotdata2 = new XYSeriesCollection(); // efficiency data
    
    XYSeries series1 = new XYSeries("Fa/Fd");
    XYSeries series2 = new XYSeries("E");
    
    float max = data[0][3];
    for(int i = 0; i < data.length; i++) {
      series2.add(data[i][0], data[i][1]);
      if(data[i][2] <= max) {
        series1.add(data[i][0], data[i][2]);
      }
    }
    
    plotdata1.addSeries(series1);
    plotdata2.addSeries(series2);
    
    // create the chart now
    ylabel = "Intensity Ratio (Fa/Fd)";
    
    JFreeChart chart = ChartFactory.createXYLineChart("Intensity Ratio", xlabel, ylabel, 
                                                          plotdata1,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    
    chart.setBackgroundPaint(Color.white);
    chart.addChangeListener(this);
    chart.setAntiAlias(false); // will allow to be modifies
    
    XYPlot plot = (XYPlot)chart.getPlot();
    plot.setOutlinePaint(Color.black);
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(true);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setAutoRangeIncludesZero(false);
    axis.setAutoRangeMinimumSize(1.0);
    
    if(spectra[1]) {
      NumberAxis axis2 = new NumberAxis("Efficiency");
      axis2.setAutoRangeIncludesZero(false);
      plot.setRangeAxis(1, axis2);
      plot.setDataset(1, plotdata2);
      plot.mapDatasetToRangeAxis(1, 1);
    }
    
    // get the rederies to modify the colors
    XYLineAndShapeRenderer r1 = (XYLineAndShapeRenderer)plot.getRenderer();
    BasicStroke stroke = new BasicStroke(3.0f);
    
    r1.setSeriesPaint(0, Color.blue);
    r1.setSeriesStroke(0, stroke);
    
    if(spectra[1]) {
      XYLineAndShapeRenderer r2 = new XYLineAndShapeRenderer();
      r2.setShapesVisible(false);
      r2.setSeriesPaint(0, Color.magenta);
      r2.setSeriesStroke(0, stroke);
      plot.setRenderer(1, r2);
    }
    
    chartPanel = new ChartPanel(chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
  }
  
  // Method to create Plot 3 (Wavelenght or r vs E, Kt
  private void createPlot3(String xlabel, float[][] data, boolean[] spectra) {
    // create the series
    XYSeriesCollection plotdata1 = new XYSeriesCollection();
    XYSeriesCollection plotdata2 = new XYSeriesCollection(); // efficiency data
    
    XYSeries series1 = new XYSeries("Kt");
    XYSeries series2 = new XYSeries("E");
    
    for(int i = 0; i < data.length; i++) {
      series2.add(data[i][0], data[i][1]);
      
      if(data[i][2] <= 1e16f) { // limit to femtosecond time range
        series1.add(data[i][0], data[i][2]/1e12f);
      }
    }
    
    plotdata1.addSeries(series1);
    plotdata2.addSeries(series2);
    
    // create the chart now
    ylabel = "Transfer Rate (s^-1/1e12)";
    
    JFreeChart chart = ChartFactory.createXYLineChart("Transfer Rate", xlabel, ylabel, 
                                                          plotdata1,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    
    chart.setBackgroundPaint(Color.white);
    chart.addChangeListener(this);
    chart.setAntiAlias(false); // will allow to be modifies
    
    XYPlot plot = (XYPlot)chart.getPlot();
    plot.setOutlinePaint(Color.black);
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(true);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setAutoRangeIncludesZero(false);
    axis.setAutoRangeMinimumSize(1.0);
    
    if(spectra[1]) {
      NumberAxis axis2 = new NumberAxis("Efficiency");
      axis2.setAutoRangeIncludesZero(false);
      plot.setRangeAxis(1, axis2);
      plot.setDataset(1, plotdata2);
      plot.mapDatasetToRangeAxis(1, 1);
    }
    
    // get the rederies to modify the colors
    XYLineAndShapeRenderer r1 = (XYLineAndShapeRenderer)plot.getRenderer();
    BasicStroke stroke = new BasicStroke(3.0f);
    
    r1.setSeriesPaint(0, Color.blue);
    r1.setSeriesStroke(0, stroke);
    
    if(spectra[1]) {
      XYLineAndShapeRenderer r2 = new XYLineAndShapeRenderer();
      r2.setShapesVisible(false);
      r2.setSeriesPaint(0, Color.magenta);
      r2.setSeriesStroke(0, stroke);
      plot.setRenderer(1, r2);
    }
    
    chartPanel = new ChartPanel(chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
  }
  
  // Method to create Plot 4 (Wavelenght or r vs E, tau
  private void createPlot4(String xlabel, float[][] data, boolean[] spectra) {
    // create the series
    XYSeriesCollection plotdata1 = new XYSeriesCollection();
    XYSeriesCollection plotdata2 = new XYSeriesCollection(); // efficiency data
    
    XYSeries series1 = new XYSeries("Tau");
    XYSeries series2 = new XYSeries("E");
    
    for(int i = 0; i < data.length; i++) {
      series1.add(data[i][0], data[i][2]);
      series2.add(data[i][0], data[i][1]);
    }
    
    plotdata1.addSeries(series1);
    plotdata2.addSeries(series2);
    
    // create the chart now
    String unit = FRETViewUtil.getTimeUnit(data[0][3]);
    ylabel = "Lifetime ("+ unit + ")";
    
    JFreeChart chart = ChartFactory.createXYLineChart("Lifetime", xlabel, ylabel, 
                                                          plotdata1,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    
    chart.setBackgroundPaint(Color.white);
    chart.addChangeListener(this);
    chart.setAntiAlias(false); // will allow to be modifies
    
    XYPlot plot = (XYPlot)chart.getPlot();
    plot.setOutlinePaint(Color.black);
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(true);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setAutoRangeIncludesZero(false);
    axis.setAutoRangeMinimumSize(1.0);
    
    if(spectra[1]) {
      NumberAxis axis2 = new NumberAxis("Efficiency");
      axis2.setAutoRangeIncludesZero(false);
      plot.setRangeAxis(1, axis2);
      plot.setDataset(1, plotdata2);
      plot.mapDatasetToRangeAxis(1, 1);
    }
    
    // get the rederies to modify the colors
    XYLineAndShapeRenderer r1 = (XYLineAndShapeRenderer)plot.getRenderer();
    BasicStroke stroke = new BasicStroke(3.0f);
    
    r1.setSeriesPaint(0, Color.blue);
    r1.setSeriesStroke(0, stroke);
    
    if(spectra[1]) {
      XYLineAndShapeRenderer r2 = new XYLineAndShapeRenderer();
      r2.setShapesVisible(false);
      r2.setSeriesPaint(0, Color.magenta);
      r2.setSeriesStroke(0, stroke);
      plot.setRenderer(1, r2);
    }
    
    chartPanel = new ChartPanel(chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
  }
  
  // Method to create the gui
  private void createGui() {
    // dispose of this wondow
		addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
				setVisible(false);
        dispose();
		  }
		});
    
    // set the layout to border layer
    getContentPane().setLayout(new BorderLayout());
    
    // some gui stuff
    JPanel panel;
    JLabel label;
    JButton button;
    
    // add the chart panel to the center location
    getContentPane().add(chartPanel, "Center");
    
    // the south panel
    panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    
    // the panel holding the slider
    if(xJS != null) {
      panel.add(xJS);
    }
    
    // add the button panel now
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
    Border border = BorderFactory.createRaisedBevelBorder();
    buttonPanel.setBorder(border);
    
    label = new JLabel("X position : ");
    buttonPanel.add(label);
    
    xposLB = new JLabel("0000.0");
    xposLB.setForeground(Color.blue);
    buttonPanel.add(xposLB);
    
    label = new JLabel(xunits);
    buttonPanel.add(label);
    
    label = new JLabel(" Y position : ");
    buttonPanel.add(label);
    
    yposLB = new JLabel("0000.0");
    yposLB.setForeground(Color.blue);
    buttonPanel.add(yposLB);
    
    label = new JLabel(yunits);
    buttonPanel.add(label);
    
    buttonPanel.add(Box.createHorizontalGlue());
    
    button = new JButton("Close");
    button.setActionCommand("close");
		button.addActionListener(this);
    buttonPanel.add(button);
    
    panel.add(buttonPanel);
    
    getContentPane().add(panel, "South");
  }
  
  // function to return a series
  private XYSeries getSeries(float[][] xydata, String name) {
    XYSeries series = new XYSeries(name);
    if(xydata != null) {
      for(int i = 0; i < xydata.length; i++) {
        series.add(xydata[i][0], xydata[i][1]);
      }
    }
    else {
      for(int i = 0; i < 10; i++) {
        series.add(i + 400, i + 20);
      }
    }
    
    return series;
  }
  
  // function to return a series
  private XYSeries getSeries(float[][] xydata, String name, int index) {
    XYSeries series = new XYSeries(name);
    if(xydata != null) {
      for(int i = 0; i < xydata.length; i++) {
        series.add(xydata[i][0], xydata[i][index]);
      }
    }
    else {
      for(int i = 0; i < 10; i++) {
        series.add(i + 100, 0);
      }
    }
    
    return series;
  }
  
  // Method to get the donor series
  private XYSeries getDonorSeries(float[][] xydata, float intensity) {
    XYSeries series = new XYSeries("Donor");
    
    //System.out.println("Intensity is " + intensity);
    
    for(int i = 0; i < xydata.length; i++) {
      series.add(xydata[i][0], xydata[i][1]*intensity);
    }
    
    return series;
  }
  
  // Method to get the acceptor series
  private XYSeries getAcceptorSeries(float[][] xydata, float intensity) {
    XYSeries series = new XYSeries("Acceptor");
    
    //System.out.println("Intensity is " + intensity);
    
    for(int i = 0; i < xydata.length; i++) {
      series.add(xydata[i][0], xydata[i][1]*intensity);
    }
    
    return series;
  }
  
  // Method to get the sum of the donor and acceptor series
  private XYSeries getSumSeries(float[][] d_xydata, float[][]a_xydata,
  float d_intensity, float a_intensity) {
    XYSeries series = new XYSeries("Sum");
    float dx = d_xydata[1][0] - d_xydata[0][0]; // find spacing between data point
    float pres = dx/2.0f; // the precision
    int d_len = d_xydata.length;
    int a_len = a_xydata.length;
    
    float minWL = 0.0f;
    if(d_xydata[0][0] < a_xydata[0][0]) {
      minWL = d_xydata[0][0];
    }
    else {
      minWL = a_xydata[0][0];
    }
    
    float maxWL = 0.0f;
    if(d_xydata[d_len - 1][0] > a_xydata[a_len - 1][0]) {
      maxWL = d_xydata[d_len - 1][0];
    }
    else {
      maxWL = a_xydata[a_len - 1][0];
    }
    
    float wl = minWL;
    int i = 0;
    int j = 0;
    
    // sum the data now
    do {
      float sum = 0;
      
      if(i < d_len) {
        float diff = Math.abs(wl - d_xydata[i][0]);
        if(diff < pres) {
          sum += d_xydata[i][1]*d_intensity;
          i++;
        }
      }
      
      if(j < a_len) {
        float diff = Math.abs(wl - a_xydata[j][0]);
        if(diff < pres) {
          sum += a_xydata[j][1]*a_intensity;
          j++;
        }
      }
      series.add(wl, sum);
      
      wl += dx;
    }
    while(wl <= maxWL);
    
    return series;
  }
  
  // Method to handel action events
	public void actionPerformed(ActionEvent ae) {
		String cmd = ae.getActionCommand();
		
		if(cmd.equals("close")) {
			setVisible(false);
      dispose();
		}
	}
  
  public void stateChanged(ChangeEvent e) {
    JSlider source = (JSlider)e.getSource();
    if (!source.getValueIsAdjusting()) {
      int xvalue = (int)source.getValue();
      int i = (int)((xvalue - minX)/dx); // locates the index in the array
      
      float d_intensity = 1.0f;
      float a_intensity = 1.0f;
      
      if(x_axis.equals("Distance")) {
        d_intensity = donor_intensity[index][i];
        a_intensity = acceptor_intensity[index][i];
      }
      else { // must be wavelength
        d_intensity = donor_intensity[i][index];
        a_intensity = acceptor_intensity[i][index];
      }
      
      // get the new data and plot it
      XYSeries d_series = getDonorSeries(donor_ems, d_intensity);
      XYSeries a_series = getAcceptorSeries(acceptor_ems, a_intensity);
      XYSeries s_series = getSumSeries(donor_ems, acceptor_ems, d_intensity, a_intensity);
      
      sim_data.removeAllSeries();
      
      sim_data.addSeries(d_series);
      sim_data.addSeries(a_series);
      sim_data.addSeries(s_series);
      
      //System.out.println("X Value is " + xvalue + " Index is " + i +
      //" Min " + minX + " dx " + dx + " Main Index " + index);
    }
  }
  
  // Method to handel chartchange events
  public void chartChanged(ChartChangeEvent event) {
    if(chartPanel != null) {
      JFreeChart chart = chartPanel.getChart();
      XYPlot plot = chart.getXYPlot();
      float xx = (float)plot.getDomainCrosshairValue();
      float yy = (float)plot.getRangeCrosshairValue();
      
      // set the labels now
      xposLB.setText("" + xx);
      yposLB.setText("" + yy);
      
      // set the currently selected wavelength or time for any listeners
      if(dsListener != null) {
        dsListener.dataPointSelected("" + xx);
      }
    }
  }
  
  // Method to set the wavelength Selected Listener
  public void setDataPointSelectedListener(DataPointSelectedListener dsListener) {
    this.dsListener = dsListener;
  }
} //--end class FRETViewPlotDialog
