/**
 *
 */
package org.expasy.bprg;

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import jxl.Cell;
import jxl.CellType;
import jxl.NumberCell;
import jxl.Workbook;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.NumberFormat;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import org.apache.log4j.Logger;


/**
 * ne pas rechercher les peak ŕ -6Da, -12Da, ect ... si le pic 13C n'a pas été trouvé
 * @author chernand
 *
 */
public class SilacQuanti {


    /**
     * Logger
     */
    private static Logger log = Logger.getLogger(SilacQuanti.class);

    /**
     *
     */
    private static final int PROTEIN_COLUMN = 0;

    /**
     *
     */
    private static final int PEPTIDESTR_COLUMN = 1;

    /**
     *
     */
    private static final int NBLABELEDAA_COLUMN = 2;

    /**
     *
     */
    private static final int FOUNDFORMS_COLUMN = 3;

    /**
     *
     */
    private static final int MASSES_COLUMN = 4;

    /**
     *
     */
    private static final int C12INTENSITY_COLUMN = 5;

    /**
     *
     */
    private static int SUMC12_COLUMN = -1;
    /**
     *
     */
    private static int SUMC13_COLUMN = -1;
    /**
     *
     */
    private static int RATIO_COLUMN = -1;

    private WritableCellFormat orangeformat;

    private WritableCellFormat redformat;

    private WritableCellFormat boldformat;

    private WritableCellFormat twodpsFormat;

    /**
     * Parameters of quantitation to be done.
     */
    private SilacQuantiParam quantiParams;

    /**
     *
     */
    public SilacQuanti() {
        initCellFormats();
    }


    /**
     *
     */
    public boolean quantifyAndWrite(File excelFile, SilacQuantiParam quantiParams) {
        this.quantiParams = quantiParams;

        Workbook source = null;
        WritableWorkbook workbook = null;
        try {
            source = Workbook.getWorkbook(excelFile);
            File workbookFile = new File(excelFile.getParentFile(), "quanti_"+excelFile.getName());
            workbook = Workbook.createWorkbook(workbookFile, source);


            computeQuantification(workbook);

            workbook.write();
            workbook.close();
            source.close();

            //open resulting file automatically if a file named maldipepquant.txt can be found in the home folder of the user
            File homefolder = new File(System.getProperty("user.home"));
            if(homefolder.exists() && homefolder.isDirectory()) {
                File[] maldifiles = homefolder.listFiles(new FilenameFilter(){
                    public boolean accept(File dir, String name) {
                        return name.equals("maldipepquant.txt");
                    }
                });
                if(maldifiles.length == 1) {
                    BufferedReader properties = new BufferedReader(new FileReader(maldifiles[0]));
                    File excelExe = new File(properties.readLine());
                    if(excelExe.exists() && excelExe.isFile() && excelExe.getName().equalsIgnoreCase("excel.exe")) {
                        //Ending message for the user
                        JOptionPane.showMessageDialog(null, "Done!\n Opening :"+workbookFile.getCanonicalPath());
                        Runtime.getRuntime().exec("\""+excelExe.getCanonicalPath()+"\" \""+workbookFile.getPath()+"\"");
                    }
                    else {
                        //Ending message for the user
                        JOptionPane.showMessageDialog(null, "Done!\n See :"+workbookFile.getCanonicalPath()+"\n\n (But I could also open the resulting file for you\nif you put a small file named \"maldipepquant.txt\"\ncontaining the full path to the Excel executable\nin your home folder...)");
                    }
                }
                else {
                    //Ending message for the user
                    JOptionPane.showMessageDialog(null, "Done!\n See :"+workbookFile.getCanonicalPath()+"\n\n (But I could also open the resulting file for you\nif you put a small file named \"maldipepquant.txt\"\ncontaining the full path to the Excel executable\nin your home folder...)");
                }
            }
        } catch (BiffException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error : "+e.getMessage(), "Excel error", JOptionPane.ERROR_MESSAGE);
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error : "+e.getMessage(), "File error", JOptionPane.ERROR_MESSAGE);
            return false;
        } catch (WriteException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error : "+e.getMessage(), "Write error", JOptionPane.ERROR_MESSAGE);
            return false;
        }

        return true;
    }


    /**
     *
     */
    private void initCellFormats() {
        NumberFormat twodps = new NumberFormat("###,##0.##");
        twodpsFormat = new WritableCellFormat(twodps);

        WritableFont arial10fontred = new WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.RED);
        redformat = new WritableCellFormat(arial10fontred, twodps);

        WritableFont arial10fontorange = new WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.ORANGE);
        orangeformat = new WritableCellFormat(arial10fontorange, twodps);

        WritableFont arial10fontbold = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD);
        boldformat = new WritableCellFormat(arial10fontbold);

    }


    /**
     * @param workbook
     * @param identSheet
     */
    private void computeQuantification(WritableWorkbook workbook) {
        //get the sheet containing exported informations
        WritableSheet identSheet = workbook.getSheet(0);

        WritableSheet quantiSheet = null;
        int currentJobId=0;
        PhenyxSILACPeptide phenyxPeptide;
        PeptideQuantiInfos quantiPeptide;
        ArrayList<PeptideQuantiInfos> jobQuantiInfos = new ArrayList<PeptideQuantiInfos>();

        //for each original row of the export
        for(int identLine =1; identLine<identSheet.getRows() && identSheet.getCell(0,identLine).getType() != CellType.EMPTY ; identLine++) {

            //Read job id (one export can contain multiple jobs)
            int newjobid = (int)(((NumberCell)identSheet.getCell(0, identLine)).getValue());
            //If different from current one
            if( newjobid != currentJobId ) {
                if(quantiSheet!=null) {
                    // store collected infos
                    writeQuantiInfos(quantiSheet, jobQuantiInfos);
                    postprocess(quantiSheet);
                }
                //create new sheet with the new job id as title
                quantiSheet = workbook.createSheet(""+newjobid, 0);
                quantiSheet.getSettings().setVerticalFreeze(1);
                if(quantiParams.data.size()==1) {
                    initDisplay1(identSheet, quantiSheet);
                }
                else {
                    initDisplay2(identSheet, quantiSheet);
                }

                //set this new job id as the current one
                currentJobId = newjobid;
            }

            //read informations in current line of the export
            phenyxPeptide = new PhenyxSILACPeptide(identSheet.getRow(identLine));
            //compute number of interesting aa in current peptide
            int aaCounter=phenyxPeptide.getAAPresent(quantiParams.getAALabels());

            //if current peptide contains the aa we are searching
            if(aaCounter !=0) {
                //create a container for quanti infos
                quantiPeptide = new PeptideQuantiInfos();
                //collect and compute
                quantiPeptide.collectInfos(phenyxPeptide, quantiParams);
                //store
                if(quantiPeptide.getProteinName()!=null) {
                    jobQuantiInfos.add(quantiPeptide);
                }

            }

        }

        if(quantiSheet!=null) {
            // store remaining collected infos
            writeQuantiInfos(quantiSheet, jobQuantiInfos);
            postprocess(quantiSheet);
        }


    }


    /**
     *
     */
    private void writeQuantiInfos(WritableSheet quantiSheet, ArrayList<PeptideQuantiInfos> infos) {
        int quantiLine = 1;
        for (PeptideQuantiInfos peptideInfos : infos) {
            addLabelToSheet(quantiSheet, PROTEIN_COLUMN, quantiLine, peptideInfos.getProteinName(), null);
            addLabelToSheet(quantiSheet, PEPTIDESTR_COLUMN, quantiLine, peptideInfos.getPeptideString(), null);
            addNumberToSheet(quantiSheet, NBLABELEDAA_COLUMN, quantiLine, peptideInfos.getLabeledAANumber(), null);
            addLabelToSheet(quantiSheet, FOUNDFORMS_COLUMN, quantiLine, peptideInfos.getForm(), null);
            addLabelToSheet(quantiSheet, MASSES_COLUMN, quantiLine,  peptideInfos.getMasses(), null);

            if(peptideInfos.isFileFound()) {
                //add intensities to excel file
                //show in orange if -2 val > -1
                //show in orange if -1 val > val
                //show in red if +6 > val heavy

                // write light values (only C12 values, never -1Da nor -2Da)
                int beginColumn = C12INTENSITY_COLUMN;
                double lightAreas = peptideInfos.getC12Areas();
                addDoubleToSheet(quantiSheet, beginColumn, quantiLine, lightAreas, twodpsFormat);
                beginColumn++;
//                if(quantiParams.findEchoPeaks>=1) {
//                    addDoubleToSheet(quantiSheet, beginColumn, quantiLine, lightAreas[1],
//                            lightAreas[1]>lightAreas[0]?orangeformat:twodpsFormat);
//                    beginColumn++;
//                    if(quantiParams.findEchoPeaks==2) {
//                        addDoubleToSheet(quantiSheet, beginColumn, quantiLine, lightAreas[2],
//                                lightAreas[2]>lightAreas[1]?orangeformat:twodpsFormat);
//                        beginColumn++;
//                    }
//                }
                // write heavy values
                double[] heavyAreas = peptideInfos.getC13Areas();
                addDoubleToSheet(quantiSheet, beginColumn, quantiLine, heavyAreas[0], twodpsFormat);
                beginColumn++;
                if(quantiParams.findEchoPeaks>=1) {
                    addDoubleToSheet(quantiSheet, beginColumn, quantiLine, heavyAreas[1],
                            heavyAreas[1]>heavyAreas[0]?orangeformat:twodpsFormat);
                    beginColumn++;
                    if(quantiParams.findEchoPeaks==2) {
                        addDoubleToSheet(quantiSheet, beginColumn, quantiLine, heavyAreas[2],
                                heavyAreas[2]>heavyAreas[1]?orangeformat:twodpsFormat);
                        beginColumn++;
                    }
                }
                //write intermediate values
                double[][] intermAreas = peptideInfos.getIntermAreas();
                if(intermAreas!=null) {
                    for (int i = 0; i < intermAreas.length; i++) {
                        addDoubleToSheet(quantiSheet, beginColumn, quantiLine, intermAreas[i][0],
                                intermAreas[i][0]>heavyAreas[0]?redformat:twodpsFormat);
                        beginColumn++;
                        if(quantiParams.findEchoPeaks>=1) {
                            addDoubleToSheet(quantiSheet, beginColumn, quantiLine, intermAreas[i][1],
                                    intermAreas[i][1]>intermAreas[i][0]?orangeformat:twodpsFormat);
                            beginColumn++;
                            if(quantiParams.findEchoPeaks==2) {
                                addDoubleToSheet(quantiSheet, beginColumn, quantiLine, intermAreas[i][2],
                                        intermAreas[i][2]>intermAreas[i][1]?orangeformat:twodpsFormat);
                                beginColumn++;
                            }
                        }

                    }
                }

                //ratios
                double sumLightForms = peptideInfos.getSumLightForms();
                double sumHeavyForms = peptideInfos.getSumHeavyForms();
                addDoubleToSheet(quantiSheet, SUMC12_COLUMN, quantiLine, sumLightForms, twodpsFormat);
                addDoubleToSheet(quantiSheet, SUMC13_COLUMN, quantiLine, sumHeavyForms, twodpsFormat);
                //ratio light/heavy
                if (sumHeavyForms!=0) {
                    addDoubleToSheet(quantiSheet, RATIO_COLUMN, quantiLine, sumLightForms/sumHeavyForms, null);
                }
                else {
                    addLabelToSheet(quantiSheet, RATIO_COLUMN, quantiLine, "Division par 0", null);
                }
            }

            quantiLine++;
        }
    }

    /**
     * @param quantiSheet
     */
    private void postprocess(WritableSheet quantiSheet) {
        //merge cells with similar data (prot/pept/masses) only different forms (Light/Heavy)
        mergeSimilarLines(quantiSheet);
        //Autofit formating to cells
        //NB: quantiSheet.getColumnView(5).setAutosize(true); doesn't work...
        autoFit(quantiSheet);

    }

    private void mergeSimilarLines(WritableSheet sheet) {
        log.debug("Merging similar lines...");
        String protName, peptSeq, descrMasses;
        String protName2, peptSeq2, descrMasses2;

        for (int rowStart = 1; rowStart < sheet.getRows(); rowStart++) {
            protName = sheet.getCell(PROTEIN_COLUMN, rowStart).getContents();
            if(protName.equals("")) continue;
            peptSeq = sheet.getCell(PEPTIDESTR_COLUMN, rowStart).getContents();
            descrMasses = sheet.getCell(MASSES_COLUMN, rowStart).getContents();
//            log.debug("Reference line ["+rowStart+"] : "+protName+"*"+peptSeq+"*"+descrMasses);

            for (int rowComp = rowStart+1; rowComp < sheet.getRows(); rowComp++) {
                protName2 = sheet.getCell(PROTEIN_COLUMN, rowComp).getContents();
                if(protName2.equals("")) continue;
                peptSeq2 = sheet.getCell(PEPTIDESTR_COLUMN, rowComp).getContents();
                descrMasses2 = sheet.getCell(MASSES_COLUMN, rowComp).getContents();
//                log.debug("Compared to line ["+rowComp+"] : "+protName2+"*"+peptSeq2+"*"+descrMasses2);

                if(protName.equals(protName2) && peptSeq.equals(peptSeq2) && descrMasses.equals(descrMasses2)) {
                    String form1 = sheet.getCell(FOUNDFORMS_COLUMN, rowStart).getContents();
                    String form2 = sheet.getCell(FOUNDFORMS_COLUMN, rowComp).getContents();
                    String newLabel = form1.compareTo(form2)<0?form1+"+"+form2:form2+"+"+form1;
//                    log.debug("Are the same! New label :"+newLabel);
                    addLabelToSheet(sheet, FOUNDFORMS_COLUMN, rowStart, newLabel, null);
                    sheet.removeRow(rowComp);
                }
            }
        }

    }

    /**
     * Autofit formating to cells
     * @param sheet to format
     */
    private void autoFit(WritableSheet sheet) {
        // ***********************************************************
        // This method traverse the sheet, column by column (written
        // of course) and set the width of each one. It takes the
        // length of each cell in a column to determine the longest.
        //
        // FontMetric return a value in pixels. To convert this
        // value to Excel`s measurement unit use the next formula:
        // (pixels-5)/7.
        // ***********************************************************
        int maxLength; // Maximum cell width
        int length; // Cell width
        int style; // Font style
        Cell cell;
        FontMetrics fm = null;
        Font font;
        jxl.format.Font cellFont;
        // ***********************************************************
        // Instantiate graphic environment to use FontMetrics
        // ***********************************************************
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        BufferedImage image = new BufferedImage(1, 1, 1);
        Graphics g = env.createGraphics(image);
        // ***********************************************************
        for (int col = 0; col < sheet.getColumns(); col++) {
            maxLength = 0;
            length = 0;
            for (int row = 0; row < sheet.getRows(); row++) {
                cell = sheet.getCell(col, row);
                //
                // Get actually cell font and style
                if (cell.getContents() == "")
                    continue; // CellType.EMPTY could be used too.
                cellFont = cell.getCellFormat().getFont();
                if (cellFont.getBoldWeight() == Font.BOLD)
                    style = Font.BOLD;
                else
                    style = Font.PLAIN;
                //
                font = new Font(cellFont.getName(), style, cellFont.getPointSize());
                fm = g.getFontMetrics(font);

                // Set string´s width in pixels
                length = fm.stringWidth(cell.getContents());

                // Store maximum length value
                if (length > maxLength)
                    maxLength = length;
            }
            // Convert maxlength from pixels to excel's measurement
            // unit. The width of a column is the quantity of
            // characters that can fit in that column
            // using the default font (usually ARIAL, size:10,
            // style:Plain)
            //
            // Set maxLength to the true size in pixels
            maxLength=(int)( Math.ceil(maxLength*1.5));
            // Convert from pixels to excel's measurement unit
            // and set column width
            if (maxLength > 0)
                sheet.setColumnView(col, ((int) Math.ceil((maxLength - 5) / 7)));

        }
    }



    /**
     * @param identSheet
     * @param quantiSheet
     * @return
     */
    private void initDisplay1(WritableSheet identSheet, WritableSheet quantiSheet) {
        //compute max aa counter to align all sumc12 and...
        int aaCounterMax = computeMaxAACounter(identSheet, quantiParams.data.get(0).aminoacid.charAt(0));
        //compute position of the first sum column
        SUMC12_COLUMN = MASSES_COLUMN
                    +1 // position of the c12 column
                    +(1+(quantiParams.findIntermPeaks?aaCounterMax-1:0))*(quantiParams.findEchoPeaks+1)//number of int columns
                    +1; //right after them
        SUMC13_COLUMN = SUMC12_COLUMN+1;
        RATIO_COLUMN = SUMC12_COLUMN+2;
        //add headers to the sheet
        addHeaders1(quantiSheet, aaCounterMax);
    }

    private void initDisplay2(WritableSheet identSheet, WritableSheet quantiSheet) {
        //compute position of the first sum column
        SUMC12_COLUMN = MASSES_COLUMN
                    +1+(quantiParams.findEchoPeaks+1)//number of int columns
                    +1; //right after them
        SUMC13_COLUMN = SUMC12_COLUMN+1;
        RATIO_COLUMN = SUMC12_COLUMN+2;
        //add headers to the sheet
        addHeaders2(quantiSheet);
    }

    /**
     * @param identSheet
     * @return
     */
    private int computeMaxAACounter(WritableSheet identSheet, char aa) {
        Cell pepCell;
        int aaCounterMax=0;
        for(int identLine =1; identLine<identSheet.getRows(); identLine++) {
            pepCell = identSheet.getCell(2,identLine);
            String peptideStr = pepCell.getContents();
            int aaCounter=0;
            for(int j=0; j<peptideStr.length();j++) {
                if(peptideStr.charAt(j) == aa) aaCounter++;
            }
            if(aaCounter>aaCounterMax) aaCounterMax = aaCounter;
        }
        return aaCounterMax;
    }


    /**
     * @param quantiSheet
     * @param aaCounterMax
     * @param indexSumC12Col
     */
    private void addHeaders1(WritableSheet quantiSheet, int aaCounterMax) {
        addLabelToSheet(quantiSheet, PROTEIN_COLUMN, 0, "Proteines", boldformat);
        addLabelToSheet(quantiSheet, PEPTIDESTR_COLUMN, 0, "Peptides", boldformat);
        addLabelToSheet(quantiSheet, NBLABELEDAA_COLUMN, 0, "Labeled AA nb", boldformat);
        addLabelToSheet(quantiSheet, FOUNDFORMS_COLUMN, 0, "Forms", boldformat);
        addLabelToSheet(quantiSheet, MASSES_COLUMN, 0, "Masses", boldformat);

        int startIntensitiesCol = C12INTENSITY_COLUMN;
        addLabelToSheet(quantiSheet, startIntensitiesCol, 0, "Light Form", boldformat);
//        if(quantiParams.findEchoPeaks>=1) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "C12-1Da", boldformat);
//        if(quantiParams.findEchoPeaks==2) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "C12-2Da", boldformat);

        addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "Heavy Form", boldformat);
        if(quantiParams.findEchoPeaks>=1) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF -1Da", boldformat);
        if(quantiParams.findEchoPeaks==2) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF -2Da", boldformat);

        if(quantiParams.findIntermPeaks) {
            int multiplier = quantiParams.data.get(0).shift.intValue();//we only do this if we have one label
            for (int daShift = multiplier  ; startIntensitiesCol<SUMC12_COLUMN-1 && daShift<(int)(aaCounterMax*multiplier); daShift+=multiplier) {
                addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF"+" -"+daShift+"Da", boldformat);
                if(quantiParams.findEchoPeaks>=1) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF"+" -"+daShift+"-1Da", boldformat);
                if(quantiParams.findEchoPeaks==2) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF"+" -"+daShift+"-2Da", boldformat);
            }
        }

        addLabelToSheet(quantiSheet, SUMC12_COLUMN, 0, "Sum LF", boldformat);
        addLabelToSheet(quantiSheet, SUMC13_COLUMN, 0, "Sum HF", boldformat);
        addLabelToSheet(quantiSheet, RATIO_COLUMN, 0, "LF / HF", boldformat);
    }

    /**
     * @param quantiSheet
     * @param aaCounterMax
     * @param indexSumC12Col
     */
    private void addHeaders2(WritableSheet quantiSheet) {
        addLabelToSheet(quantiSheet, PROTEIN_COLUMN, 0, "Proteines", boldformat);
        addLabelToSheet(quantiSheet, PEPTIDESTR_COLUMN, 0, "Peptides", boldformat);
        addLabelToSheet(quantiSheet, NBLABELEDAA_COLUMN, 0, "Labeled AA nb", boldformat);
        addLabelToSheet(quantiSheet, FOUNDFORMS_COLUMN, 0, "Forms", boldformat);
        addLabelToSheet(quantiSheet, MASSES_COLUMN, 0, "Masses", boldformat);

        int startIntensitiesCol = C12INTENSITY_COLUMN;
        addLabelToSheet(quantiSheet, startIntensitiesCol, 0, "Light Form", boldformat);
//        if(quantiParams.findEchoPeaks>=1) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "C12-1Da", boldformat);
//        if(quantiParams.findEchoPeaks==2) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "C12-2Da", boldformat);

        addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "Heavy Form", boldformat);
        if(quantiParams.findEchoPeaks>=1) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF -1Da", boldformat);
        if(quantiParams.findEchoPeaks==2) addLabelToSheet(quantiSheet, ++startIntensitiesCol, 0, "HF -2Da", boldformat);

        addLabelToSheet(quantiSheet, SUMC12_COLUMN, 0, "Sum LF", boldformat);
        addLabelToSheet(quantiSheet, SUMC13_COLUMN, 0, "Sum HF", boldformat);
        addLabelToSheet(quantiSheet, RATIO_COLUMN, 0, "LF / HF", boldformat);
    }




    /**
     * @param quantiSheet
     * @param label
     */
    private void addLabelToSheet(WritableSheet sheet, int i, int j, String text, WritableCellFormat format) {
        try {
            if(format == null) {
                sheet.addCell(new Label(i, j, text));
            }
            else {
                sheet.addCell(new Label(i, j, text, format));
            }
        } catch (RowsExceededException e1) {
            e1.printStackTrace();
        } catch (WriteException e1) {
            e1.printStackTrace();
        }
    }

    /**
     * @param quantiSheet
     * @param label
     */
    private void addNumberToSheet(WritableSheet sheet, int i, int j, int value, WritableCellFormat format) {
        try {
            if(format == null) {
                sheet.addCell(new Number(i, j, value));
            }
            else {
                sheet.addCell(new Number(i, j, value, format));
            }
        } catch (RowsExceededException e1) {
            e1.printStackTrace();
        } catch (WriteException e1) {
            e1.printStackTrace();
        }
    }

    /**
     * @param quantiSheet
     * @param label
     */
    private void addDoubleToSheet(WritableSheet sheet, int i, int j, double value, WritableCellFormat format) {
        try {
            if(value == -1) { return;} //displays -1 values as "" //addLabelToSheet(sheet, i, j, "", null);
            if(value == 0) {addLabelToSheet(sheet, i, j, "?", null); return;}//displays 0 values as "?"

            if(format == null) {
                sheet.addCell(new Number(i, j, value));
            }
            else {
                sheet.addCell(new Number(i, j, value, format));
            }
        } catch (RowsExceededException e1) {
            e1.printStackTrace();
        } catch (WriteException e1) {
            e1.printStackTrace();
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {

    }


}




