package jxl.read.biff;

import common.Assert;
import common.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import jxl.Cell;
import jxl.CellFeatures;
import jxl.CellReferenceHelper;
import jxl.CellType;
import jxl.DateCell;
import jxl.HeaderFooter;
import jxl.Range;
import jxl.SheetSettings;
import jxl.WorkbookSettings;
import jxl.biff.ContinueRecord;
import jxl.biff.FormattingRecords;
import jxl.biff.Type;
import jxl.biff.WorkspaceInformationRecord;
import jxl.biff.drawing.Button;
import jxl.biff.drawing.Chart;
import jxl.biff.drawing.Comment;
import jxl.biff.drawing.Drawing;
import jxl.biff.drawing.DrawingData;
import jxl.biff.drawing.MsoDrawingRecord;
import jxl.biff.drawing.NoteRecord;
import jxl.biff.drawing.ObjRecord;
import jxl.biff.drawing.TextObjectRecord;
import jxl.biff.formula.FormulaException;
import jxl.format.PageOrientation;
import jxl.format.PaperSize;

final class SheetReader {
  private static Logger logger = Logger.getLogger(SheetReader.class);
  
  private File excelFile;
  
  private SSTRecord sharedStrings;
  
  private BOFRecord sheetBof;
  
  private BOFRecord workbookBof;
  
  private FormattingRecords formattingRecords;
  
  private int numRows;
  
  private int numCols;
  
  private Cell[][] cells;
  
  private int startPosition;
  
  private ArrayList rowProperties;
  
  private ArrayList columnInfosArray;
  
  private ArrayList sharedFormulas;
  
  private ArrayList hyperlinks;
  
  private Range[] mergedCells;
  
  private DataValidation dataValidation;
  
  private ArrayList charts;
  
  private ArrayList drawings;
  
  private DrawingData drawingData;
  
  private boolean nineteenFour;
  
  private PLSRecord plsRecord;
  
  private ButtonPropertySetRecord buttonPropertySet;
  
  private WorkspaceInformationRecord workspaceOptions;
  
  private int[] rowBreaks;
  
  private SheetSettings settings;
  
  private WorkbookSettings workbookSettings;
  
  private WorkbookParser workbook;
  
  private SheetImpl sheet;
  
  SheetReader(File f, SSTRecord sst, FormattingRecords fr, BOFRecord sb, BOFRecord wb, boolean nf, WorkbookParser wp, int sp, SheetImpl sh) {
    this.excelFile = f;
    this.sharedStrings = sst;
    this.formattingRecords = fr;
    this.sheetBof = sb;
    this.workbookBof = wb;
    this.columnInfosArray = new ArrayList();
    this.sharedFormulas = new ArrayList();
    this.hyperlinks = new ArrayList();
    this.rowProperties = new ArrayList(10);
    this.charts = new ArrayList();
    this.drawings = new ArrayList();
    this.nineteenFour = nf;
    this.workbook = wp;
    this.startPosition = sp;
    this.sheet = sh;
    this.settings = new SheetSettings();
    this.workbookSettings = this.workbook.getSettings();
  }
  
  private void addCell(Cell cell) {
    if (cell.getRow() < this.numRows && cell.getColumn() < this.numCols) {
      if (this.cells[cell.getRow()][cell.getColumn()] != null) {
        StringBuffer sb = new StringBuffer();
        CellReferenceHelper.getCellReference(cell.getColumn(), cell.getRow(), sb);
        logger.warn("Cell " + sb.toString() + " already contains data");
      } 
      this.cells[cell.getRow()][cell.getColumn()] = cell;
    } else {
      logger.warn("Cell " + CellReferenceHelper.getCellReference(cell.getColumn(), cell.getRow()) + " exceeds defined cell boundaries in Dimension record " + "(" + this.numCols + "x" + this.numRows + ")");
    } 
  }
  
  final void read() {
    Record r = null;
    BaseSharedFormulaRecord sharedFormula = null;
    boolean sharedFormulaAdded = false;
    boolean cont = true;
    this.excelFile.setPos(this.startPosition);
    MsoDrawingRecord msoRecord = null;
    ObjRecord objRecord = null;
    boolean firstMsoRecord = true;
    Window2Record window2Record = null;
    PrintGridLinesRecord printGridLinesRecord = null;
    PrintHeadersRecord printHeadersRecord = null;
    HashMap comments = new HashMap();
    while (cont) {
      r = this.excelFile.next();
      Type type = r.getType();
      if (type == Type.UNKNOWN && r.getCode() == 0) {
        logger.warn("Biff code zero found");
        if (r.getLength() == 10) {
          logger.warn("Biff code zero found - trying a dimension record.");
          r.setType(Type.DIMENSION);
        } else {
          logger.warn("Biff code zero found - Ignoring.");
        } 
      } 
      if (type == Type.DIMENSION) {
        DimensionRecord dr = null;
        if (this.workbookBof.isBiff8()) {
          dr = new DimensionRecord(r);
        } else {
          dr = new DimensionRecord(r, DimensionRecord.biff7);
        } 
        this.numRows = dr.getNumberOfRows();
        this.numCols = dr.getNumberOfColumns();
        this.cells = new Cell[this.numRows][this.numCols];
        continue;
      } 
      if (type == Type.LABELSST) {
        LabelSSTRecord label = new LabelSSTRecord(r, this.sharedStrings, this.formattingRecords, this.sheet);
        addCell(label);
        continue;
      } 
      if (type == Type.RK || type == Type.RK2) {
        RKRecord rkr = new RKRecord(r, this.formattingRecords, this.sheet);
        if (this.formattingRecords.isDate(rkr.getXFIndex())) {
          DateCell dc = new DateRecord(rkr, rkr.getXFIndex(), this.formattingRecords, this.nineteenFour, this.sheet);
          addCell((Cell)dc);
          continue;
        } 
        addCell(rkr);
        continue;
      } 
      if (type == Type.HLINK) {
        HyperlinkRecord hr = new HyperlinkRecord(r, this.sheet, this.workbookSettings);
        this.hyperlinks.add(hr);
        continue;
      } 
      if (type == Type.MERGEDCELLS) {
        MergedCellsRecord mc = new MergedCellsRecord(r, this.sheet);
        if (this.mergedCells == null) {
          this.mergedCells = mc.getRanges();
          continue;
        } 
        Range[] newMergedCells = new Range[this.mergedCells.length + (mc.getRanges()).length];
        System.arraycopy(this.mergedCells, 0, newMergedCells, 0, this.mergedCells.length);
        System.arraycopy(mc.getRanges(), 0, newMergedCells, this.mergedCells.length, (mc.getRanges()).length);
        this.mergedCells = newMergedCells;
        continue;
      } 
      if (type == Type.MULRK) {
        MulRKRecord mulrk = new MulRKRecord(r);
        int num = mulrk.getNumberOfColumns();
        int ixf = 0;
        for (int j = 0; j < num; j++) {
          ixf = mulrk.getXFIndex(j);
          NumberValue nv = new NumberValue(mulrk.getRow(), mulrk.getFirstColumn() + j, RKHelper.getDouble(mulrk.getRKNumber(j)), ixf, this.formattingRecords, this.sheet);
          if (this.formattingRecords.isDate(ixf)) {
            DateCell dc = new DateRecord(nv, ixf, this.formattingRecords, this.nineteenFour, this.sheet);
            addCell((Cell)dc);
          } else {
            nv.setNumberFormat(this.formattingRecords.getNumberFormat(ixf));
            addCell((Cell)nv);
          } 
        } 
        continue;
      } 
      if (type == Type.NUMBER) {
        NumberRecord nr = new NumberRecord(r, this.formattingRecords, this.sheet);
        if (this.formattingRecords.isDate(nr.getXFIndex())) {
          DateCell dc = new DateRecord(nr, nr.getXFIndex(), this.formattingRecords, this.nineteenFour, this.sheet);
          addCell((Cell)dc);
          continue;
        } 
        addCell(nr);
        continue;
      } 
      if (type == Type.BOOLERR) {
        BooleanRecord br = new BooleanRecord(r, this.formattingRecords, this.sheet);
        if (br.isError()) {
          ErrorRecord er = new ErrorRecord(br.getRecord(), this.formattingRecords, this.sheet);
          addCell(er);
          continue;
        } 
        addCell(br);
        continue;
      } 
      if (type == Type.PRINTGRIDLINES) {
        printGridLinesRecord = new PrintGridLinesRecord(r);
        this.settings.setPrintGridLines(printGridLinesRecord.getPrintGridLines());
        continue;
      } 
      if (type == Type.PRINTHEADERS) {
        printHeadersRecord = new PrintHeadersRecord(r);
        this.settings.setPrintHeaders(printHeadersRecord.getPrintHeaders());
        continue;
      } 
      if (type == Type.WINDOW2) {
        window2Record = new Window2Record(r);
        this.settings.setShowGridLines(window2Record.getShowGridLines());
        this.settings.setDisplayZeroValues(window2Record.getDisplayZeroValues());
        this.settings.setSelected(true);
        continue;
      } 
      if (type == Type.PANE) {
        PaneRecord pr = new PaneRecord(r);
        if (window2Record != null && window2Record.getFrozen()) {
          this.settings.setVerticalFreeze(pr.getRowsVisible());
          this.settings.setHorizontalFreeze(pr.getColumnsVisible());
        } 
        continue;
      } 
      if (type == Type.CONTINUE)
        continue; 
      if (type == Type.NOTE) {
        if (!this.workbookSettings.getDrawingsDisabled()) {
          NoteRecord nr = new NoteRecord(r);
          Comment comment = (Comment)comments.remove(new Integer(nr.getObjectId()));
          if (comment == null) {
            logger.warn(" cannot find comment for note id " + nr.getObjectId() + "...ignoring");
            continue;
          } 
          comment.setNote(nr);
          this.drawings.add(comment);
          addCellComment(comment.getColumn(), comment.getRow(), comment.getText(), comment.getWidth(), comment.getHeight());
        } 
        continue;
      } 
      if (type == Type.ARRAY)
        continue; 
      if (type == Type.PROTECT) {
        ProtectRecord pr = new ProtectRecord(r);
        this.settings.setProtected(pr.isProtected());
        continue;
      } 
      if (type == Type.SHAREDFORMULA) {
        if (sharedFormula == null) {
          logger.warn("Shared template formula is null - trying most recent formula template");
          SharedFormulaRecord lastSharedFormula = this.sharedFormulas.get(this.sharedFormulas.size() - 1);
          if (lastSharedFormula != null)
            sharedFormula = lastSharedFormula.getTemplateFormula(); 
        } 
        SharedFormulaRecord sfr = new SharedFormulaRecord(r, sharedFormula, this.workbook, this.workbook, this.sheet);
        this.sharedFormulas.add(sfr);
        sharedFormula = null;
        continue;
      } 
      if (type == Type.FORMULA || type == Type.FORMULA2) {
        DateFormulaRecord dateFormulaRecord;
        FormulaRecord fr = new FormulaRecord(r, this.excelFile, this.formattingRecords, this.workbook, this.workbook, this.sheet, this.workbookSettings);
        if (fr.isShared()) {
          BaseSharedFormulaRecord prevSharedFormula = sharedFormula;
          sharedFormula = (BaseSharedFormulaRecord)fr.getFormula();
          sharedFormulaAdded = addToSharedFormulas(sharedFormula);
          if (sharedFormulaAdded)
            sharedFormula = prevSharedFormula; 
          if (!sharedFormulaAdded && prevSharedFormula != null)
            addCell(revertSharedFormula(prevSharedFormula)); 
          continue;
        } 
        Cell cell = fr.getFormula();
        try {
          if (fr.getFormula().getType() == CellType.NUMBER_FORMULA) {
            NumberFormulaRecord nfr = (NumberFormulaRecord)fr.getFormula();
            if (this.formattingRecords.isDate(nfr.getXFIndex()))
              dateFormulaRecord = new DateFormulaRecord(nfr, this.formattingRecords, this.workbook, this.workbook, this.nineteenFour, this.sheet); 
          } 
          addCell((Cell)dateFormulaRecord);
        } catch (FormulaException e) {
          logger.warn(CellReferenceHelper.getCellReference(dateFormulaRecord.getColumn(), dateFormulaRecord.getRow()) + " " + e.getMessage());
        } 
        continue;
      } 
      if (type == Type.LABEL) {
        LabelRecord lr = null;
        if (this.workbookBof.isBiff8()) {
          lr = new LabelRecord(r, this.formattingRecords, this.sheet, this.workbookSettings);
        } else {
          lr = new LabelRecord(r, this.formattingRecords, this.sheet, this.workbookSettings, LabelRecord.biff7);
        } 
        addCell(lr);
        continue;
      } 
      if (type == Type.RSTRING) {
        RStringRecord lr = null;
        Assert.verify(!this.workbookBof.isBiff8());
        lr = new RStringRecord(r, this.formattingRecords, this.sheet, this.workbookSettings, RStringRecord.biff7);
        addCell(lr);
        continue;
      } 
      if (type == Type.NAME)
        continue; 
      if (type == Type.PASSWORD) {
        PasswordRecord pr = new PasswordRecord(r);
        this.settings.setPasswordHash(pr.getPasswordHash());
        continue;
      } 
      if (type == Type.ROW) {
        RowRecord rr = new RowRecord(r);
        if (!rr.isDefaultHeight() || !rr.matchesDefaultFontHeight() || rr.isCollapsed() || rr.hasDefaultFormat())
          this.rowProperties.add(rr); 
        continue;
      } 
      if (type == Type.BLANK) {
        if (!this.workbookSettings.getIgnoreBlanks()) {
          BlankCell bc = new BlankCell(r, this.formattingRecords, this.sheet);
          addCell(bc);
        } 
        continue;
      } 
      if (type == Type.MULBLANK) {
        if (!this.workbookSettings.getIgnoreBlanks()) {
          MulBlankRecord mulblank = new MulBlankRecord(r);
          int num = mulblank.getNumberOfColumns();
          for (int j = 0; j < num; j++) {
            int ixf = mulblank.getXFIndex(j);
            MulBlankCell mbc = new MulBlankCell(mulblank.getRow(), mulblank.getFirstColumn() + j, ixf, this.formattingRecords, this.sheet);
            addCell(mbc);
          } 
        } 
        continue;
      } 
      if (type == Type.SCL) {
        SCLRecord scl = new SCLRecord(r);
        this.settings.setZoomFactor(scl.getZoomFactor());
        continue;
      } 
      if (type == Type.COLINFO) {
        ColumnInfoRecord cir = new ColumnInfoRecord(r);
        this.columnInfosArray.add(cir);
        continue;
      } 
      if (type == Type.HEADER) {
        HeaderRecord hr = null;
        if (this.workbookBof.isBiff8()) {
          hr = new HeaderRecord(r, this.workbookSettings);
        } else {
          hr = new HeaderRecord(r, this.workbookSettings, HeaderRecord.biff7);
        } 
        HeaderFooter header = new HeaderFooter(hr.getHeader());
        this.settings.setHeader(header);
        continue;
      } 
      if (type == Type.FOOTER) {
        FooterRecord fr = null;
        if (this.workbookBof.isBiff8()) {
          fr = new FooterRecord(r, this.workbookSettings);
        } else {
          fr = new FooterRecord(r, this.workbookSettings, FooterRecord.biff7);
        } 
        HeaderFooter footer = new HeaderFooter(fr.getFooter());
        this.settings.setFooter(footer);
        continue;
      } 
      if (type == Type.SETUP) {
        SetupRecord sr = new SetupRecord(r);
        if (sr.isPortrait()) {
          this.settings.setOrientation(PageOrientation.PORTRAIT);
        } else {
          this.settings.setOrientation(PageOrientation.LANDSCAPE);
        } 
        this.settings.setPaperSize(PaperSize.getPaperSize(sr.getPaperSize()));
        this.settings.setHeaderMargin(sr.getHeaderMargin());
        this.settings.setFooterMargin(sr.getFooterMargin());
        this.settings.setScaleFactor(sr.getScaleFactor());
        this.settings.setPageStart(sr.getPageStart());
        this.settings.setFitWidth(sr.getFitWidth());
        this.settings.setFitHeight(sr.getFitHeight());
        this.settings.setHorizontalPrintResolution(sr.getHorizontalPrintResolution());
        this.settings.setVerticalPrintResolution(sr.getVerticalPrintResolution());
        this.settings.setCopies(sr.getCopies());
        if (this.workspaceOptions != null)
          this.settings.setFitToPages(this.workspaceOptions.getFitToPages()); 
        continue;
      } 
      if (type == Type.WSBOOL) {
        this.workspaceOptions = new WorkspaceInformationRecord(r);
        continue;
      } 
      if (type == Type.DEFCOLWIDTH) {
        DefaultColumnWidthRecord dcwr = new DefaultColumnWidthRecord(r);
        this.settings.setDefaultColumnWidth(dcwr.getWidth());
        continue;
      } 
      if (type == Type.DEFAULTROWHEIGHT) {
        DefaultRowHeightRecord drhr = new DefaultRowHeightRecord(r);
        if (drhr.getHeight() != 0)
          this.settings.setDefaultRowHeight(drhr.getHeight()); 
        continue;
      } 
      if (type == Type.LEFTMARGIN) {
        MarginRecord m = new LeftMarginRecord(r);
        this.settings.setLeftMargin(m.getMargin());
        continue;
      } 
      if (type == Type.RIGHTMARGIN) {
        MarginRecord m = new RightMarginRecord(r);
        this.settings.setRightMargin(m.getMargin());
        continue;
      } 
      if (type == Type.TOPMARGIN) {
        MarginRecord m = new TopMarginRecord(r);
        this.settings.setTopMargin(m.getMargin());
        continue;
      } 
      if (type == Type.BOTTOMMARGIN) {
        MarginRecord m = new BottomMarginRecord(r);
        this.settings.setBottomMargin(m.getMargin());
        continue;
      } 
      if (type == Type.HORIZONTALPAGEBREAKS) {
        HorizontalPageBreaksRecord dr = null;
        if (this.workbookBof.isBiff8()) {
          dr = new HorizontalPageBreaksRecord(r);
        } else {
          dr = new HorizontalPageBreaksRecord(r, HorizontalPageBreaksRecord.biff7);
        } 
        this.rowBreaks = dr.getRowBreaks();
        continue;
      } 
      if (type == Type.PLS) {
        this.plsRecord = new PLSRecord(r);
        continue;
      } 
      if (type == Type.DVAL)
        continue; 
      if (type == Type.HCENTER) {
        CentreRecord hr = new CentreRecord(r);
        this.settings.setHorizontalCentre(hr.isCentre());
        continue;
      } 
      if (type == Type.VCENTER) {
        CentreRecord vc = new CentreRecord(r);
        this.settings.setVerticalCentre(vc.isCentre());
        continue;
      } 
      if (type == Type.DV)
        continue; 
      if (type == Type.OBJ) {
        objRecord = new ObjRecord(r);
        if (!this.workbookSettings.getDrawingsDisabled())
          handleObjectRecord(objRecord, msoRecord, comments); 
        if (objRecord.getType() != ObjRecord.CHART) {
          objRecord = null;
          msoRecord = null;
        } 
        continue;
      } 
      if (type == Type.MSODRAWING) {
        if (!this.workbookSettings.getDrawingsDisabled()) {
          if (msoRecord != null)
            this.drawingData.addRawData(msoRecord.getData()); 
          msoRecord = new MsoDrawingRecord(r);
          if (firstMsoRecord) {
            msoRecord.setFirst();
            firstMsoRecord = false;
          } 
        } 
        continue;
      } 
      if (type == Type.BUTTONPROPERTYSET) {
        this.buttonPropertySet = new ButtonPropertySetRecord(r);
        continue;
      } 
      if (type == Type.CALCMODE) {
        CalcModeRecord cmr = new CalcModeRecord(r);
        this.settings.setAutomaticFormulaCalculation(cmr.isAutomatic());
        continue;
      } 
      if (type == Type.SAVERECALC) {
        SaveRecalcRecord cmr = new SaveRecalcRecord(r);
        this.settings.setRecalculateFormulasBeforeSave(cmr.getRecalculateOnSave());
        continue;
      } 
      if (type == Type.BOF) {
        BOFRecord br = new BOFRecord(r);
        Assert.verify(!br.isWorksheet());
        int startpos = this.excelFile.getPos() - r.getLength() - 4;
        Record r2 = this.excelFile.next();
        while (r2.getCode() != Type.EOF.value)
          r2 = this.excelFile.next(); 
        if (br.isChart()) {
          if (!this.workbook.getWorkbookBof().isBiff8()) {
            logger.warn("only biff8 charts are supported");
          } else {
            if (this.drawingData == null)
              this.drawingData = new DrawingData(); 
            if (!this.workbookSettings.getDrawingsDisabled()) {
              Chart chart = new Chart(msoRecord, objRecord, this.drawingData, startpos, this.excelFile.getPos(), this.excelFile, this.workbookSettings);
              this.charts.add(chart);
              if (this.workbook.getDrawingGroup() != null)
                this.workbook.getDrawingGroup().add(chart); 
            } 
          } 
          msoRecord = null;
          objRecord = null;
        } 
        if (this.sheetBof.isChart())
          cont = false; 
        continue;
      } 
      if (type == Type.EOF)
        cont = false; 
    } 
    this.excelFile.restorePos();
    Iterator i = this.sharedFormulas.iterator();
    while (i.hasNext()) {
      SharedFormulaRecord sfr = i.next();
      Cell[] sfnr = sfr.getFormulas(this.formattingRecords, this.nineteenFour);
      for (int sf = 0; sf < sfnr.length; sf++)
        addCell(sfnr[sf]); 
    } 
    if (!sharedFormulaAdded && sharedFormula != null)
      addCell(revertSharedFormula(sharedFormula)); 
    if (msoRecord != null && this.workbook.getDrawingGroup() != null)
      this.workbook.getDrawingGroup().setDrawingsOmitted(msoRecord, objRecord); 
    if (!comments.isEmpty())
      logger.warn("Not all comments have a corresponding Note record"); 
  }
  
  private boolean addToSharedFormulas(BaseSharedFormulaRecord fr) {
    boolean added = false;
    SharedFormulaRecord sfr = null;
    for (int i = 0, size = this.sharedFormulas.size(); i < size && !added; i++) {
      sfr = this.sharedFormulas.get(i);
      added = sfr.add(fr);
    } 
    return added;
  }
  
  private Cell revertSharedFormula(BaseSharedFormulaRecord f) {
    int pos = this.excelFile.getPos();
    this.excelFile.setPos(f.getFilePos());
    FormulaRecord fr = new FormulaRecord(f.getRecord(), this.excelFile, this.formattingRecords, this.workbook, this.workbook, FormulaRecord.ignoreSharedFormula, this.sheet, this.workbookSettings);
    try {
      DateFormulaRecord dateFormulaRecord;
      Cell cell = fr.getFormula();
      if (fr.getFormula().getType() == CellType.NUMBER_FORMULA) {
        NumberFormulaRecord nfr = (NumberFormulaRecord)fr.getFormula();
        if (this.formattingRecords.isDate(fr.getXFIndex()))
          dateFormulaRecord = new DateFormulaRecord(nfr, this.formattingRecords, this.workbook, this.workbook, this.nineteenFour, this.sheet); 
      } 
      this.excelFile.setPos(pos);
      return (Cell)dateFormulaRecord;
    } catch (FormulaException e) {
      logger.warn(CellReferenceHelper.getCellReference(fr.getColumn(), fr.getRow()) + " " + e.getMessage());
      return null;
    } 
  }
  
  final int getNumRows() {
    return this.numRows;
  }
  
  final int getNumCols() {
    return this.numCols;
  }
  
  final Cell[][] getCells() {
    return this.cells;
  }
  
  final ArrayList getRowProperties() {
    return this.rowProperties;
  }
  
  final ArrayList getColumnInfosArray() {
    return this.columnInfosArray;
  }
  
  final ArrayList getHyperlinks() {
    return this.hyperlinks;
  }
  
  final ArrayList getCharts() {
    return this.charts;
  }
  
  final ArrayList getDrawings() {
    return this.drawings;
  }
  
  final DataValidation getDataValidation() {
    return this.dataValidation;
  }
  
  final Range[] getMergedCells() {
    return this.mergedCells;
  }
  
  final SheetSettings getSettings() {
    return this.settings;
  }
  
  final int[] getRowBreaks() {
    return this.rowBreaks;
  }
  
  final WorkspaceInformationRecord getWorkspaceOptions() {
    return this.workspaceOptions;
  }
  
  final PLSRecord getPLS() {
    return this.plsRecord;
  }
  
  final ButtonPropertySetRecord getButtonPropertySet() {
    return this.buttonPropertySet;
  }
  
  private void addCellComment(int col, int row, String text, double width, double height) {
    Cell c = this.cells[row][col];
    if (c == null) {
      logger.warn("Cell at " + CellReferenceHelper.getCellReference(col, row) + " not present - adding a blank");
      MulBlankCell mbc = new MulBlankCell(row, col, 0, this.formattingRecords, this.sheet);
      CellFeatures cf = new CellFeatures();
      cf.setReadComment(text, width, height);
      mbc.setCellFeatures(cf);
      addCell(mbc);
      return;
    } 
    if (c instanceof CellFeaturesAccessor) {
      CellFeaturesAccessor cv = (CellFeaturesAccessor)c;
      CellFeatures cf = cv.getCellFeatures();
      if (cf == null) {
        cf = new CellFeatures();
        cv.setCellFeatures(cf);
      } 
      cf.setReadComment(text, width, height);
    } else {
      logger.warn("Not able to add comment to cell type " + c.getClass().getName() + " at " + CellReferenceHelper.getCellReference(col, row));
    } 
  }
  
  private void handleObjectRecord(ObjRecord objRecord, MsoDrawingRecord msoRecord, HashMap comments) {
    if (msoRecord == null) {
      logger.warn("Object record is not associated with a drawing  record - ignoring");
      return;
    } 
    if (objRecord.getType() == ObjRecord.PICTURE) {
      if (this.drawingData == null)
        this.drawingData = new DrawingData(); 
      Drawing drawing = new Drawing(msoRecord, objRecord, this.drawingData, this.workbook.getDrawingGroup());
      this.drawings.add(drawing);
      return;
    } 
    if (objRecord.getType() == ObjRecord.EXCELNOTE) {
      if (this.drawingData == null)
        this.drawingData = new DrawingData(); 
      Comment comment = new Comment(msoRecord, objRecord, this.drawingData, this.workbook.getDrawingGroup(), this.workbookSettings);
      Record r2 = this.excelFile.next();
      if (r2.getType() == Type.MSODRAWING) {
        MsoDrawingRecord mso = new MsoDrawingRecord(r2);
        comment.addMso(mso);
        r2 = this.excelFile.next();
      } 
      Assert.verify((r2.getType() == Type.TXO));
      TextObjectRecord txo = new TextObjectRecord(r2);
      comment.setTextObject(txo);
      r2 = this.excelFile.next();
      Assert.verify((r2.getType() == Type.CONTINUE));
      ContinueRecord text = new ContinueRecord(r2);
      comment.setText(text);
      r2 = this.excelFile.next();
      if (r2.getType() == Type.CONTINUE) {
        ContinueRecord formatting = new ContinueRecord(r2);
        comment.setFormatting(formatting);
      } 
      comments.put(new Integer(comment.getObjectId()), comment);
      return;
    } 
    if (objRecord.getType() == ObjRecord.BUTTON) {
      if (this.drawingData == null)
        this.drawingData = new DrawingData(); 
      Button button = new Button(msoRecord, objRecord, this.drawingData, this.workbook.getDrawingGroup(), this.workbookSettings);
      Record r2 = this.excelFile.next();
      if (r2.getType() == Type.MSODRAWING) {
        MsoDrawingRecord mso = new MsoDrawingRecord(r2);
        button.addMso(mso);
        r2 = this.excelFile.next();
      } 
      Assert.verify((r2.getType() == Type.TXO));
      TextObjectRecord txo = new TextObjectRecord(r2);
      button.setTextObject(txo);
      r2 = this.excelFile.next();
      Assert.verify((r2.getType() == Type.CONTINUE));
      ContinueRecord text = new ContinueRecord(r2);
      button.setText(text);
      r2 = this.excelFile.next();
      if (r2.getType() == Type.CONTINUE) {
        ContinueRecord formatting = new ContinueRecord(r2);
        button.setFormatting(formatting);
      } 
      this.drawings.add(button);
      return;
    } 
    if (objRecord.getType() != ObjRecord.CHART) {
      logger.warn(objRecord.getType() + " on sheet \"" + this.sheet.getName() + "\" not supported - omitting");
      if (this.drawingData == null)
        this.drawingData = new DrawingData(); 
      this.drawingData.addData(msoRecord.getData());
      if (this.workbook.getDrawingGroup() != null)
        this.workbook.getDrawingGroup().setDrawingsOmitted(msoRecord, objRecord); 
      return;
    } 
  }
  
  DrawingData getDrawingData() {
    return this.drawingData;
  }
}
