
/**
 * DataFileWriter.java
 * This class writes out a tab delimited file containing the work sheet data.
 *
 * Created:  Jan 3, 2004
 *
 * @author Nathan Stevens
 * @version 0.11 6/24/05 
 */
import java.io.File;

public class DataFileWriter extends Thread {
  private final String EXT = ".txt";
  private final String TEXT_DELIM = "//";
  private File file;
  private File directory;  //the directory where files are to be writen
  private String exnum;  // The export number
  private SpectraData[] sdata;
  private StringBuffer buffer;
  private boolean hasref = false;  //those the current data object have reference data
  
  // The main constructor
  public DataFileWriter(SpectraData[] sdata, File directory, String exnum) {
    this.sdata = sdata;
    this.directory = directory;
    this.exnum = exnum;
    buffer = new StringBuffer();
  }
  
  public void run() {
    TextOutputFile outputFile;
    
    for(int i = 0; i < sdata.length; i++) {
      SpectraData sd = sdata[i];
      
      if(sdata[i].is3D()) {
        write3Data(sdata[i]);
        continue;
      }
      
      String filename = sd.getName() + EXT;
      
      hasref = sd.hasRef();
      
      if(exnum.equals("xy1")) {
        addXYData(sd);
      }
      else if(exnum.equals("xy2")) {
        addLabels(sd);
        addXYData(sd);
      }
      else if(exnum.equals("xy3")) {
        addHeader(sd);
        addXYData(sd);
      }
      else if(exnum.equals("xy4")) {
        addHeader(sd);
        addLabels(sd);
        addXYData(sd);
      }
      else {
        System.err.println("Unkown export type...Not doing anything.");
        return;
      }
      
      // Now write out the file
      file = new File(directory, filename);
      outputFile = new TextOutputFile(file);
      String s = buffer.toString();
      outputFile.print(s);
      outputFile.close();
      
      // reset the
      buffer = new StringBuffer();
    }
  }
  
  // Method to right out streak camera data
  private void write3Data(SpectraData sd) {
    TextOutputFile outputFile;
    String filename = sd.getName() + EXT;
    
    if(exnum.equals("xy3") || exnum.equals("xy4")) {
      addHeader(sd);
    }
    
    // add the column labels
    String[] labels = SpectraDataUtil.get3DColumnLabels(sd);
    for(int i = 0; i < labels.length; i++) {
      if(i == (labels.length - 1)) {
        buffer.append(labels[i]).append("\n");
      }
      else {
        buffer.append(labels[i]).append("\t");
      }
    }
    
    // add the data now
    String[][] xydata = SpectraDataUtil.get3DStringArray(sd);
    for(int i = 0; i < xydata.length; i++) {
      for(int j = 0; j < xydata[0].length; j++) {
        if(j == (xydata[0].length - 1)) {
          buffer.append(xydata[i][j]).append("\n");
        }
        else {
          buffer.append(xydata[i][j]).append("\t");
        }
      }
    }
    
    // Now write out the file
    file = new File(directory, filename);
    outputFile = new TextOutputFile(file);
    String s = buffer.toString();
    outputFile.print(s);
    outputFile.close();
    
    // reset the buffer
    buffer = new StringBuffer();
  }
  
  // Method to add the header to the String buffer file
  private void addHeader(SpectraData sd) {
    String[] sdheader = sd.getHeader();
    String[] header = new String[sdheader.length + 1];
    
    // figure out what kind of header we have
    String exptype = sd.getType();
    
    if(exptype.equals("transmission") || exptype.equals("reflectance")) {
      header[0] = TEXT_DELIM + " Experiment Type : " + exptype + "\n";
      header[1] = TEXT_DELIM + " Min : " + sdheader[0] + " nm Max : " + sdheader[1] + " nm\n";
      header[2] = TEXT_DELIM + " Data Point Count : " + sdheader[2] + "\n";
      header[3] = TEXT_DELIM + " Cell Type : " + sdheader[3] + "\n";
      header[4] = TEXT_DELIM + " Cell Path Length : " + sdheader[4] + " mm\n";
      header[5] = TEXT_DELIM + " Notes : " + sdheader[5] + "\n";
      
      buffer.append(header[0]).append(header[1]).append(header[2]);
      buffer.append(header[3]).append(header[4]).append(header[5]);
    }
    else if(exptype.equals("Em") || exptype.equals("Ex")) {
      header[0] = TEXT_DELIM + " Experiment Type : " + exptype + "\n";
      header[1] = TEXT_DELIM + " Min : " + sdheader[0] + " nm Max : " + sdheader[1] + " nm\n";
      header[2] = TEXT_DELIM + " Data Point Count : " + sdheader[2] + "\n";
      header[3] = TEXT_DELIM + " Signal Collected @ : " + sdheader[3] + "\n";
      header[4] = TEXT_DELIM + " Slits : " + sdheader[4] + " mm Excitation/Emssion : " 
                           + sdheader[5]+ " nm\n";
      header[5] = TEXT_DELIM + " Cell Type : " + sdheader[6] + "\n";
      header[6] = TEXT_DELIM + " Notes : " + sdheader[7] + "\n";
      
      buffer.append(header[0]).append(header[1]).append(header[2]);
      buffer.append(header[3]).append(header[4]).append(header[5]);
      buffer.append(header[6]);
    }
    else if(exptype.equals("macro") || exptype.equals("micro") || exptype.equals("FT")) {
      header[0] = TEXT_DELIM + " Experiment Type : " + exptype + "\n";
      header[1] = TEXT_DELIM + " Min : " + sdheader[0] + " cm-1 Max : " + sdheader[1] + " cm-1\n";
      header[2] = TEXT_DELIM + " Data Point Count : " + sdheader[2] + "\n";
      header[3] = TEXT_DELIM + " Laser Wavelenght : " + sdheader[3] + " nm\n";
      header[4] = TEXT_DELIM + " Integration Time : " + sdheader[4] + " seconds\n";
      header[5] = TEXT_DELIM + " Cell Type : " + sdheader[5] + "\n";
      header[6] = TEXT_DELIM + " Notes : " + sdheader[6] + "\n";
      
      buffer.append(header[0]).append(header[1]).append(header[2]);
      buffer.append(header[3]).append(header[4]).append(header[5]);
      buffer.append(header[6]);
    }
    else if(exptype.equals("streak")) {
      header[0] = TEXT_DELIM + " Min Wavelength : " + sdheader[0] + " nm Max Wavelength : " + sdheader[1] + " nm\n";
      header[1] = TEXT_DELIM + " Min Time : " + sdheader[1] + " nm Max Time : " + sdheader[2] + " ps\n";
      header[2] = TEXT_DELIM + " Data Point Count : " + sdheader[4] + "\n";
      header[3] = TEXT_DELIM + " Laser Wavelength : " + sdheader[5] + " nm\n";
      header[4] = TEXT_DELIM + " Exposure Time : " + sdheader[6] + " msec\n";
      header[5] = TEXT_DELIM + " Number of Exposures : " + sdheader[7] + "\n";
      header[6] = TEXT_DELIM + " Cell Type : " + sdheader[8] + "\n";
      header[7] = TEXT_DELIM + " Notes : " + sdheader[9] + "\n";
      
      buffer.append(header[0]).append(header[1]).append(header[2]);
      buffer.append(header[3]).append(header[4]).append(header[5]);
      buffer.append(header[6]).append(header[7]);
    }
    else if(exptype.equals("oodata")) {
      header[0] = TEXT_DELIM + " Min Wavelength : " + sdheader[0] + " nm Max Wavelength : " + sdheader[1] + " nm\n";
      header[1] = TEXT_DELIM + " Data Point Count : " + sdheader[2] + "\n";
      header[2] = TEXT_DELIM + " Integration Time : " + sdheader[4] + " msec\n";
      header[3] = TEXT_DELIM + " Spectra Averaged : " + sdheader[5] + "\n";
      header[4] = TEXT_DELIM + " Cell Type : " + sdheader[7] + "\n";
      header[5] = TEXT_DELIM + " Notes : " + sdheader[8] + "\n";
      
      buffer.append(header[0]).append(header[1]).append(header[2]);
      buffer.append(header[3]).append(header[4]).append(header[5]);
    }
    else if(exptype.equals("pump-probe")) {
      header[0] = TEXT_DELIM + " Min Wavelength : " + sdheader[0] + " nm Max Wavelength : " + sdheader[1] + " nm\n";
      header[1] = TEXT_DELIM + " Data Point Count : " + sdheader[2] + "\n";
      header[2] = TEXT_DELIM + " Delay : " + sdheader[3] + " fs\n";
      header[3] = TEXT_DELIM + " Integration Time : " + sdheader[4] + " msec\n";
      header[4] = TEXT_DELIM + " Spectra Averaged : " + sdheader[5] + "\n";
      header[5] = TEXT_DELIM + " Pump Wavelength : " + sdheader[6] + " nm\n";
      header[6] = TEXT_DELIM + " Cell Type : " + sdheader[7] + "\n";
      header[7] = TEXT_DELIM + " Notes : " + sdheader[8] + "\n";
      
      buffer.append(header[0]).append(header[1]).append(header[2]);
      buffer.append(header[3]).append(header[4]).append(header[5]);
      buffer.append(header[6]).append(header[7]);
    }
    else {
      System.err.println("Unkown experiment type " + exptype + " in DataFileWriter");
      return;
    }
  }
  
  // Method to add the labels to the String buffer
  private void addLabels(SpectraData sd) {
    String[] clabels = sd.getColumnLabels();
    if(sd.getType().equals("pump-probe") || sd.getType().equals("frgs")) {
      buffer.append(clabels[0]).append("\t").append(clabels[1]).append("\tR-");
      buffer.append(clabels[1]).append("\tN-").append(clabels[1]).append("\n");
    }
    else if(hasref) {
      buffer.append(clabels[0]).append("\t").append(clabels[1]).append("\tR-");
      buffer.append(clabels[1]).append("\n");
    }
    else {
      buffer.append(clabels[0]).append("\t").append(clabels[1]).append("\n");
    }
  }
  
  // Method to add the xydata to the String buffer
  private void addXYData(SpectraData sd) {
    String[][] xydata;
    
    if(hasref) {
      xydata = SpectraDataUtil.getRefStringArray(sd);
    }
    else {
      xydata = SpectraDataUtil.getStringArray(sd);
    }
    
    for(int i = 0; i < xydata.length; i++) {
      if(sd.getType().equals("pump-probe") || sd.getType().equals("frgs")) {
        buffer.append(xydata[i][0]).append("\t").append(xydata[i][1]);
        buffer.append("\t").append(xydata[i][2]).append("\t");
        buffer.append(xydata[i][3]).append("\n");
      }
      else if(hasref) {
        buffer.append(xydata[i][0]).append("\t").append(xydata[i][1]);
        buffer.append("\t").append(xydata[i][2]).append("\n");
      }
      else {
        buffer.append(xydata[i][0]).append("\t").append(xydata[i][1]).append("\n");
      }
    }
  }
  
} // --end class DataFileWriter
