/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CExcelSheet.h  -  description
                             -------------------
    begin                : Mon Jan 19 2004
    copyright            : (C) 2004 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it 
   under the terms of the GNU Library General Public License as published by
   the Free Software Foundation; either version 2 of the License, or (at 
   your option) any later version.

   This library is distributed in the hope that it will be useful, but 
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifndef __CEXCELSHEET_H__
#define __CEXCELSHEET_H__

#include <stdio.h>

#include <sptk3/excel/CExcelRows.h>
#include <sptk3/excel/CExcelRecordsBuffer.h>
#include <sptk3/excel/CExcelCellFormat.h>
#include <sptk3/excel/CExcelColumn.h>

#include <vector>

class CExcelBook;

/// @addtogroup excel Excel Classes
/// @{

/// Class CExcelSheet represents an Excel spreadsheet
class SP_EXPORT CExcelSheet {
   friend class CExcelBook;
private:
   std::string    m_sheetName;           	///< Spreadsheet name
   char           m_format_buffer[64];   	///< Spreadsheet formats
   const char    *m_lastError;           	///< Last processing error
   CExcelBook    *m_parentBook;          	///< Spreadsheet's parent book
   CExcelRow     *m_currentRow;          	///< Current row in the dataset.
   short          m_BIFFversion;         	///< Excel format version
   CExcelColumns  m_columns;             	///< Excel columns info
   unsigned			m_lastComputedPosition;	///< Last computed position

   /// Processes an Excel file record
   void        process_item (int rectype, int reclen, char *rec);

   /// Formats the floating point data with the format ixf
   char *      format_double(double d,int ixf);
protected:
   int                  m_sheetPosition;       ///< Spreadsheet position
   CExcelRecordsBuffer  m_recordsBuffer;       ///< Internal buffer for ExcelRecords

   /// Encodes sheet's data into internal records buffer
   /// The resulting recordset is used later to save sheet into Excel file.
   /// @param sheetStreamPosition unsigned, the position of the sheet BOF in the stream
   void encode(unsigned sheetStreamPosition);

   /// Returns internal recordsBuffer
   const CExcelRecordsBuffer& recordsBuffer() const { return m_recordsBuffer; }

   /// Reads the sheet from CSV file
   /// @param fileName CString, the name of the input file
   int readCSVFile(std::string fileName);

   /// Saves the sheet into CSV file
   /// @param fileName CString, the name of the output file
   int writeCSVFile(std::string fileName);

   /// Saves the sheet into CSV file
   /// @param file FILE *, the external output file
   int writeCSVFile(FILE *file);

   /// Loads spreadsheet from the Excel file
   int parseWorkSheet(CBuffer& excelData,unsigned& pos);

public:
   /// Spreadsheet rows
   CExcelRows rows;

protected:
   /// Protected constructor, only CExcelBook can create new CExcelSheet
   /// @param name const char *, spreadsheet name
   /// @param filePosition int, spreadsheet position in Excel file
   /// @param parentBook CExcelBook *, parent Excel book
   CExcelSheet(const char *name,int filePosition,CExcelBook *parentBook);

public:
   /// Returns spreadsheet name
   const std::string& name() const { return m_sheetName; }

   /// Sets spreadsheet name
   void name(const char *nm) { m_sheetName = nm; }

   /// Clears the spreadsheet data
   void clearData();

   /// Returns the width of the column
   /// @param col unsigned, column number
   /// @returns the width of the column - in characters of default font
   unsigned colWidth(unsigned col) const { return m_columns[col]->width(); }

   /// Sets the width of the column
   /// @param col unsigned, column number
   /// @param w unsigned, the width of the column - in characters of default font
   void colWidth(unsigned col,unsigned w) { m_columns[col]->width(w); }

   /// Returns the number of the rows in spreadsheet
   unsigned rowCount() const { return rows.size(); }

   /// Returns the number of the columns in spreadsheet
   unsigned colCount() const { return rows[0].size(); }

   /// Sets the data in the cell
   /// @param row unsigned, cell row number
   /// @param col unsigned, cell column number
   /// @param value CVariant, cell value
   /// @param format CExcelFormat *, pointer to the format record
   int setValue(unsigned row,unsigned col,CVariant value,const CExcelCellFormat *format);

   /// Sets the RK (integer,float,date,datetime) data in the cell
   /// @param row unsigned, cell row number
   /// @param col unsigned, cell column number
   /// @param value double, cell value
   /// @param rkType CVariantType, number type (integer,float)
   /// @param format CExcelFormat *, pointer to the format record
   int setRKValue(unsigned row,unsigned col,double value,CVariantType rkType,const CExcelCellFormat *format);

   /// Returns spreadsheet position in Excel file
   unsigned filePosition() const { return m_sheetPosition; }

   /// Changes the size of the spreadsheet
   void resize(unsigned height,unsigned width);

   /// Sets format to a group of cells
   /// @param format const CExcelCellFormat *, the cell format
   /// @param row1 unsigned, the first row in the cell group
   /// @param col1 unsigned, the first column in the cell group
   /// @param row2 unsigned, the last row in the cell group
   /// @param col2 unsigned, the last column in the cell group
   void format(const CExcelCellFormat *format,unsigned row1,unsigned col1,unsigned row2,unsigned col2);

   /// Updates vertical positions for the sheet rows
   /// Uses m_lastComputedPosition to start computations from
   void updatePositions();
};

/// The list of Excel spreadsheets
class SP_EXPORT CExcelSheets : public std::vector<CExcelSheet *> {
   CExcelBook  *m_parentBook; ///< Parent Excel book
public:

   /// Default constructor
   CExcelSheets() { m_parentBook = 0L; }

   /// Destructor
   ~CExcelSheets() { clear(); }

   /// Cleaner
   void clear();

   /// Attach the list to the parent Excel book
   void attach(CExcelBook *book) { m_parentBook = book; }
};

/// @}

#endif
