
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache POI" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache POI", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.poi.hssf.model;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import org.apache.poi.hssf
    .record.*;       // normally I don't do this, buy we literally mean ALL
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.*;
import org.apache.poi.hssf.record
    .aggregates.*;   // normally I don't do this, buy we literally mean ALL

/**
 * Low level model implementation of a Sheet (one workbook contains many sheets)
 * This file contains the low level binary records starting at the sheets BOF and
 * ending with the sheets EOF.  Use HSSFSheet for a high level representation.
 * <P>
 * The structures of the highlevel API use references to this to perform most of their
 * operations.  Its probably unwise to use these low level structures directly unless you
 * really know what you're doing.  I recommend you read the Microsoft Excel 97 Developer's
 * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf
 * before even attempting to use this.
 * <P>
 * @author  Andrew C. Oliver (acoliver at apache dot org)
 * @author  Glen Stampoultzis (glens at apache.org)
 * @author  Shawn Laubach (slaubach at apache dot org) Gridlines, Headers, Footers, and PrintSetup
 * @author Jason Height (jheight at chariot dot net dot au) Clone support
 * @author  Brian Sanders (kestrel at burdell dot org) Active Cell support
 *
 * @see org.apache.poi.hssf.model.Workbook
 * @see org.apache.poi.hssf.usermodel.HSSFSheet
 * @version 1.0-pre
 */

public class Sheet implements Model
{
    public static final short   LeftMargin = 0;
    public static final short   RightMargin = 1;
    public static final short   TopMargin = 2;
    public static final short   BottomMargin = 3;

    protected ArrayList                 records        = null;
    int                                 preoffset      = 0;      // offset of the sheet in a new file
    int                                 loc            = 0;
    protected boolean                   containsLabels = false;
    protected int                       dimsloc        = 0;
    protected DimensionsRecord          dims;
    protected DefaultColWidthRecord     defaultcolwidth  = null;
    protected DefaultRowHeightRecord    defaultrowheight = null;
    protected GridsetRecord             gridset          = null;
    protected PrintSetupRecord          printSetup       = null;
    protected HeaderRecord              header           = null;
    protected FooterRecord              footer           = null;
    protected PrintGridlinesRecord      printGridlines   = null;
    protected WindowTwoRecord           windowTwo        = null;
    protected MergeCellsRecord          merged           = null;
    protected Margin                    margins[]        = null;
    protected List                 		mergedRecords    = new ArrayList();
    protected int                       numMergedRegions = 0;
    protected SelectionRecord           selection        = null;
    private static POILogger            log              = POILogFactory.getLogger(Sheet.class);
    private ArrayList                   columnSizes      = null;  // holds column info
    protected ValueRecordsAggregate     cells            = null;
    protected RowRecordsAggregate       rows             = null;
    private Iterator                    valueRecIterator = null;
    private Iterator                    rowRecIterator   = null;
    protected int                       eofLoc           = 0;
	protected ProtectRecord             protect          = null;

    public static final byte PANE_LOWER_RIGHT = (byte)0;
    public static final byte PANE_UPPER_RIGHT = (byte)1;
    public static final byte PANE_LOWER_LEFT = (byte)2;
    public static final byte PANE_UPPER_LEFT = (byte)3;

    /**
     * Creates new Sheet with no intialization --useless at this point
     * @see #createSheet(List,int,int)
     */
    public Sheet()
    {
    }

    /**
     * read support  (offset used as starting point for search) for low level
     * API.  Pass in an array of Record objects, the sheet number (0 based) and
     * a record offset (should be the location of the sheets BOF record).  A Sheet
     * object is constructed and passed back with all of its initialization set
     * to the passed in records and references to those records held. This function
     * is normally called via Workbook.
     *
     * @param recs array containing those records in the sheet in sequence (normally obtained from RecordFactory)
     * @param sheetnum integer specifying the sheet's number (0,1 or 2 in this release)
     * @param offset of the sheet's BOF record
     *
     * @return Sheet object with all values set to those read from the file
     *
     * @see org.apache.poi.hssf.model.Workbook
     * @see org.apache.poi.hssf.record.Record
     */
    public static Sheet createSheet(List recs, int sheetnum, int offset)
    {
        log.logFormatted(log.DEBUG,
                         "Sheet createSheet (existing file) with %",
                         new Integer(recs.size()));
        Sheet     retval             = new Sheet();
        ArrayList records            = new ArrayList(recs.size() / 5);
        boolean   isfirstcell        = true;
        boolean   isfirstrow         = true;
        int       bofEofNestingLevel = 0;

        for (int k = offset; k < recs.size(); k++)
        {
            Record rec = ( Record ) recs.get(k);

            if (rec.getSid() == LabelRecord.sid)
            {
                log.log(log.DEBUG, "Hit label record.");
                retval.containsLabels = true;
            }
            else if (rec.getSid() == BOFRecord.sid)
            {
                bofEofNestingLevel++;
                log.log(log.DEBUG, "Hit BOF record. Nesting increased to " + bofEofNestingLevel);
            }
            else if (rec.getSid() == EOFRecord.sid)
            {
                --bofEofNestingLevel;
                log.log(log.DEBUG, "Hit EOF record. Nesting decreased to " + bofEofNestingLevel);
                if (bofEofNestingLevel == 0) {
                    records.add(rec);
                    retval.eofLoc = k;
                    break;
                }
            }
            else if (rec.getSid() == DimensionsRecord.sid)
            {
                retval.dims    = ( DimensionsRecord ) rec;
                retval.dimsloc = records.size();
            }
            else if (rec.getSid() == MergeCellsRecord.sid)
            {
                retval.mergedRecords.add(rec);
                retval.merged = ( MergeCellsRecord ) rec;
                retval.numMergedRegions += retval.merged.getNumAreas();
            }
            else if (rec.getSid() == ColumnInfoRecord.sid)
            {
                if (retval.columnSizes == null)
                {
                    retval.columnSizes = new ArrayList();
                }
                retval.columnSizes.add(rec);
            }
            else if (rec.getSid() == DefaultColWidthRecord.sid)
            {
                retval.defaultcolwidth = ( DefaultColWidthRecord ) rec;
            }
            else if (rec.getSid() == DefaultRowHeightRecord.sid)
            {
                retval.defaultrowheight = ( DefaultRowHeightRecord ) rec;
            }
            else if ( rec.isValue() && bofEofNestingLevel == 1 )
            {
                if ( isfirstcell )
                {
                    retval.cells = new ValueRecordsAggregate();
                    rec = retval.cells;
                    retval.cells.construct( k, recs );
                    isfirstcell = false;
                }
                else
                {
                    rec = null;
                }
            }
            else if ( rec.getSid() == StringRecord.sid )
            {
                rec = null;
            }
            else if ( rec.getSid() == RowRecord.sid )
            {
                RowRecord row = (RowRecord)rec;
                if (!isfirstrow) rec = null; //only add the aggregate once

                if ( isfirstrow )
                {
                    retval.rows = new RowRecordsAggregate();
                    rec = retval.rows;                    
                    isfirstrow = false;
                }
                retval.rows.insertRow(row);
            }
            else if ( rec.getSid() == PrintGridlinesRecord.sid )
            {
                retval.printGridlines = (PrintGridlinesRecord) rec;
            }
            else if ( rec.getSid() == HeaderRecord.sid && bofEofNestingLevel == 1)
            {
                retval.header = (HeaderRecord) rec;
            }
            else if ( rec.getSid() == FooterRecord.sid && bofEofNestingLevel == 1)
            {
                retval.footer = (FooterRecord) rec;
            }
            else if ( rec.getSid() == PrintSetupRecord.sid && bofEofNestingLevel == 1)
            {
                retval.printSetup = (PrintSetupRecord) rec;
            }
            else if ( rec.getSid() == LeftMarginRecord.sid)
            {
                retval.getMargins()[LeftMargin] = (LeftMarginRecord) rec;
            }
            else if ( rec.getSid() == RightMarginRecord.sid)
            {
                retval.getMargins()[RightMargin] = (RightMarginRecord) rec;
            }
            else if ( rec.getSid() == TopMarginRecord.sid)
            {
                retval.getMargins()[TopMargin] = (TopMarginRecord) rec;
            }
            else if ( rec.getSid() == BottomMarginRecord.sid)
            {
                retval.getMargins()[BottomMargin] = (BottomMarginRecord) rec;
            }
            else if ( rec.getSid() == SelectionRecord.sid )
            {
                retval.selection = (SelectionRecord) rec;
            }
            else if ( rec.getSid() == WindowTwoRecord.sid )
            {
                retval.windowTwo = (WindowTwoRecord) rec;
            }
			else if ( rec.getSid() == ProtectRecord.sid )
			{
				retval.protect = (ProtectRecord) rec;
			}

            if (rec != null)
            {
                records.add(rec);
            }
        }
        retval.records = records;
//        if (retval.rows == null)
//        {
//            retval.rows = new RowRecordsAggregate();
//        }
        retval.checkCells();
        retval.checkRows();
//        if (retval.cells == null)
//        {
//            retval.cells = new ValueRecordsAggregate();
//        }
        log.log(log.DEBUG, "sheet createSheet (existing file) exited");
        return retval;
    }

    /**
     * Clones the low level records of this sheet and returns the new sheet instance.
     * This method is implemented by adding methods for deep cloning to all records that
     * can be added to a sheet. The <b>Record</b> object does not implement cloneable. 
     * When adding a new record, implement a public clone method if and only if the record
     * belongs to a sheet. 
     */
    public Sheet cloneSheet()
    {
      ArrayList clonedRecords = new ArrayList(this.records.size());
      for (int i=0; i<this.records.size();i++) {
        Record rec = (Record)((Record)this.records.get(i)).clone();
        //Need to pull out the Row record and the Value records from their
        //Aggregates.
        //This is probably the best way to do it since we probably dont want the createSheet
        //To cater for these artificial Record types
        if (rec instanceof RowRecordsAggregate) {
          RowRecordsAggregate rrAgg = (RowRecordsAggregate)rec;
          for (Iterator rowIter = rrAgg.getIterator();rowIter.hasNext();) {
            Record rowRec = (Record)rowIter.next();
            clonedRecords.add(rowRec);
          }
        } else if (rec instanceof ValueRecordsAggregate) {
          ValueRecordsAggregate vrAgg = (ValueRecordsAggregate)rec;
          for (Iterator cellIter = vrAgg.getIterator();cellIter.hasNext();) {
            Record valRec = (Record)cellIter.next();
            clonedRecords.add(valRec);
          }
        } else if (rec instanceof FormulaRecordAggregate) {
          FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)rec;
          Record fmAggRec = fmAgg.getFormulaRecord();
          if (fmAggRec != null)
            clonedRecords.add(fmAggRec);
          fmAggRec =   fmAgg.getStringRecord();
          if (fmAggRec != null)
            clonedRecords.add(fmAggRec);
        } else {
          clonedRecords.add(rec);
        }
      }
      return createSheet(clonedRecords, 0, 0);
    }


    /**
     * read support  (offset = 0) Same as createSheet(Record[] recs, int, int)
     * only the record offset is assumed to be 0.
     *
     * @param records  array containing those records in the sheet in sequence (normally obtained from RecordFactory)
     * @param sheetnum integer specifying the sheet's number (0,1 or 2 in this release)
     * @return Sheet object
     */

    public static Sheet createSheet(List records, int sheetnum)
    {
        log.log(log.DEBUG,
                "Sheet createSheet (exisiting file) assumed offset 0");
        return createSheet(records, sheetnum, 0);
    }

    /**
     * Creates a sheet with all the usual records minus values and the "index"
     * record (not required).  Sets the location pointer to where the first value
     * records should go.  Use this to create a sheet from "scratch".
     *
     * @return Sheet object with all values set to defaults
     */

    public static Sheet createSheet()
    {
        log.log(log.DEBUG, "Sheet createsheet from scratch called");
        Sheet     retval  = new Sheet();
        ArrayList records = new ArrayList(30);

        records.add(retval.createBOF());

        // records.add(retval.createIndex());
        records.add(retval.createCalcMode());
        records.add(retval.createCalcCount() );
        records.add( retval.createRefMode() );
        records.add( retval.createIteration() );
        records.add( retval.createDelta() );
        records.add( retval.createSaveRecalc() );
        records.add( retval.createPrintHeaders() );
        retval.printGridlines = (PrintGridlinesRecord) retval.createPrintGridlines();
        records.add( retval.printGridlines );
        retval.gridset = (GridsetRecord) retval.createGridset();
        records.add( retval.gridset );
        records.add( retval.createGuts() );
        retval.defaultrowheight =
                (DefaultRowHeightRecord) retval.createDefaultRowHeight();
        records.add( retval.defaultrowheight );
        records.add( retval.createWSBool() );
        retval.header = (HeaderRecord) retval.createHeader();
        records.add( retval.header );
        retval.footer = (FooterRecord) retval.createFooter();
        records.add( retval.footer );
        records.add( retval.createHCenter() );
        records.add( retval.createVCenter() );
        retval.printSetup = (PrintSetupRecord) retval.createPrintSetup();
        records.add( retval.printSetup );
        retval.defaultcolwidth =
                (DefaultColWidthRecord) retval.createDefaultColWidth();
        records.add( retval.defaultcolwidth);
        retval.dims    = ( DimensionsRecord ) retval.createDimensions();
        retval.dimsloc = 19;
        records.add(retval.dims);
        records.add(retval.windowTwo = retval.createWindowTwo());
        retval.setLoc(records.size() - 1);
        retval.selection = 
                (SelectionRecord) retval.createSelection();
        records.add(retval.selection);
		retval.protect = (ProtectRecord) retval.createProtect();
		records.add(retval.protect);
        records.add(retval.createEOF());
        retval.records = records;
        log.log(log.DEBUG, "Sheet createsheet from scratch exit");
        return retval;
    }

    private void checkCells()
    {
        if (cells == null)
        {
            cells = new ValueRecordsAggregate();
            records.add(getDimsLoc() + 1, cells);
        }
    }

    private void checkRows()
    {
        if (rows == null)
        {
            rows = new RowRecordsAggregate();
            records.add(getDimsLoc() + 1, rows);
        }
    }

    //public int addMergedRegion(short rowFrom, short colFrom, short rowTo,
    public int addMergedRegion(int rowFrom, short colFrom, int rowTo,
                               short colTo)
    {
        if (merged == null || merged.getNumAreas() == 1027)
        {
            merged = ( MergeCellsRecord ) createMergedCells();
            mergedRecords.add(merged);            
            records.add(records.size() - 1, merged);
        }
        merged.addArea(rowFrom, colFrom, rowTo, colTo);
        return numMergedRegions++; 
    }

    public void removeMergedRegion(int index)
    {
        //safety checks
        if (index >= numMergedRegions || mergedRecords.size() == 0)
           return;
            
        int pos = 0;
        int startNumRegions = 0;
        
        //optimisation for current record
        if (numMergedRegions - index < merged.getNumAreas())
        {
            pos = mergedRecords.size() - 1;
            startNumRegions = numMergedRegions - merged.getNumAreas(); 
        }
        else
        {
            for (int n = 0; n < mergedRecords.size(); n++)
            {
                MergeCellsRecord record = (MergeCellsRecord) mergedRecords.get(n);
                if (startNumRegions + record.getNumAreas() > index)
                {
                    pos = n;
                    break;
                }
                startNumRegions += record.getNumAreas(); 
            }
        }

        MergeCellsRecord rec = (MergeCellsRecord) mergedRecords.get(pos);
        rec.removeAreaAt(index - startNumRegions);
        numMergedRegions--;
        if (rec.getNumAreas() == 0)
        {
			mergedRecords.remove(pos);
			//get rid of the record from the sheet
			records.remove(merged);            
            if (merged == rec) {
            	//pull up the LAST record for operations when we finally
            	//support continue records for mergedRegions
            	if (mergedRecords.size() > 0) {
            		merged = (MergeCellsRecord) mergedRecords.get(mergedRecords.size() - 1);
            	} else {
            		merged = null;
            	}
            }
        }
    }

    public MergeCellsRecord.MergedRegion getMergedRegionAt(int index)
    {
        //safety checks
        if (index >= numMergedRegions || mergedRecords.size() == 0)
            return null;
            
        int pos = 0;
        int startNumRegions = 0;
        
        //optimisation for current record
        if (numMergedRegions - index < merged.getNumAreas())
        {
            pos = mergedRecords.size() - 1;
            startNumRegions = numMergedRegions - merged.getNumAreas();
        }
        else
        {
            for (int n = 0; n < mergedRecords.size(); n++)
            {
                MergeCellsRecord record = (MergeCellsRecord) mergedRecords.get(n);
                if (startNumRegions + record.getNumAreas() > index)
                {
                    pos = n;
                    break;
                }
                startNumRegions += record.getNumAreas(); 
            }
        }
        return ((MergeCellsRecord) mergedRecords.get(pos)).getAreaAt(index - startNumRegions);
    }

    public int getNumMergedRegions()
    {
        return numMergedRegions;
    }

    /**
     * This is basically a kludge to deal with the now obsolete Label records.  If
     * you have to read in a sheet that contains Label records, be aware that the rest
     * of the API doesn't deal with them, the low level structure only provides read-only
     * semi-immutable structures (the sets are there for interface conformance with NO
     * impelmentation).  In short, you need to call this function passing it a reference
     * to the Workbook object.  All labels will be converted to LabelSST records and their
     * contained strings will be written to the Shared String tabel (SSTRecord) within
     * the Workbook.
     *
     * @param wb sheet's matching low level Workbook structure containing the SSTRecord.
     * @see org.apache.poi.hssf.record.LabelRecord
     * @see org.apache.poi.hssf.record.LabelSSTRecord
     * @see org.apache.poi.hssf.record.SSTRecord
     */

    public void convertLabelRecords(Workbook wb)
    {
        log.log(log.DEBUG, "convertLabelRecords called");
        if (containsLabels)
        {
            for (int k = 0; k < records.size(); k++)
            {
                Record rec = ( Record ) records.get(k);

                if (rec.getSid() == LabelRecord.sid)
                {
                    LabelRecord oldrec = ( LabelRecord ) rec;

                    records.remove(k);
                    LabelSSTRecord newrec   = new LabelSSTRecord();
                    int            stringid =
                        wb.addSSTString(oldrec.getValue());

                    newrec.setRow(oldrec.getRow());
                    newrec.setColumn(oldrec.getColumn());
                    newrec.setXFIndex(oldrec.getXFIndex());
                    newrec.setSSTIndex(stringid);
                          records.add(k, newrec);
                }
            }
        }
        log.log(log.DEBUG, "convertLabelRecords exit");
    }

    /**
     * Returns the number of low level binary records in this sheet.  This adjusts things for the so called
     * AgregateRecords.
     *
     * @see org.apache.poi.hssf.record.Record
     */

    public int getNumRecords()
    {
        checkCells();
        checkRows();
        log.log(log.DEBUG, "Sheet.getNumRecords");
        log.logFormatted(log.DEBUG, "returning % + % + % - 2 = %", new int[]
        {
            records.size(), cells.getPhysicalNumberOfCells(),
            rows.getPhysicalNumberOfRows(),
            records.size() + cells.getPhysicalNumberOfCells()
            + rows.getPhysicalNumberOfRows() - 2
        });
        return records.size() + cells.getPhysicalNumberOfCells()
               + rows.getPhysicalNumberOfRows() - 2;
    }

    /**
     * Per an earlier reported bug in working with Andy Khan's excel read library.  This
     * sets the values in the sheet's DimensionsRecord object to be correct.  Excel doesn't
     * really care, but we want to play nice with other libraries.
     *
     * @see org.apache.poi.hssf.record.DimensionsRecord
     */

    //public void setDimensions(short firstrow, short firstcol, short lastrow,
    public void setDimensions(int firstrow, short firstcol, int lastrow,
                              short lastcol)
    {
        log.log(log.DEBUG, "Sheet.setDimensions");
        log.log(log.DEBUG,
                (new StringBuffer("firstrow")).append(firstrow)
                    .append("firstcol").append(firstcol).append("lastrow")
                    .append(lastrow).append("lastcol").append(lastcol)
                    .toString());
        dims.setFirstCol(firstcol);
        dims.setFirstRow(firstrow);
        dims.setLastCol(lastcol);
        dims.setLastRow(lastrow);
        log.log(log.DEBUG, "Sheet.setDimensions exiting");
    }

    /**
     * set the locator for where we should look for the next value record.  The
     * algorythm will actually start here and find the correct location so you
     * can set this to 0 and watch performance go down the tubes but it will work.
     * After a value is set this is automatically advanced.  Its also set by the
     * create method.  So you probably shouldn't mess with this unless you have
     * a compelling reason why or the help for the method you're calling says so.
     * Check the other methods for whether they care about
     * the loc pointer.  Many of the "modify" and "remove" methods re-initialize this
     * to "dimsloc" which is the location of the Dimensions Record and presumably the
     * start of the value section (at or around 19 dec).
     *
     * @param loc the record number to start at
     *
     */

    public void setLoc(int loc)
    {
        valueRecIterator = null;
        log.log(log.DEBUG, "sheet.setLoc(): " + loc);
        this.loc = loc;
    }

    /**
     * Returns the location pointer to the first record to look for when adding rows/values
     *
     */

    public int getLoc()
    {
        log.log(log.DEBUG, "sheet.getLoc():" + loc);
        return loc;
    }

    /**
     * Set the preoffset when using DBCELL records (currently unused) - this is
     * the position of this sheet within the whole file.
     *
     * @param offset the offset of the sheet's BOF within the file.
     */

    public void setPreOffset(int offset)
    {
        this.preoffset = offset;
    }

    /**
     * get the preoffset when using DBCELL records (currently unused) - this is
     * the position of this sheet within the whole file.
     *
     * @return offset the offset of the sheet's BOF within the file.
     */

    public int getPreOffset()
    {
        return preoffset;
    }

    /**
     * Serializes all records in the sheet into one big byte array.  Use this to write
     * the sheet out.
     *
     * @return byte[] array containing the binary representation of the records in this sheet
     *
     */

    public byte [] serialize()
    {
        log.log(log.DEBUG, "Sheet.serialize");

        // addDBCellRecords();
        byte[] retval    = null;

        // ArrayList bytes     = new ArrayList(4096);
        int    arraysize = getSize();
        int    pos       = 0;

        // for (int k = 0; k < records.size(); k++)
        // {
        // bytes.add((( Record ) records.get(k)).serialize());
        //
        // }
        // for (int k = 0; k < bytes.size(); k++)
        // {
        // arraysize += (( byte [] ) bytes.get(k)).length;
        // log.debug((new StringBuffer("arraysize=")).append(arraysize)
        // .toString());
        // }
        retval = new byte[ arraysize ];
        for (int k = 0; k < records.size(); k++)
        {

            // byte[] rec = (( byte [] ) bytes.get(k));
            // System.arraycopy(rec, 0, retval, pos, rec.length);
            pos += (( Record ) records.get(k)).serialize(pos,
                    retval);   // rec.length;
        }
        log.log(log.DEBUG, "Sheet.serialize returning " + retval);
        return retval;
    }

    /**
     * Serializes all records in the sheet into one big byte array.  Use this to write
     * the sheet out.
     *
     * @param offset to begin write at
     * @param data   array containing the binary representation of the records in this sheet
     *
     */

    public int serialize(int offset, byte [] data)
    {
        log.log(log.DEBUG, "Sheet.serialize using offsets");

        // addDBCellRecords();
        // ArrayList bytes     = new ArrayList(4096);
        // int arraysize = getSize();   // 0;
        int pos       = 0;

        // for (int k = 0; k < records.size(); k++)
        // {
        // bytes.add((( Record ) records.get(k)).serialize());
        //
        // }
        // for (int k = 0; k < bytes.size(); k++)
        // {
        // arraysize += (( byte [] ) bytes.get(k)).length;
        // log.debug((new StringBuffer("arraysize=")).append(arraysize)
        // .toString());
        // }
        for (int k = 0; k < records.size(); k++)
        {
//             byte[] rec = (( byte [] ) bytes.get(k));
            // System.arraycopy(rec, 0, data, offset + pos, rec.length);
            Record record = (( Record ) records.get(k));

            //uncomment to test record sizes
//            byte[] data2 = new byte[record.getRecordSize()];
//            record.serialize(0, data2 );   // rec.length;
//            if (LittleEndian.getUShort(data2, 2) != record.getRecordSize() - 4
//                    && record instanceof RowRecordsAggregate == false && record instanceof ValueRecordsAggregate == false)
//                throw new RuntimeException("Blah!!!");

            pos += record.serialize(pos + offset, data );   // rec.length;

        }
        log.log(log.DEBUG, "Sheet.serialize returning ");
        return pos;
    }

    /**
     * Create a row record.  (does not add it to the records contained in this sheet)
     *
     * @param row number
     * @return RowRecord created for the passed in row number
     * @see org.apache.poi.hssf.record.RowRecord
     */

    public RowRecord createRow(int row)
    {
        log.log(log.DEBUG, "create row number " + row);
        RowRecord rowrec = new RowRecord();

        //rowrec.setRowNumber(( short ) row);
        rowrec.setRowNumber(row);
        rowrec.setHeight(( short ) 0xff);
        rowrec.setOptimize(( short ) 0x0);
        rowrec.setOptionFlags(( short ) 0x0);
        rowrec.setXFIndex(( short ) 0x0);
        return rowrec;
    }

    /**
     * Create a LABELSST Record (does not add it to the records contained in this sheet)
     *
     * @param row the row the LabelSST is a member of
     * @param col the column the LabelSST defines
     * @param index the index of the string within the SST (use workbook addSSTString method)
     * @return LabelSSTRecord newly created containing your SST Index, row,col.
     * @see org.apache.poi.hssf.record.SSTRecord
     */

    //public LabelSSTRecord createLabelSST(short row, short col, int index)
    public LabelSSTRecord createLabelSST(int row, short col, int index)
    {
        log.logFormatted(log.DEBUG, "create labelsst row,col,index %,%,%",
                         new int[]
        {
            row, col, index
        });
        LabelSSTRecord rec = new LabelSSTRecord();

        rec.setRow(row);
        rec.setColumn(col);
        rec.setSSTIndex(index);
        rec.setXFIndex(( short ) 0x0f);
        return rec;
    }

    /**
     * Create a NUMBER Record (does not add it to the records contained in this sheet)
     *
     * @param row the row the NumberRecord is a member of
     * @param col the column the NumberRecord defines
     * @param value for the number record
     *
     * @return NumberRecord for that row, col containing that value as added to the sheet
     */

    //public NumberRecord createNumber(short row, short col, double value)
    public NumberRecord createNumber(int row, short col, double value)
    {
        log.logFormatted(log.DEBUG, "create number row,col,value %,%,%",
                         new double[]
        {
            row, col, value
        });
        NumberRecord rec = new NumberRecord();

        //rec.setRow(( short ) row);
        rec.setRow(row);
        rec.setColumn(col);
        rec.setValue(value);
        rec.setXFIndex(( short ) 0x0f);
        return rec;
    }

    /**
     * create a BLANK record (does not add it to the records contained in this sheet)
     *
     * @param row - the row the BlankRecord is a member of
     * @param col - the column the BlankRecord is a member of
     */

    //public BlankRecord createBlank(short row, short col)
    public BlankRecord createBlank(int row, short col)
    {
        //log.logFormatted(log.DEBUG, "create blank row,col %,%", new short[]
        log.logFormatted(log.DEBUG, "create blank row,col %,%", new int[]
        {
            row, col
        });
        BlankRecord rec = new BlankRecord();

        //rec.setRow(( short ) row);
        rec.setRow(row);
        rec.setColumn(col);
        rec.setXFIndex(( short ) 0x0f);
        return rec;
    }

    /**
     * Attempts to parse the formula into PTGs and create a formula record
     * DOES NOT WORK YET
     *
     * @param row - the row for the formula record
     * @param col - the column of the formula record
     * @param formula - a String representing the formula.  To be parsed to PTGs
     * @return bogus/useless formula record
     */

    //public FormulaRecord createFormula(short row, short col, String formula)
    public FormulaRecord createFormula(int row, short col, String formula)
    {
        log.logFormatted(log.DEBUG, "create formula row,col,formula %,%,%",
                         //new short[]
                         new int[]
        {
            row, col
        }, formula);
        FormulaRecord rec = new FormulaRecord();

        rec.setRow(row);
        rec.setColumn(col);
        rec.setOptions(( short ) 2);
        rec.setValue(0);
        rec.setXFIndex(( short ) 0x0f);
        FormulaParser fp = new FormulaParser(formula,null); //fix - do we need this method?
        fp.parse();
        Ptg[] ptg  = fp.getRPNPtg();
        int   size = 0;

        for (int k = 0; k < ptg.length; k++)
        {
            size += ptg[ k ].getSize();
            rec.pushExpressionToken(ptg[ k ]);
        }
        rec.setExpressionLength(( short ) size);
        return rec;
    }

    /**
     * Adds a value record to the sheet's contained binary records
     * (i.e. LabelSSTRecord or NumberRecord).
     * <P>
     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
     * When adding several rows you can just start at the last one by leaving loc
     * at what this sets it to.
     *
     * @param row the row to add the cell value to
     * @param col the cell value record itself.
     */

    //public void addValueRecord(short row, CellValueRecordInterface col)
    public void addValueRecord(int row, CellValueRecordInterface col)
    {
        checkCells();
        log.logFormatted(log.DEBUG, "add value record  row,loc %,%", new int[]
        {
            row, loc
        });
        DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc());

        if (col.getColumn() > d.getLastCol())
        {
            d.setLastCol(( short ) (col.getColumn() + 1));
        }
        if (col.getColumn() < d.getFirstCol())
        {
            d.setFirstCol(col.getColumn());
        }
        cells.insertCell(col);

        /*
         * for (int k = loc; k < records.size(); k++)
         * {
         *   Record rec = ( Record ) records.get(k);
         *
         *   if (rec.getSid() == RowRecord.sid)
         *   {
         *       RowRecord rowrec = ( RowRecord ) rec;
         *
         *       if (rowrec.getRowNumber() == col.getRow())
         *       {
         *           records.add(k + 1, col);
         *           loc = k;
         *           if (rowrec.getLastCol() <= col.getColumn())
         *           {
         *               rowrec.setLastCol((( short ) (col.getColumn() + 1)));
         *           }
         *           break;
         *       }
         *   }
         * }
         */
    }

    /**
     * remove a value record from the records array.
     *
     * This method is not loc sensitive, it resets loc to = dimsloc so no worries.
     *
     * @param row - the row of the value record you wish to remove
     * @param col - a record supporting the CellValueRecordInterface.
     * @see org.apache.poi.hssf.record.CellValueRecordInterface
     */

    //public void removeValueRecord(short row, CellValueRecordInterface col)
    public void removeValueRecord(int row, CellValueRecordInterface col)
    {
        checkCells();
        log.logFormatted(log.DEBUG, "remove value record row,dimsloc %,%",
                         new int[]{row, dimsloc} );
        loc = dimsloc;
        cells.removeCell(col);

        /*
         * for (int k = loc; k < records.size(); k++)
         * {
         *   Record rec = ( Record ) records.get(k);
         *
         *   // checkDimsLoc(rec,k);
         *   if (rec.isValue())
         *   {
         *       CellValueRecordInterface cell =
         *           ( CellValueRecordInterface ) rec;
         *
         *       if ((cell.getRow() == col.getRow())
         *               && (cell.getColumn() == col.getColumn()))
         *       {
         *           records.remove(k);
         *           break;
         *       }
         *   }
         * }
         */
    }

    /**
     * replace a value record from the records array.
     *
     * This method is not loc sensitive, it resets loc to = dimsloc so no worries.
     *
     * @param newval - a record supporting the CellValueRecordInterface.  this will replace
     *                the cell value with the same row and column.  If there isn't one, one will
     *                be added.
     */

    public void replaceValueRecord(CellValueRecordInterface newval)
    {
        checkCells();
        setLoc(dimsloc);
        log.log(log.DEBUG, "replaceValueRecord ");
        cells.insertCell(newval);

        /*
         * CellValueRecordInterface oldval = getNextValueRecord();
         *
         * while (oldval != null)
         * {
         *   if (oldval.isEqual(newval))
         *   {
         *       records.set(( short ) (getLoc() - 1), newval);
         *       return;
         *   }
         *   oldval = getNextValueRecord();
         * }
         * addValueRecord(newval.getRow(), newval);
         * setLoc(dimsloc);
         */
    }

    /**
     * Adds a row record to the sheet
     *
     * <P>
     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
     * When adding several rows you can just start at the last one by leaving loc
     * at what this sets it to.
     *
     * @param row the row record to be added
     * @see #setLoc(int)
     */

    public void addRow(RowRecord row)
    {
        checkRows();
        log.log(log.DEBUG, "addRow ");
        DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc());

        if (row.getRowNumber() > d.getLastRow())
        {
            d.setLastRow(row.getRowNumber() + 1);
        }
        if (row.getRowNumber() < d.getFirstRow())
        {
            d.setFirstRow(row.getRowNumber());
        }
        //IndexRecord index = null;
         //If the row exists remove it, so that any cells attached to the row are removed
         RowRecord existingRow = rows.getRow(row.getRowNumber());
         if (existingRow != null)
           rows.removeRow(existingRow);

        rows.insertRow(row);

        /*
         * for (int k = loc; k < records.size(); k++)
         * {
         *   Record rec = ( Record ) records.get(k);
         *
         *   if (rec.getSid() == IndexRecord.sid)
         *   {
         *       index = ( IndexRecord ) rec;
         *   }
         *   if (rec.getSid() == RowRecord.sid)
         *   {
         *       RowRecord rowrec = ( RowRecord ) rec;
         *
         *       if (rowrec.getRowNumber() > row.getRowNumber())
         *       {
         *           records.add(k, row);
         *           loc = k;
         *           break;
         *       }
         *   }
         *   if (rec.getSid() == WindowTwoRecord.sid)
         *   {
         *       records.add(k, row);
         *       loc = k;
         *       break;
         *   }
         * }
         * if (index != null)
         * {
         *   if (index.getLastRowAdd1() <= row.getRowNumber())
         *   {
         *       index.setLastRowAdd1(row.getRowNumber() + 1);
         *   }
         * }
         */
        log.log(log.DEBUG, "exit addRow");
    }

    /**
     * Removes a row record
     *
     * This method is not loc sensitive, it resets loc to = dimsloc so no worries.
     *
     * @param row  the row record to remove
     */

    public void removeRow(RowRecord row)
    {
        checkRows();
        // IndexRecord index = null;

        setLoc(getDimsLoc());
        rows.removeRow(row);

        /*
         * for (int k = loc; k < records.size(); k++)
         * {
         *   Record rec = ( Record ) records.get(k);
         *
         *   // checkDimsLoc(rec,k);
         *   if (rec.getSid() == RowRecord.sid)
         *   {
         *       RowRecord rowrec = ( RowRecord ) rec;
         *
         *       if (rowrec.getRowNumber() == row.getRowNumber())
         *       {
         *           records.remove(k);
         *           break;
         *       }
         *   }
         *   if (rec.getSid() == WindowTwoRecord.sid)
         *   {
         *       break;
         *   }
         * }
         */
    }

    /**
     * get the NEXT value record (from LOC).  The first record that is a value record
     * (starting at LOC) will be returned.
     *
     * <P>
     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
     * When adding several rows you can just start at the last one by leaving loc
     * at what this sets it to.  For this method, set loc to dimsloc to start with,
     * subsequent calls will return values in (physical) sequence or NULL when you get to the end.
     *
     * @return CellValueRecordInterface representing the next value record or NULL if there are no more
     * @see #setLoc(int)
     */

    public CellValueRecordInterface getNextValueRecord()
    {
        log.log(log.DEBUG, "getNextValue loc= " + loc);
        if (valueRecIterator == null)
        {
            valueRecIterator = cells.getIterator();
        }
        if (!valueRecIterator.hasNext())
        {
            return null;
        }
        return ( CellValueRecordInterface ) valueRecIterator.next();

        /*
         *      if (this.getLoc() < records.size())
         *     {
         *         for (int k = getLoc(); k < records.size(); k++)
         *         {
         *             Record rec = ( Record ) records.get(k);
         *
         *             this.setLoc(k + 1);
         *             if (rec instanceof CellValueRecordInterface)
         *             {
         *                 return ( CellValueRecordInterface ) rec;
         *             }
         *         }
         *     }
         *     return null;
         */
    }

    /**
     * get the NEXT RowRecord or CellValueRecord(from LOC).  The first record that
     * is a Row record or CellValueRecord(starting at LOC) will be returned.
     * <P>
     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
     * When adding several rows you can just start at the last one by leaving loc
     * at what this sets it to.  For this method, set loc to dimsloc to start with.
     * subsequent calls will return rows in (physical) sequence or NULL when you get to the end.
     *
     * @return RowRecord representing the next row record or CellValueRecordInterface
     *  representing the next cellvalue or NULL if there are no more
     * @see #setLoc(int)
     *
     */

/*    public Record getNextRowOrValue()
    {
        log.debug((new StringBuffer("getNextRow loc= ")).append(loc)
            .toString());
        if (this.getLoc() < records.size())
        {
            for (int k = this.getLoc(); k < records.size(); k++)
            {
                Record rec = ( Record ) records.get(k);

                this.setLoc(k + 1);
                if (rec.getSid() == RowRecord.sid)
                {
                    return rec;
                }
                else if (rec.isValue())
                {
                    return rec;
                }
            }
        }
        return null;
    }
 */

    /**
     * get the NEXT RowRecord (from LOC).  The first record that is a Row record
     * (starting at LOC) will be returned.
     * <P>
     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
     * When adding several rows you can just start at the last one by leaving loc
     * at what this sets it to.  For this method, set loc to dimsloc to start with.
     * subsequent calls will return rows in (physical) sequence or NULL when you get to the end.
     *
     * @return RowRecord representing the next row record or NULL if there are no more
     * @see #setLoc(int)
     *
     */

    public RowRecord getNextRow()
    {
        log.log(log.DEBUG, "getNextRow loc= " + loc);
        if (rowRecIterator == null)
        {
            rowRecIterator = rows.getIterator();
        }
        if (!rowRecIterator.hasNext())
        {
            return null;
        }
        return ( RowRecord ) rowRecIterator.next();

/*        if (this.getLoc() < records.size())
        {
            for (int k = this.getLoc(); k < records.size(); k++)
            {
                Record rec = ( Record ) records.get(k);

                this.setLoc(k + 1);
                if (rec.getSid() == RowRecord.sid)
                {
                    return ( RowRecord ) rec;
                }
            }
        }*/
    }

    /**
     * get the NEXT (from LOC) RowRecord where rownumber matches the given rownum.
     * The first record that is a Row record (starting at LOC) that has the
     * same rownum as the given rownum will be returned.
     * <P>
     * This method is "loc" sensitive.  Meaning you need to set LOC to where you
     * want it to start searching.  If you don't know do this: setLoc(getDimsLoc).
     * When adding several rows you can just start at the last one by leaving loc
     * at what this sets it to.  For this method, set loc to dimsloc to start with.
     * subsequent calls will return rows in (physical) sequence or NULL when you get to the end.
     *
     * @param rownum   which row to return (careful with LOC)
     * @return RowRecord representing the next row record or NULL if there are no more
     * @see #setLoc(int)
     *
     */

    //public RowRecord getRow(short rownum)
    public RowRecord getRow(int rownum)
    {
        log.log(log.DEBUG, "getNextRow loc= " + loc);
        return rows.getRow(rownum);

        /*
         * if (this.getLoc() < records.size())
         * {
         *   for (int k = this.getLoc(); k < records.size(); k++)
         *   {
         *       Record rec = ( Record ) records.get(k);
         *
         *       this.setLoc(k + 1);
         *       if (rec.getSid() == RowRecord.sid)
         *       {
         *           if ((( RowRecord ) rec).getRowNumber() == rownum)
         *           {
         *               return ( RowRecord ) rec;
         *           }
         *       }
         *   }
         * }
         */

        // return null;
    }

    /**
     * Not currently used method to calculate and add dbcell records
     *
     */

    public void addDBCellRecords()
    {
        int         offset        = 0;
        int         recnum        = 0;
        int         rownum        = 0;
        //int         lastrow       = 0;
        //long        lastrowoffset = 0;
        IndexRecord index         = null;

        // ArrayList rowOffsets = new ArrayList();
        IntList     rowOffsets    = new IntList();

        for (recnum = 0; recnum < records.size(); recnum++)
        {
            Record rec = ( Record ) records.get(recnum);

            if (rec.getSid() == IndexRecord.sid)
            {
                index = ( IndexRecord ) rec;
            }
            if (rec.getSid() != RowRecord.sid)
            {
                offset += rec.serialize().length;
            }
            else
            {
                break;
            }
        }

        // First Row Record
        for (; recnum < records.size(); recnum++)
        {
            Record rec = ( Record ) records.get(recnum);

            if (rec.getSid() == RowRecord.sid)
            {
                rownum++;
                rowOffsets.add(offset);
                if ((rownum % 32) == 0)
                {

                    // if this is the last rec in a  dbcell block
                    // find the next row or last value record
                    for (int rn = recnum; rn < records.size(); rn++)
                    {
                        rec = ( Record ) records.get(rn);
                        if ((!rec.isInValueSection())
                                || (rec.getSid() == RowRecord.sid))
                        {

                            // here is the next row or last value record
                            records.add(rn,
                                        createDBCell(offset, rowOffsets,
                                                     index));
                            recnum = rn;
                            break;
                        }
                    }
                }
                else
                {
                }
            }
            if (!rec.isInValueSection())
            {
                records.add(recnum, createDBCell(offset, rowOffsets, index));
                break;
            }
            offset += rec.serialize().length;
        }
    }

    /** not currently used */

    private DBCellRecord createDBCell(int offset, IntList rowoffsets,
                                      IndexRecord index)
    {
        DBCellRecord rec = new DBCellRecord();

        rec.setRowOffset(offset - rowoffsets.get(0));

        // test hack
        rec.addCellOffset(( short ) 0x0);

        // end test hack
        addDbCellToIndex(offset, index);
        return rec;
    }

    /** not currently used */

    private void addDbCellToIndex(int offset, IndexRecord index)
    {
        int numdbcells = index.getNumDbcells() + 1;

        index.addDbcell(offset + preoffset);

        // stupid but whenever we add an offset that causes everything to be shifted down 4
        for (int k = 0; k < numdbcells; k++)
        {
            int dbval = index.getDbcellAt(k);

            index.setDbcell(k, dbval + 4);
        }
    }

    /**
     * creates the BOF record
     * @see org.apache.poi.hssf.record.BOFRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a BOFRecord
     */

    protected Record createBOF()
    {
        BOFRecord retval = new BOFRecord();

        retval.setVersion(( short ) 0x600);
        retval.setType(( short ) 0x010);

        // retval.setBuild((short)0x10d3);
        retval.setBuild(( short ) 0x0dbb);
        retval.setBuildYear(( short ) 1996);
        retval.setHistoryBitMask(0xc1);
        retval.setRequiredVersion(0x6);
        return retval;
    }

    /**
     * creates the Index record  - not currently used
     * @see org.apache.poi.hssf.record.IndexRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a IndexRecord
     */

    protected Record createIndex()
    {
        IndexRecord retval = new IndexRecord();

        retval.setFirstRow(0);   // must be set explicitly
        retval.setLastRowAdd1(0);
        return retval;
    }

    /**
     * creates the CalcMode record and sets it to 1 (automatic formula caculation)
     * @see org.apache.poi.hssf.record.CalcModeRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a CalcModeRecord
     */

    protected Record createCalcMode()
    {
        CalcModeRecord retval = new CalcModeRecord();

        retval.setCalcMode(( short ) 1);
        return retval;
    }

    /**
     * creates the CalcCount record and sets it to 0x64 (default number of iterations)
     * @see org.apache.poi.hssf.record.CalcCountRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a CalcCountRecord
     */

    protected Record createCalcCount()
    {
        CalcCountRecord retval = new CalcCountRecord();

        retval.setIterations(( short ) 0x64);   // default 64 iterations
        return retval;
    }

    /**
     * creates the RefMode record and sets it to A1 Mode (default reference mode)
     * @see org.apache.poi.hssf.record.RefModeRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a RefModeRecord
     */

    protected Record createRefMode()
    {
        RefModeRecord retval = new RefModeRecord();

        retval.setMode(retval.USE_A1_MODE);
        return retval;
    }

    /**
     * creates the Iteration record and sets it to false (don't iteratively calculate formulas)
     * @see org.apache.poi.hssf.record.IterationRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a IterationRecord
     */

    protected Record createIteration()
    {
        IterationRecord retval = new IterationRecord();

        retval.setIteration(false);
        return retval;
    }

    /**
     * creates the Delta record and sets it to 0.0010 (default accuracy)
     * @see org.apache.poi.hssf.record.DeltaRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a DeltaRecord
     */

    protected Record createDelta()
    {
        DeltaRecord retval = new DeltaRecord();

        retval.setMaxChange(0.0010);
        return retval;
    }

    /**
     * creates the SaveRecalc record and sets it to true (recalculate before saving)
     * @see org.apache.poi.hssf.record.SaveRecalcRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a SaveRecalcRecord
     */

    protected Record createSaveRecalc()
    {
        SaveRecalcRecord retval = new SaveRecalcRecord();

        retval.setRecalc(true);
        return retval;
    }

    /**
     * creates the PrintHeaders record and sets it to false (we don't create headers yet so why print them)
     * @see org.apache.poi.hssf.record.PrintHeadersRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a PrintHeadersRecord
     */

    protected Record createPrintHeaders()
    {
        PrintHeadersRecord retval = new PrintHeadersRecord();

        retval.setPrintHeaders(false);
        return retval;
    }

    /**
     * creates the PrintGridlines record and sets it to false (that makes for ugly sheets).  As far as I can
     * tell this does the same thing as the GridsetRecord
     *
     * @see org.apache.poi.hssf.record.PrintGridlinesRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a PrintGridlinesRecord
     */

    protected Record createPrintGridlines()
    {
        PrintGridlinesRecord retval = new PrintGridlinesRecord();

        retval.setPrintGridlines(false);
        return retval;
    }

    /**
     * creates the Gridset record and sets it to true (user has mucked with the gridlines)
     * @see org.apache.poi.hssf.record.GridsetRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a GridsetRecord
     */

    protected Record createGridset()
    {
        GridsetRecord retval = new GridsetRecord();

        retval.setGridset(true);
        return retval;
    }

    /**
     * creates the Guts record and sets leftrow/topcol guttter and rowlevelmax/collevelmax to 0
     * @see org.apache.poi.hssf.record.GutsRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a GutsRecordRecord
     */

    protected Record createGuts()
    {
        GutsRecord retval = new GutsRecord();

        retval.setLeftRowGutter(( short ) 0);
        retval.setTopColGutter(( short ) 0);
        retval.setRowLevelMax(( short ) 0);
        retval.setColLevelMax(( short ) 0);
        return retval;
    }

    /**
     * creates the DefaultRowHeight Record and sets its options to 0 and rowheight to 0xff
     * @see org.apache.poi.hssf.record.DefaultRowHeightRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a DefaultRowHeightRecord
     */

    protected Record createDefaultRowHeight()
    {
        DefaultRowHeightRecord retval = new DefaultRowHeightRecord();

        retval.setOptionFlags(( short ) 0);
        retval.setRowHeight(( short ) 0xff);
        return retval;
    }

    /**
     * creates the WSBoolRecord and sets its values to defaults
     * @see org.apache.poi.hssf.record.WSBoolRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a WSBoolRecord
     */

    protected Record createWSBool()
    {
        WSBoolRecord retval = new WSBoolRecord();

        retval.setWSBool1(( byte ) 0x4);
        retval.setWSBool2(( byte ) 0xffffffc1);
        return retval;
    }

    /**
     * creates the Header Record and sets it to nothing/0 length
     * @see org.apache.poi.hssf.record.HeaderRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a HeaderRecord
     */

    protected Record createHeader()
    {
        HeaderRecord retval = new HeaderRecord();

        retval.setHeaderLength(( byte ) 0);
        retval.setHeader(null);
        return retval;
    }

    /**
     * creates the Footer Record and sets it to nothing/0 length
     * @see org.apache.poi.hssf.record.FooterRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a FooterRecord
     */

    protected Record createFooter()
    {
        FooterRecord retval = new FooterRecord();

        retval.setFooterLength(( byte ) 0);
        retval.setFooter(null);
        return retval;
    }

    /**
     * creates the HCenter Record and sets it to false (don't horizontally center)
     * @see org.apache.poi.hssf.record.HCenterRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a HCenterRecord
     */

    protected Record createHCenter()
    {
        HCenterRecord retval = new HCenterRecord();

        retval.setHCenter(false);
        return retval;
    }

    /**
     * creates the VCenter Record and sets it to false (don't horizontally center)
     * @see org.apache.poi.hssf.record.VCenterRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a VCenterRecord
     */

    protected Record createVCenter()
    {
        VCenterRecord retval = new VCenterRecord();

        retval.setVCenter(false);
        return retval;
    }

    /**
     * creates the PrintSetup Record and sets it to defaults and marks it invalid
     * @see org.apache.poi.hssf.record.PrintSetupRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a PrintSetupRecord
     */

    protected Record createPrintSetup()
    {
        PrintSetupRecord retval = new PrintSetupRecord();

        retval.setPaperSize(( short ) 1);
        retval.setScale(( short ) 100);
        retval.setPageStart(( short ) 1);
        retval.setFitWidth(( short ) 1);
        retval.setFitHeight(( short ) 1);
        retval.setOptions(( short ) 2);
        retval.setHResolution(( short ) 300);
        retval.setVResolution(( short ) 300);
        retval.setHeaderMargin( 0.5);
        retval.setFooterMargin( 0.5);
        retval.setCopies(( short ) 0);
        return retval;
    }

    /**
     * creates the DefaultColWidth Record and sets it to 8
     * @see org.apache.poi.hssf.record.DefaultColWidthRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a DefaultColWidthRecord
     */

    protected Record createDefaultColWidth()
    {
        DefaultColWidthRecord retval = new DefaultColWidthRecord();

        retval.setColWidth(( short ) 8);
        return retval;
    }

    /**
     * creates the ColumnInfo Record and sets it to a default column/width
     * @see org.apache.poi.hssf.record.ColumnInfoRecord
     * @return record containing a ColumnInfoRecord
     */

    protected Record createColInfo()
    {
        ColumnInfoRecord retval = new ColumnInfoRecord();

        retval.setColumnWidth(( short ) 0x8);
        retval.setOptions(( short ) 6);
        retval.setXFIndex(( short ) 0x0f);
        return retval;
    }

    /**
     * get the default column width for the sheet (if the columns do not define their own width)
     * @return default column width
     */

    public short getDefaultColumnWidth()
    {
        return defaultcolwidth.getColWidth();
    }

    /**
     * get whether gridlines are printed.
     * @return true if printed
     */

    public boolean isGridsPrinted()
    {
        return !gridset.getGridset();
    }

    /**
     * set whether gridlines printed or not.
     * @param value     True if gridlines printed.
     */

    public void setGridsPrinted(boolean value)
    {
        gridset.setGridset(!value);
    }

    /**
     * set the default column width for the sheet (if the columns do not define their own width)
     * @param dcw  default column width
     */

    public void setDefaultColumnWidth(short dcw)
    {
        defaultcolwidth.setColWidth(dcw);
    }

    /**
     * set the default row height for the sheet (if the rows do not define their own height)
     */

    public void setDefaultRowHeight(short dch)
    {
        defaultrowheight.setRowHeight(dch);
    }

    /**
     * get the default row height for the sheet (if the rows do not define their own height)
     * @return  default row height
     */

    public short getDefaultRowHeight()
    {
        return defaultrowheight.getRowHeight();
    }

    /**
     * get the width of a given column in units of 1/20th of a point width (twips?)
     * @param column index
     * @see org.apache.poi.hssf.record.DefaultColWidthRecord
     * @see org.apache.poi.hssf.record.ColumnInfoRecord
     * @see #setColumnWidth(short,short)
     * @return column width in units of 1/20th of a point (twips?)
     */

    public short getColumnWidth(short column)
    {
        short            retval = 0;
        ColumnInfoRecord ci     = null;
        int              k      = 0;

        if (columnSizes != null)
        {
            for (k = 0; k < columnSizes.size(); k++)
            {
                ci = ( ColumnInfoRecord ) columnSizes.get(k);
                if ((ci.getFirstColumn() <= column)
                        && (column <= ci.getLastColumn()))
                {
                    break;
                }
                ci = null;
            }
        }
        if (ci != null)
        {
            retval = ci.getColumnWidth();
        }
        else
        {
            retval = defaultcolwidth.getColWidth();
        }
        return retval;
    }

    /**
     * set the width for a given column in 1/20th of a character width units
     * @param column - the column number
     * @param width (in units of 1/20th of a character width)
     */

    public void setColumnWidth(short column, short width)
    {
        ColumnInfoRecord ci = null;
        int              k  = 0;

        if (columnSizes == null)
        {
            columnSizes = new ArrayList();
        }
        //int cioffset = getDimsLoc() - columnSizes.size();

        for (k = 0; k < columnSizes.size(); k++)
        {
            ci = ( ColumnInfoRecord ) columnSizes.get(k);
            if ((ci.getFirstColumn() <= column)
                    && (column <= ci.getLastColumn()))
            {
                break;
            }
            ci = null;
        }
        if (ci != null)
        {
            if (ci.getColumnWidth() == width)
            {

                // do nothing...the cell's width is equal to what we're setting it to.
            }
            else if ((ci.getFirstColumn() == column)
                     && (ci.getLastColumn() == column))
            {                               // if its only for this cell then
                ci.setColumnWidth(width);   // who cares, just change the width
            }
            else if ((ci.getFirstColumn() == column)
                     || (ci.getLastColumn() == column))
            {

                // okay so the width is different but the first or last column == the column we'return setting
                // we'll just divide the info and create a new one
                if (ci.getFirstColumn() == column)
                {
                    ci.setFirstColumn(( short ) (column + 1));
                }
                else
                {
                    ci.setLastColumn(( short ) (column - 1));
                }
                ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();

                nci.setFirstColumn(column);
                nci.setLastColumn(column);
                nci.setOptions(ci.getOptions());
                nci.setXFIndex(ci.getXFIndex());
                nci.setColumnWidth(width);
                columnSizes.add(k, nci);
                records.add((1 + getDimsLoc() - columnSizes.size()) + k, nci);
                dimsloc++;
            }
            else{
                //split to 3 records
                short lastcolumn = ci.getLastColumn();
                ci.setLastColumn(( short ) (column - 1));

                ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();
                nci.setFirstColumn(column);
                nci.setLastColumn(column);
                nci.setOptions(ci.getOptions());
                nci.setXFIndex(ci.getXFIndex());
                nci.setColumnWidth(width);
                columnSizes.add(k, nci);
                records.add((1 + getDimsLoc() - columnSizes.size()) + k, nci);
                dimsloc++;

                nci = ( ColumnInfoRecord ) createColInfo();
                nci.setFirstColumn((short)(column+1));
                nci.setLastColumn(lastcolumn);
                nci.setOptions(ci.getOptions());
                nci.setXFIndex(ci.getXFIndex());
                nci.setColumnWidth(ci.getColumnWidth());
                columnSizes.add(k, nci);
                records.add((1 + getDimsLoc() - columnSizes.size()) + k, nci);
                dimsloc++;
            }
        }
        else
        {

            // okay so there ISN'T a column info record that cover's this column so lets create one!
            ColumnInfoRecord nci = ( ColumnInfoRecord ) createColInfo();

            nci.setFirstColumn(column);
            nci.setLastColumn(column);
            nci.setColumnWidth(width);
            columnSizes.add(k, nci);
            records.add((1 + getDimsLoc() - columnSizes.size()) + k, nci);
            dimsloc++;
        }
    }

    /**
     * creates the Dimensions Record and sets it to bogus values (you should set this yourself
     * or let the high level API do it for you)
     * @see org.apache.poi.hssf.record.DimensionsRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a DimensionsRecord
     */

    protected Record createDimensions()
    {
        DimensionsRecord retval = new DimensionsRecord();

        retval.setFirstCol(( short ) 0);
        retval.setLastRow(1);             // one more than it is
        retval.setFirstRow(0);
        retval.setLastCol(( short ) 1);   // one more than it is
        return retval;
    }

    /**
     * creates the WindowTwo Record and sets it to:  <P>
     * options        = 0x6b6 <P>
     * toprow         = 0 <P>
     * leftcol        = 0 <P>
     * headercolor    = 0x40 <P>
     * pagebreakzoom  = 0x0 <P>
     * normalzoom     = 0x0 <p>
     * @see org.apache.poi.hssf.record.WindowTwoRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a WindowTwoRecord
     */

    protected WindowTwoRecord createWindowTwo()
    {
        WindowTwoRecord retval = new WindowTwoRecord();

        retval.setOptions(( short ) 0x6b6);
        retval.setTopRow(( short ) 0);
        retval.setLeftCol(( short ) 0);
        retval.setHeaderColor(0x40);
        retval.setPageBreakZoom(( short ) 0);
        retval.setNormalZoom(( short ) 0);
        return retval;
    }

    /**
     * Creates the Selection record and sets it to nothing selected
     *
     * @see org.apache.poi.hssf.record.SelectionRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a SelectionRecord
     */

    protected Record createSelection()
    {
        SelectionRecord retval = new SelectionRecord();

        retval.setPane(( byte ) 0x3);
        retval.setActiveCellCol(( short ) 0x0);
        retval.setActiveCellRow(( short ) 0x0);
        retval.setNumRefs(( short ) 0x0);
        return retval;
    }
    
    /**
     * Returns the active row
     *
     * @see org.apache.poi.hssf.record.SelectionRecord
     * @return row the active row index
     */
    public int getActiveCellRow()
    {
        if (selection == null)
        {
            return 0;
        }
        return selection.getActiveCellRow();
    }
    
    /**
     * Sets the active row
     *
     * @param row the row index
     * @see org.apache.poi.hssf.record.SelectionRecord
     */
    public void setActiveCellRow(int row)
    {
        //shouldn't have a sheet w/o a SelectionRecord, but best to guard anyway
        if (selection != null)
        {
            selection.setActiveCellRow(row);
        }
    }
    
    /**
     * Returns the active column
     *
     * @see org.apache.poi.hssf.record.SelectionRecord
     * @return row the active column index
     */
    public short getActiveCellCol()
    {
        if (selection == null)
        {
            return (short) 0;
        }
        return selection.getActiveCellCol();
    }
    
    /**
     * Sets the active column
     *
     * @param col the column index
     * @see org.apache.poi.hssf.record.SelectionRecord
     */
    public void setActiveCellCol(short col)
    {
        //shouldn't have a sheet w/o a SelectionRecord, but best to guard anyway
        if (selection != null)
        {
            selection.setActiveCellCol(col);
        }
    }

    protected Record createMergedCells()
    {
        MergeCellsRecord retval = new MergeCellsRecord();

        retval.setNumAreas(( short ) 0);
        return retval;
    }

    /**
     * creates the EOF record
     * @see org.apache.poi.hssf.record.EOFRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a EOFRecord
     */

    protected Record createEOF()
    {
        return new EOFRecord();
    }

    /**
     * get the location of the DimensionsRecord (which is the last record before the value section)
     * @return location in the array of records of the DimensionsRecord
     */

    public int getDimsLoc()
    {
        log.log(log.DEBUG, "getDimsLoc dimsloc= " + dimsloc);
        return dimsloc;
    }

    /**
     * in the event the record is a dimensions record, resets both the loc index and dimsloc index
     */

    public void checkDimsLoc(Record rec, int recloc)
    {
        if (rec.getSid() == DimensionsRecord.sid)
        {
            loc     = recloc;
            dimsloc = recloc;
        }
    }

    public int getSize()
    {
        int retval = 0;

        for (int k = 0; k < records.size(); k++)
        {
            retval += (( Record ) records.get(k)).getRecordSize();
        }
        return retval;
    }

    public List getRecords()
    {
        return records;
    }

    /**
     * Gets the gridset record for this sheet.
     */

    public GridsetRecord getGridsetRecord()
    {
        return gridset;
    }

    /**
     * Returns the first occurance of a record matching a particular sid.
     */

    public Record findFirstRecordBySid(short sid)
    {
        for (Iterator iterator = records.iterator(); iterator.hasNext(); )
        {
            Record record = ( Record ) iterator.next();

            if (record.getSid() == sid)
            {
                return record;
            }
        }
        return null;
    }

    /**
     * Sets the SCL record or creates it in the correct place if it does not
     * already exist.
     *
     * @param sclRecord     The record to set.
     */
    public void setSCLRecord(SCLRecord sclRecord)
    {
        int oldRecordLoc = findFirstRecordLocBySid(SCLRecord.sid);
        if (oldRecordLoc == -1)
        {
            // Insert it after the window record
            int windowRecordLoc = findFirstRecordLocBySid(WindowTwoRecord.sid);
            records.add(windowRecordLoc+1, sclRecord);
        }
        else
        {
            records.set(oldRecordLoc, sclRecord);
        }

    }

    /**
     * Finds the first occurance of a record matching a particular sid and
     * returns it's position.
     * @param sid   the sid to search for
     * @return  the record position of the matching record or -1 if no match
     *          is made.
     */
    public int findFirstRecordLocBySid( short sid )
    {
        int index = 0;
        for (Iterator iterator = records.iterator(); iterator.hasNext(); )
        {
            Record record = ( Record ) iterator.next();

            if (record.getSid() == sid)
            {
                return index;
            }
            index++;
        }
        return -1;
    }

    /**
     * Returns the HeaderRecord.
     * @return HeaderRecord for the sheet.
     */
    public HeaderRecord getHeader ()
    {
	return header;
    }

    /**
     * Sets the HeaderRecord.
     * @param newHeader The new HeaderRecord for the sheet.
     */
    public void setHeader (HeaderRecord newHeader)
    {
    	header = newHeader;
    }

    /**
     * Returns the FooterRecord.
     * @return FooterRecord for the sheet.
     */
    public FooterRecord getFooter ()
    {
	    return footer;
    }

    /**
     * Sets the FooterRecord.
     * @param newFooter The new FooterRecord for the sheet.
     */
    public void setFooter (FooterRecord newFooter)
    {
	    footer = newFooter;
    }

    /**
     * Returns the PrintSetupRecord.
     * @return PrintSetupRecord for the sheet.
     */
    public PrintSetupRecord getPrintSetup ()
    {
	    return printSetup;
    }

    /**
     * Sets the PrintSetupRecord.
     * @param newPrintSetup The new PrintSetupRecord for the sheet.
     */
    public void setPrintSetup (PrintSetupRecord newPrintSetup)
    {
	    printSetup = newPrintSetup;
    }

    /**
     * Returns the PrintGridlinesRecord.
     * @return PrintGridlinesRecord for the sheet.
     */
    public PrintGridlinesRecord getPrintGridlines ()
    {
	    return printGridlines;
    }

    /**
     * Sets the PrintGridlinesRecord.
     * @param newPrintGridlines The new PrintGridlinesRecord for the sheet.
     */
    public void setPrintGridlines (PrintGridlinesRecord newPrintGridlines)
    {
	    printGridlines = newPrintGridlines;
    }

    /**
     * Sets whether the sheet is selected
     * @param sel True to select the sheet, false otherwise.
     */
    public void setSelected(boolean sel) {
        windowTwo.setSelected(sel);
    }

     /**
      * Gets the size of the margin in inches.
      * @param margin which margin to get
      * @return the size of the margin
      */
    public double getMargin(short margin) {
	if (getMargins()[margin] != null)
	    return margins[margin].getMargin();
	else {
	    switch ( margin )
		{
		case LeftMargin:
		    return .75;
		case RightMargin:
		    return .75;
		case TopMargin:
		    return 1.0;
		case BottomMargin:
		    return 1.0;
		default :
		    throw new RuntimeException( "Unknown margin constant:  " + margin );
		}
	}
    }

     /**
      * Sets the size of the margin in inches.
      * @param margin which margin to get
      * @param size the size of the margin
      */
    public void setMargin(short margin, double size) {
	Margin m = getMargins()[margin];
	if (m  == null) {
	    switch ( margin )
		{
		case LeftMargin:
		    m = new LeftMarginRecord();
		    records.add( getDimsLoc() + 1, m );
		    break;
		case RightMargin:
		    m = new RightMarginRecord();
		    records.add( getDimsLoc() + 1, m );
		    break;
		case TopMargin:
		    m = new TopMarginRecord();
		    records.add( getDimsLoc() + 1, m );
		    break;
		case BottomMargin:
		    m = new BottomMarginRecord();
		    records.add( getDimsLoc() + 1, m );
		    break;
		default :
		    throw new RuntimeException( "Unknown margin constant:  " + margin );
		}
	    margins[margin] = m;
	}
	m.setMargin( size );
    }

    public int getEofLoc()
    {
        return eofLoc;
    }

    /**
     * Creates a split (freezepane).
     * @param colSplit      Horizonatal position of split.
     * @param rowSplit      Vertical position of split.
     * @param topRow        Top row visible in bottom pane
     * @param leftmostColumn   Left column visible in right pane.
     */
    public void createFreezePane(int colSplit, int rowSplit, int topRow, int leftmostColumn )
    {
        int loc = findFirstRecordLocBySid(WindowTwoRecord.sid);
        PaneRecord pane = new PaneRecord();
        pane.setX((short)colSplit);
        pane.setY((short)rowSplit);
        pane.setTopRow((short) topRow);
        pane.setLeftColumn((short) leftmostColumn);
        if (rowSplit == 0)
        {
            pane.setTopRow((short)0);
            pane.setActivePane((short)1);
        }
        else if (colSplit == 0)
        {
            pane.setLeftColumn((short)64);
            pane.setActivePane((short)2);
        }
        else
        {
            pane.setActivePane((short)0);
        }
        records.add(loc+1, pane);

        windowTwo.setFreezePanes(true);
        windowTwo.setFreezePanesNoSplit(true);

        SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid);
//        SelectionRecord sel2 = (SelectionRecord) sel.clone();
//        SelectionRecord sel3 = (SelectionRecord) sel.clone();
//        SelectionRecord sel4 = (SelectionRecord) sel.clone();
//        sel.setPane(PANE_LOWER_RIGHT);         // 0
//        sel3.setPane(PANE_UPPER_RIGHT);        // 1
        sel.setPane((byte)pane.getActivePane());         // 2
//        sel2.setPane(PANE_UPPER_LEFT);         // 3
//        sel4.setActiveCellCol((short)Math.max(sel3.getActiveCellCol(), colSplit));
//        sel3.setActiveCellRow((short)Math.max(sel4.getActiveCellRow(), rowSplit));

        int selLoc = findFirstRecordLocBySid(SelectionRecord.sid);
//        sel.setActiveCellCol((short)15);
//        sel.setActiveCellRow((short)15);
//        sel2.setActiveCellCol((short)0);
//        sel2.setActiveCellRow((short)0);

//        records.add(selLoc+1,sel2);
//        records.add(selLoc+2,sel3);
//        records.add(selLoc+3,sel4);
    }

    /**
     * Creates a split pane.
     * @param xSplitPos      Horizonatal position of split (in 1/20th of a point).
     * @param ySplitPos      Vertical position of split (in 1/20th of a point).
     * @param topRow        Top row visible in bottom pane
     * @param leftmostColumn   Left column visible in right pane.
     * @param activePane    Active pane.  One of: PANE_LOWER_RIGHT,
     *                      PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
     * @see #PANE_LOWER_LEFT
     * @see #PANE_LOWER_RIGHT
     * @see #PANE_UPPER_LEFT
     * @see #PANE_UPPER_RIGHT
     */
    public void createSplitPane(int xSplitPos, int ySplitPos, int topRow, int leftmostColumn, int activePane )
    {
        int loc = findFirstRecordLocBySid(WindowTwoRecord.sid);
        PaneRecord r = new PaneRecord();
        r.setX((short)xSplitPos);
        r.setY((short)ySplitPos);
        r.setTopRow((short) topRow);
        r.setLeftColumn((short) leftmostColumn);
        r.setActivePane((short) activePane);
        records.add(loc+1, r);

        windowTwo.setFreezePanes(false);
        windowTwo.setFreezePanesNoSplit(false);

        SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid);
//        SelectionRecord sel2 = (SelectionRecord) sel.clone();
//        SelectionRecord sel3 = (SelectionRecord) sel.clone();
//        SelectionRecord sel4 = (SelectionRecord) sel.clone();
        sel.setPane(PANE_LOWER_RIGHT);         // 0
//        sel3.setPane(PANE_UPPER_RIGHT);        // 1
//        sel4.setPane(PANE_LOWER_LEFT);         // 2
//        sel2.setPane(PANE_UPPER_LEFT);         // 3
//        sel4.setActiveCellCol((short)Math.max(sel3.getActiveCellCol(), colSplit));
//        sel3.setActiveCellRow((short)Math.max(sel4.getActiveCellRow(), rowSplit));

        int selLoc = findFirstRecordLocBySid(SelectionRecord.sid);
//        sel.setActiveCellCol((short)15);
//        sel.setActiveCellRow((short)15);
//        sel2.setActiveCellCol((short)0);
//        sel2.setActiveCellRow((short)0);

//        records.add(selLoc+1,sel2);
//        records.add(selLoc+2,sel3);
//        records.add(selLoc+3,sel4);
    }

    public SelectionRecord getSelection()
    {
        return selection;
    }

    public void setSelection( SelectionRecord selection )
    {
        this.selection = selection;
    }
       /**
        * creates a Protect record with protect set to false.
        * @see org.apache.poi.hssf.record.ProtectRecord
        * @see org.apache.poi.hssf.record.Record
        * @return a ProtectRecord
        */

       protected Record createProtect()
       {
               log.log(log.DEBUG, "create protect record with protection disabled");
               ProtectRecord retval = new ProtectRecord();

               retval.setProtect(false);
               // by default even when we support encryption we won't
               return retval;
       }

       public ProtectRecord getProtect()
       {
               return protect;
     }

    /**
     * Sets whether the gridlines are shown in a viewer.
     * @param show whether to show gridlines or not
     */
    public void setDisplayGridlines(boolean show) {
        windowTwo.setDisplayGridlines(show);
    }

    /**
     * Returns if gridlines are displayed.
     * @return whether gridlines are displayed
     */
    public boolean isDisplayGridlines() {
	return windowTwo.getDisplayGridlines();
    }

    /**
     * Sets whether the formulas are shown in a viewer.
     * @param show whether to show formulas or not
     */
    public void setDisplayFormulas(boolean show) {
        windowTwo.setDisplayFormulas(show);
    }

    /**
     * Returns if formulas are displayed.
     * @return whether formulas are displayed
     */
    public boolean isDisplayFormulas() {
	return windowTwo.getDisplayFormulas();
    }

    /**
     * Sets whether the RowColHeadings are shown in a viewer.
     * @param show whether to show RowColHeadings or not
     */
    public void setDisplayRowColHeadings(boolean show) {
        windowTwo.setDisplayRowColHeadings(show);
    }

    /**
     * Returns if RowColHeadings are displayed.
     * @return whether RowColHeadings are displayed
     */
    public boolean isDisplayRowColHeadings() {
	return windowTwo.getDisplayRowColHeadings();
    }

    /**
     * Returns the array of margins.  If not created, will create.
     *
     * @return the array of marings.
     */
    protected Margin[] getMargins() {
        if (margins == null)
            margins = new Margin[4];
	return margins;
    }
}
