
/**
 * PumpProbeImageDialog.java
 * Used to view an image constructed from pump-probe data
 *
 * Created: July 17, 2005
 *
 * @author Nathan Stevens
 * @version 0.13 9/18/05
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.awt.Image;
import java.awt.geom.*;
import java.util.*;
import java.text.*;

public class PumpProbeImageDialog extends JDialog implements ActionListener {
  private PumpProbeView pumpProbeView = null;
  private JLabel minWlLB = null;
  private JLabel minTLB = null;
  private JLabel maxWlLB = null;
  private JLabel maxTLB = null;
  private JCheckBox auto_selCB = null;
  private float[][] xydata = null;
  private int width = 0;
  private int height = 0;
  private float minInt = 1000.0f;
  private float maxInt = 0.0f;
  private int[] minmax = new int[4]; // store the location of the minimum and maximum points
  
  // the defult constructor
  public PumpProbeImageDialog(PumpProbeView pumpProbeView) {
    super(pumpProbeView, "PumpProbe Image", false);
    this.pumpProbeView = pumpProbeView;
    
    // closes the program
		addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent we) {
				setVisible(false);
        dispose();
		  }
		});
    
     // Set the layout to border layout
    getContentPane().setLayout(new BorderLayout());
    
    // some gui stuff
    JPanel panel;
    JLabel label;
    JButton button;
    TitledBorder titledBorder;
    Insets insets;
    
    // add the image to the center now
    
    createDataArray(); // first cerate the data array to create image from
    
    Image ppImage = createPumpProbeImage();
    PumpProbeImagePanel imagePanel = 
    new PumpProbeImagePanel(this, ppImage, width, height, minmax);
    
    // add the image to the center panel now
    int sp_height = height;
    if(height > 500) {
      sp_height = 500;
    }
    
    JScrollPane scrollPane = new JScrollPane(imagePanel);
    scrollPane.setPreferredSize(new Dimension(500, sp_height));
    
		getContentPane().add(scrollPane, "Center");
    
    // add the south panel now
    JPanel southPanel = new JPanel();
    southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
    
    // add the panel that holds the
    JPanel infoPanel = new JPanel();
    infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.X_AXIS));
    
    // add the image gradient map
    panel = new JPanel();
    panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0,2));
    titledBorder = BorderFactory.createTitledBorder("Image Info");
    panel.setBorder(titledBorder);
    
    GradientPanel gradientPanel = new GradientPanel();
    gradientPanel.setBorder(titledBorder);
    panel.add(gradientPanel);
    
    // add the panel holding the location of the min and max
    JPanel mmPanel = new JPanel();
    mmPanel.setLayout(new GridLayout(5, 1, 0, 0));
    String text = null;
    
    text = xydata[0][minmax[2]] + " nm";
    label = new JLabel(text);
    mmPanel.add(label);
    
    text = xydata[minmax[3]][0] + " fs";
    label = new JLabel(text);
    mmPanel.add(label);
    
    label = new JLabel();
    mmPanel.add(label);
    
    text = xydata[0][minmax[0]] + " nm";
    label = new JLabel(text);
    mmPanel.add(label);
    
    text = xydata[minmax[1]][0] + " fs";
    label = new JLabel(text);
    mmPanel.add(label);
    
    panel.add(mmPanel);
    
    infoPanel.add(panel);
    
    // add the region of interest panel
    JPanel roiPanel = new JPanel();
    roiPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0,2));
    titledBorder = BorderFactory.createTitledBorder("Region Of Interest");
    roiPanel.setBorder(titledBorder);
    
    // panel holding time/wavelenght labels
    JPanel roiP1 = new JPanel();
    roiP1.setLayout(new GridLayout(5, 1, 2, 0));
    
    label = new JLabel("Wavelength (nm) ");
    roiP1.add(label);
    
    label = new JLabel();
    roiP1.add(label);
    
    label = new JLabel("Time (fs)");
    roiP1.add(label);
    
    label = new JLabel();
    roiP1.add(label);
    
    roiPanel.add(roiP1);
    
    // panel holding minimum time and wavelength values
    roiP1 = new JPanel();
    roiP1.setLayout(new GridLayout(5, 1, 2, 0));
    
    minWlLB= new JLabel("000.000");
    minWlLB.setForeground(Color.blue);
    roiP1.add(minWlLB);
    
    label = new JLabel();
    roiP1.add(label);
    
    minTLB= new JLabel("000.000");
    minTLB.setForeground(Color.blue);
    roiP1.add(minTLB);
    
    roiPanel.add(roiP1);
    
    // panel holding "to"
    roiP1 = new JPanel();
    roiP1.setLayout(new GridLayout(5, 1, 2, 0));
    
    label = new JLabel(" to ");
    roiP1.add(label);
    
    label = new JLabel();
    roiP1.add(label);
    
    label = new JLabel(" to ");
    roiP1.add(label);
    
    roiPanel.add(roiP1);
    
     // panel holding maximum time and wavelength values
    roiP1 = new JPanel();
    roiP1.setLayout(new GridLayout(5, 1, 2, 0));
    
    maxWlLB= new JLabel("000.000");
    maxWlLB.setForeground(Color.blue);
    roiP1.add(maxWlLB);
    
    label = new JLabel();
    roiP1.add(label);
    
    maxTLB= new JLabel("000.000");
    maxTLB.setForeground(Color.blue);
    roiP1.add(maxTLB);
    
    roiPanel.add(roiP1);
    
    // The roiPanel to the information panel
    infoPanel.add(roiPanel);
    
    // The infoPanel to the south panel
    southPanel.add(infoPanel);
    
    // add the set wavelength and close buttons now
    panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
    
    /*button = new JButton("Axis");
		button.setActionCommand("setwavelength");
		button.addActionListener(this);
    button.setToolTipText("Set the Wavelength Range in PumpProbeView...");
    panel.add(button); */
    
    String size = width + "  x " + height;
    
    label = new JLabel(" Image Size : ");
    panel.add(label);
    
    label = new JLabel(size);
    label.setForeground(Color.blue);
    panel.add(label);
    
    label = new JLabel(" Data : ");
    panel.add(label);
    
    label = new JLabel(pumpProbeView.filename);
    label.setForeground(Color.blue);
    panel.add(label);
    
    panel.add(Box.createHorizontalGlue());
    
    button = new JButton("Close");
		button.setActionCommand("close");
		button.addActionListener(this);
    button.setToolTipText("Close this window");
    panel.add(button);
    
    southPanel.add(panel);
    
    getContentPane().add(southPanel, "South");
  }
  
   // Method to handel action events
  public void actionPerformed(ActionEvent ae) {
    String cmd = ae.getActionCommand();
    
    if(cmd.equals("close")) {
      setVisible(false);
      dispose();
    }
    else if(cmd.equals("setwl")) {
      // code
    }
    else {
      System.err.println("Action Command not handeled in class PumpProbeImagePanel...");
      System.err.println(cmd);
    }
  }
  
  // Method to update the ROI
  public void updateROI(Rectangle rect) {
    int x1 = rect.x;
    int y1 = rect.y;
    int x2 = x1 + rect.width;
    int y2 = y1 + rect.height;
    String text = "";
    
    // update the lables
    try {
      text = "" + xydata[0][x1+1];
      minWlLB.setText(text);
      
      text = "" + xydata[y1 + 1][0];
      minTLB.setText(text);
      
      text = "" + xydata[0][x2+1];
      maxWlLB.setText(text);
      
      text = "" + xydata[y2 + 1][0];
      maxTLB.setText(text);
    }
    catch(IndexOutOfBoundsException e) { }
    
    // update the wavelength in pump probe view now location
    text = "" + xydata[0][x1+1];
    pumpProbeView.dataPointSelected(text);
  }
  
  // Method to creat the image
  private Image createPumpProbeImage() {
    int pix[] = new int[width * height];
    int index = 0;
    
    float blue_increment = maxInt/255;
    float red_increment = Math.abs(minInt/255);
    
    for (int y = 0; y < height; y++) {
	    for (int x = 0; x < width; x++) {
        int blue = 0;
        int green = 0;
        int red= 0;
        int alpha = 255;
        
        if(xydata[y+1][x + 1] > 0) {
          blue = (int)(xydata[y + 1][x + 1]/blue_increment);
        }
        else {
          red = (int)Math.abs(xydata[y +1][x + 1]/red_increment);
        }
        
        index = y*width + x;
        pix[index] = (alpha << 24) | (red << 16) | (green << 8) | blue;
	    }
    }
    
    Image image = createImage(new MemoryImageSource(width, height, pix, 0, width));
    
    return image;
  }
  
  // Method to create the 3D data array
  private void createDataArray() {
    SpectraData[] wl_sda = pumpProbeView.getWLPData(null); // get the wavelength profile SpectraData
    
    // set the size of the xydata array and image now
    float[][] data = wl_sda[0].getData();
    int xsize = data.length + 1; // must add one for axis
    int ysize = wl_sda.length + 1; // must add one for axis;
    width = data.length;
    height = wl_sda.length;
    
    xydata = new float[ysize][xsize];
    
    // add the wavelenght axis
    for(int i = 0; i < data.length; i++) {
      xydata[0][i+1] = data[i][0];
    }
    
    for(int i = 1; i < xydata.length; i++) {
      SpectraData sd = wl_sda[i-1];
      data = sd.getData();
      float delay = getTimeDelay(sd);
      xydata[i][0] = delay;
      
      for(int j = 0; j < data.length; j++) {
        float intensity = data[j][1];
        xydata[i][j+1] = intensity;
        
        // set the minimum intensity value now
        if(intensity < minInt) {
          minInt = intensity;
          minmax[0] = j + 1;
          minmax[1] = i;
        }
        
         // set the maximum intensity value now
        if(intensity > maxInt) {
          maxInt = intensity;
          minmax[2] = j+1;
          minmax[3] = i;
        }
      }
    }
  }
  
  // Method to get the time Delay
  private float getTimeDelay(SpectraData sd) {
    float delay = 0.0f;
    try {
      delay = Float.parseFloat(sd.getDelay());
    }
    catch(NumberFormatException nfe){}
    
    return delay;
  }
  
  // class to create the gradient map
  class GradientPanel extends JPanel {
    private BasicStroke stroke = new BasicStroke(2.0f);
    private int h = 70;
    private int w = 25;
    private Color red = Color.red;
    private Color black = Color.black;
    private Color blue = Color.blue;
    
    // the defualt constructor
    public GradientPanel () {
      setPreferredSize(new Dimension(w + 100, h));
    }
    
    // the paint method
    public void paint(Graphics g) {
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON);
      
      // draw the blue to black rectangle now
      GradientPaint bluetoblack = new GradientPaint(0, 0, blue, 0, h/2, black);
      g2.setPaint(bluetoblack);
      g2.fill(new Rectangle2D.Double(0, 0, w, h/2));
      
      
      // draw black to red to black rectangle now
      GradientPaint blacktored = new GradientPaint(0, h/2, black, 0, h, red);
      g2.setPaint(blacktored);
      g2.fill(new Rectangle2D.Double(0, h/2, w, h));
      
      // add the text
      g2.setPaint(black);
      
      NumberFormat nf = NumberFormat.getInstance();
      DecimalFormat df = (DecimalFormat) nf;
      df.setDecimalSeparatorAlwaysShown(true);
      df.applyPattern("0.####");
      
      String maxOD = "OD : +" + df.format(maxInt);
      g2.drawString(maxOD, w + 5, 10);
      
      String minOD = "OD : " + df.format(minInt);
      g2.drawString(minOD, w + 5, h);
      
      //String size = "Size : " + width + " , " + height;
      //g2.drawString(size, 0, h + 5);
    }
  }// --end class GradientPanel
} // --end class PumpProbeImagePanel
