
/**
 * InvitrogenFileReader.java
 * This class reads in information from spectrum data files found on invitrogen site.
 *
 * Created:  June 13, 2006
 *
 * @author Nathan Stevens
 * @version 0.1 6/21/06
 */
import java.io.*;
import java.util.Vector;

public class InvitrogenFileReader extends Thread {
  private final String DELIM = ",";
  private FRETViewPlugin plugin = null;
  private TextInputFile inputFile = null;
  private DonorAcceptorData dyeData = null;
  private File[] files = null;
  
  // Method to read in data
  public InvitrogenFileReader() { }
  
  // The main constructor
  public InvitrogenFileReader(FRETViewPlugin plugin, File[] files) {
    super("Invitrogen File Reader");
    this.plugin = plugin;
    this.files = files;
  }
  
  // The run method to read in the file
  public void run() {
    dyeData = plugin.dyeData;
    DyeSpectra ds;
    
    for(int i = 0; i < files.length; i++) {
      ds = importDataFile(files[i]);
      if(ds != null) {
        dyeData.addDyeSpectra(ds);
      }
      else {
        plugin.print("Error reading data file " + files[i].getName());
        plugin.print("It does not appear to be an Invitrogen data file...\n");
      }
    }
    
    // update the display now
    plugin.updateDisplay(true);
  }
  
  // Method to read in a file and return an SpectraData object
  private DyeSpectra importDataFile(File file) {
    inputFile = new TextInputFile(file);
    Vector abs_text = new Vector();
    Vector ems_text = new Vector();
    DyeSpectra ds = null;
    String line = null;
    float[][] abs_data = null;
    float[][] ems_data = null;
    String[] sa = null;
    
    // set some variable
    String name = getName(file);
    String notes = "Invitrogen data";
    float QY = 1.0f;
    float EC = 100.0f;
    float lifetime = 1.0f;
    
    // check to see if this is the right format
    line = inputFile.readLine();
    
    if(line.indexOf("wl,") == -1) { // just read data in
      name = line;
      notes = inputFile.readLine();
      
      line = inputFile.readLine();
      sa = line.split(DELIM);
      
      int index = sa[0].indexOf("=") + 1;
      String ecs = sa[0].substring(index);
      
      index = sa[1].indexOf("=") + 1;
      String qys = sa[1].substring(index);
      
      try {
        EC = Float.parseFloat(ecs);
        QY = Float.parseFloat(qys);
      }
      catch(NumberFormatException nfe) {
        System.err.println("Number Format Exception while reading EC & QC " 
        + " EC = " + ecs + "QY = " + qys);
      }
      catch(Exception e) { return null;}
      
      // read wl header info now
      line = inputFile.readLine();
    }
    
    //debug code
    //System.out.println("Data : " + name + "\n" + notes + "\n" + QY + "\n" + EC);
    
    // now read in the data
    while(!inputFile.eof()) {
      line = inputFile.readLine();
      if(line.indexOf("Data") == -1) {
        sa = line.split(DELIM);
        
        if(!line.startsWith(",,")) {
          abs_text.addElement(sa[0] + "," + sa[1]);
        }
        
        if(sa.length == 4 && sa[2].length() != 0 && sa[3].length() != 0) {
          ems_text.addElement(sa[2] + "," + sa[3]);
        }
      }
    }
    inputFile.close();
    
    // creat the absorbtion spectra data now
    String dmeta[] = new String[8];
    dmeta[0] = "Invitrogen";
    dmeta[1] = "Invitrogen";
    dmeta[2] = "Unknown";
    dmeta[3] = "iain.johnson@invitrogen.com";
    dmeta[4] = "Invitrogen Data";
    dmeta[5] = "mm-dd-yyyy";
    dmeta[6] = "00";
    
    // get the data array now
    abs_data  = getDataArray(abs_text);
    if(abs_data == null) return null;
    
    // now create the absorption and emission SpectraData Objects
    String min = "" + abs_data[0][0];
    String max = "" + abs_data[abs_data.length-1][0];
    String dps = "" + abs_data.length;
    
    String[] header = {min, max, dps, "Unknown", "n/a", notes};
    SpectraData abs_sd = new SpectraData(name, "transmission", header, dmeta, abs_data, null);
    
    // create the emission spectra object
    dmeta = (String[])dmeta.clone();
    
    ems_data  = getDataArray(ems_text);
    if(ems_data == null) return null;
    
    min = "" + ems_data[0][0];
    max = "" + ems_data[ems_data.length-1][0];
    dps = "" + ems_data.length;
    
    header = new String[]{min, max, dps, "RA", "n/a", "000", "Unknown", notes};
    SpectraData ems_sd = new SpectraData(name, "Em", header, dmeta, ems_data, null);
    
    // create the spectra dyespectra data object and return it
    ds = new DyeSpectra(name, abs_sd, ems_sd, EC, QY);
    ds.setNotes(notes);
    
    return ds;
  }
  
  // Method to read in a descending data array
  private float[][] getDataArray(Vector textlines) {
    Object[] lines = textlines.toArray();
    float[][] xydata = null;
    String[] sa = null;
    String line = null;
    
    if(textlines.size() != 0) {
      xydata = new float[textlines.size()][2];
      float xvalue = 0.0f;
      float yvalue = 0.0f;
      
      for(int i = 0; i < xydata.length; i++) {
        line = (String)lines[i];
        sa = line.split(DELIM);
        try {
          xvalue = Float.parseFloat(sa[0]);
          yvalue = Float.parseFloat(sa[1]);
        }
        catch (NumberFormatException nfe) {
           xvalue = 0f;
           yvalue = 0f;
        }
        catch (ArrayIndexOutOfBoundsException e) {
          System.err.println("Error Occured on data line " + i + "\n" + line);
          return null;
        }
        
        xydata[i][0] = xvalue;
        xydata[i][1] = yvalue;
      }
    }
    
    return xydata;
  }
  
  // return the name of the data object
  private String getName(File file) {
    String fn = file.getName();
    int end = fn.indexOf('.');
    String name = fn.substring(0, end);
    
    return name;
  }
} //-- end class Invitrogen Data File Reader
