/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CExcelBook.h  -  description
                             -------------------
    begin                : Mon Jan 19 2004
    copyright            : (C) 2000-2005 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 __CEXCELBOOK_H__
#define __CEXCELBOOK_H__

#include <sptk3/excel/CExcelPalette.h>
#include <sptk3/excel/CExcelCellFormat.h>
#include <sptk3/excel/CExcelSheet.h>
#include <sptk3/excel/CExcelStyle.h>
#include <sptk3/excel/CExcelHeader.h>
#include <sptk3/excel/CExcelBAT.h>
#include <sptk3/excel/CExcelProperty.h>
#include <sptk3/excel/CExcelSST.h>
#include <sptk3/CStrings.h>
#include <stdio.h>

typedef void (*CExcelBookCallback)(const char *operationName,int percentage);

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

/// The Excel book
class SP_EXPORT CExcelBook {
   friend class CExcelSheet;
protected:
   std::string           m_name;              ///< Abstract workbook name
   std::string           m_lastError;         ///< Last processing error
   int                   m_codePage;          ///< Encoding type
   short                 m_BIFFversion;       ///< Excel BIFF format version
   CExcelRecordList      m_records;           ///< The list of records from Excel file
   int                  *m_sstRecordOffsets;  ///< Excel record offsets
   int                   m_sstRecordCount;    ///< Excel record count
   unsigned              m_bofPosition;       ///< The position of the first BOF in the file
   CExcelBookCallback    m_callback;          ///< Load/save progression callback
   CExcelStyles          m_styles;            ///< The list of global styles

   /// Computes the number of blocks (rounded up) using file positions
   /// @param start unsigned, the start position in the file
   /// @param end unsigned, the end position in the file
   /// @param blockSize unsigned, the size of the block in the file
   unsigned blockCount(unsigned start,unsigned end,unsigned blockSize=BIG_BLOCK_SIZE);

   /// Processes one Excel record
   void process_item(const CExcelRecord& record);

   /// Parses Excel File
   int  scanExcelFile(FILE *f);

   /// Parses Excel File for sheet information
   int  scanSheetsInfo(FILE *f);

   /// Parses Workbook Globals
   int  parseWorkBookGlobals(unsigned& dataStart);

   /// Decodes Excel shared string record
   int  decodeSSTrecord(const CExcelRecord& record);

   /// Decodes Excel extended shared string record
   int decodeEXTSSTrecord(const CExcelRecord& record);

   /// Saves Excel records for writing into the CExcelRecords
   /// @param records CExcelRecords&, the output set of records
   void saveRecords(CExcelRecordsBuffer& records);
protected:
   CExcelHeader          m_excelHeader;      ///< Excel file header
   CExcelBAT             m_excelBAT;         ///< Excel file Block Allocation Table (BAT)
   CExcelBAT             m_excelSBAT;        ///< Excel file Small Block Allocation Table (SBAT)
   CExcelProperties      m_excelProperties;  ///< Excel file Properties
   CBuffer              *m_workBookData;     ///< Workbook records buffer

   /// Calls a callback function (if set)
   void do_callback(const char *operation,int percentage);

public:
   CExcelSheets          sheets;             ///< The list of spreadsheets
   CExcelSST             sharedStringTable;  ///< The list of shared strings
   CExcelCellFormats     xfRecords;          ///< The list of formats
   CExcelPalette         palette;            ///< The list of the available colours

   /// Constructor
   /// @param name CString, an abstract name to associate with the workbook
   CExcelBook(std::string name="");

   /// Destructor
   ~CExcelBook();

   /// Clears inside structure completely
   void clear();

   /// Clears inside structure completely, 
   /// then creates the minimal set of fonts, formats, etc.
   void init();

   /// Returns an abstract workbook name
   const std::string& name() const { return m_name; }

   /// Sets an abstract workbook name
   void name(const char *nm) { m_name = nm; }

   /// Reads the Excel file
   /// @param fileName CString, the name of the input file
   int readExcelFile(std::string fileName);

   /// Reads the CSV file
   /// The sheet is created automatically for every imported CSV file
   /// @param fileName CString, the name of the input file
   int readCSVFile(std::string fileName);

   /// Saves the Excel file
   /// @param fileName CString, the name of the output file
   int writeExcelFile(std::string fileName);

   /// Saves the Excel file
   /// @param file FILE *, the external output file
   int writeExcelFile(FILE *file);

   /// Saves the CSV file
   /// @param fileName CString, the name of the output file
   /// @param sheetNumber unsigned, the number of sheet to export (the default is 0, the very first sheet)
   int writeCSVFile(std::string fileName,unsigned sheetNumber=0);

   /// Saves the CSV file
   /// @param file FILE *, the external output file
   /// @param sheetNumber unsigned, the number of sheet to export (the default is 0, the very first sheet)
   int writeCSVFile(FILE *file,unsigned sheetNumber=0);

   /// Reports the last error
   const char * lastError() { return m_lastError.c_str(); }

   /// Returns load/save progression callback
   CExcelBookCallback callback() const { return m_callback; }

   /// Defines load/save progression callback
   /// @param cb CExcelBookCallback, the new callback function
   void callback(CExcelBookCallback cb) { m_callback = cb; }

   /// Returns a numeric format for the index
   /// @param index unsigned, logical index for the numeric format
   const CExcelNumericFormat& numericFormat(unsigned index) const { return xfRecords.numericFormat(index); }

   /// Creates a new sheet in the book
   CExcelSheet *newSheet(const char *sheetName);

   /// Adds a new font to the font list, or finds similar existing font
   /// @param fontName const char *, font name
   /// @param fontHeight unsigned, font height in points
   /// @param fontAttr unsigned, font attr (EFM_ATTR_ITALIC,EFM_ATTR_BOLD,EFM_ATTR_UNDERLINE,EFM_ATTR_STRIKEOUT)
   /// @param charSet unsigned, character set as defined in Windows API LOGFONT structure
   /// @returns logical index of the new or existing font
   unsigned defineFont(const char *fontName,unsigned fontHeight,unsigned fontAttr=0,unsigned charSet=0);

   /// Returns the font by the logical font index.
   /// Font with index 4 is a dummy font and shouldn't be used.
   const CExcelFont& font(unsigned fontIndex) const;

   /// Defines a new cell format from the scratch
   /// @param fontIndex unsigned, the logical index of the existing font
   /// @param numericFormatIndex unsigned, the logical index of the existing numeric format
   /// @param align unsigned, the combination of align flags from enum CExcelCellAlignFlags
   /// @param wrap bool, the cell text wrap flag
   /// @param border CExcelBorderLine, the type of the cell border line
   /// @param pattern unsigned, one of the Excel standard pattern types 0..0x12
   /// @param patternForeColorIndex unsigned, the pattern fore color index in the palette
   /// @param patternBackColorIndex unsigned, the pattern back color index in the palette
   /// @returns the pointer on the new cell format
   CExcelCellFormat *defineFormat(
      unsigned fontIndex=0,
      unsigned numericFormatIndex=0,
      unsigned align=0,
      bool     wrap=false,
      CExcelBorderLine border=CBL_NONE,
      unsigned pattern=0,
      unsigned patternForeColorIndex=EPC_BLACK,
      unsigned patternBackColorIndex=EPC_WHITE
   );
};

/// @}

#endif
