/**
 * PlotSpectraGraph.java
 * Contains the graph that plots the dye spectra
 * Created: September 5 , 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.*;

// class the plots the spectras
public class PlotSpectraGraph extends JDialog implements ChartChangeListener {
  private PlotSpectraDialog psd = null;
  private ChartPanel chartPanel = null;
  private XYSeriesCollection xydata = null; // stores data to be plotted
  private JFreeChart chart = null; // plots the simulated data
  private JLabel xposLB = null;
  private String xunits = " nm";
  
  // constructor that is needed but not used
  public PlotSpectraGraph() { } 
  
  // the default constructor
  public PlotSpectraGraph(PlotSpectraDialog plotSpectraDialog) { 
    super(plotSpectraDialog.fretview, "Graph Dialog", false);
    
    psd = plotSpectraDialog;
    
    // handles clossing of this plugin
		addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
        setVisible(false);
      }
		});
    
    // set the layout
    getContentPane().setLayout(new BorderLayout());
    
    // create the graph
    String ylabel = "Intensity (a.u)";
    String xlabel = "Wavelength (nm)";
    
    xydata = new XYSeriesCollection();
    
    // now create the chart panel
    chart = ChartFactory.createXYLineChart(null, xlabel, ylabel, 
                                                          xydata,
                                                          PlotOrientation.VERTICAL,
                                                          true,
                                                          true,
                                                          false);
    // edit the chart now
    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);
    
    NumberAxis axis = (NumberAxis)plot.getRangeAxis();
    axis.setAutoRangeIncludesZero(false);
    axis.setAutoRangeMinimumSize(1.0);
    
    loadGraphData(); // load the data
    
    chartPanel = new ChartPanel(chart);
    chartPanel.setDomainZoomable(true);
    chartPanel.setRangeZoomable(true);
    
    // add the chart panel now
    getContentPane().add(chartPanel, "Center");
    
    // add the button panel now
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
    Border border = BorderFactory.createRaisedBevelBorder();
    buttonPanel.setBorder(border);
    
    JLabel 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);
    
    buttonPanel.add(Box.createHorizontalGlue());
    
    getContentPane().add(buttonPanel, "South");
  }
  
  // Method to listen to chart change events
  public void chartChanged(ChartChangeEvent event) {
    if(chart == null || xposLB == null) { //prevents null pointer exceptions
      return;
    }
    
    XYPlot plot = chart.getXYPlot();
    float xx = (float)plot.getDomainCrosshairValue();
    xposLB.setText("" + xx);
  }
  
  // Method to update the plot
  public void loadGraphData() {
    // clear any data already there
    xydata.removeAllSeries();
    
    XYPlot plot = (XYPlot)chart.getPlot();
    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);
    
    // get any data that needs to be plotted
    SpectraData sd = null;
    String name = null;
    XYSeries abs_series = null;
    XYSeries ems_series = null;
    int series_num = 0;
    
    for(int i = 0; i < psd.colors.length; i++) {
      DyeSpectra ds = psd.spectra[i];
      if(ds != null) {
        // create the absorption and emission series to be plotted
        sd = ds.getAbsorption();
        name = "Dye " + (i + 1) + "(abs)";
        abs_series = getSeries(sd.getData(), name);
        
        sd = ds.getEmission();
        name = "Dye " + (i + 1) + "(ems)";
        ems_series = getSeries(sd.getData(), name);
        
        //add the series if they are not null
        if(abs_series != null && psd.absCB[i].isSelected()) {
          xydata.addSeries(abs_series);
          r1.setSeriesPaint(series_num, psd.colors[i]);
          r1.setSeriesStroke(series_num, stroke);
          series_num++;
        }
        
        if(ems_series != null && psd.emsCB[i].isSelected()) {
          xydata.addSeries(ems_series);
          r1.setSeriesPaint(series_num, psd.colors[i]);
          r1.setSeriesStroke(series_num, dash);
          series_num++;
        }
      }
    }
  }
  
  // Method to return a series for particular data
  private XYSeries getSeries(float[][] data, String name) {
    XYSeries series= null;
    
    // make sure there is real data there
    if(data.length > 5) {
      series = new XYSeries(name);
      for(int i = 0; i < data.length; i++) {
        series.add(data[i][0], data[i][1]);
      }
    }
    
    return series;
  }
  
  // Method to close this window
  public void close() {
    setVisible(false);
  }
} // --end class PlotSpectraDialogGraph
