/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CExcelProperty.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 __CEXCELPROPERTY_H__
#define __CEXCELPROPERTY_H__

#include <stdio.h>
#include <string.h>

#include <sptk3/excel/CExcelBAT.h>

#include <vector>

#define PROPERTY_SIZE               0x80

#define _NAME_SIZE_OFFSET           0x40
#define _NO_INDEX                   -1

// useful offsets
#define _PROPERTY_TYPE_OFFSET       0x42
#define _NODE_COLOR_OFFSET          0x43
#define _PREVIOUS_PROPERTY_OFFSET   0x44
#define _NEXT_PROPERTY_OFFSET       0x48
#define _CHILD_PROPERTY_OFFSET      0x4C
#define _STORAGE_CLSID_OFFSET       0x50
#define _USER_FLAGS_OFFSET          0x60
#define _SECONDS_1_OFFSET           0x64
#define _DAYS_1_OFFSET              0x68
#define _SECONDS_2_OFFSET           0x6C
#define _DAYS_2_OFFSET              0x70
#define _START_BLOCK_OFFSET         0x74
#define _SIZE_OFFSET                0x78

// node colors
#define _NODE_BLACK                 1
#define _NODE_RED                   0

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

/// Represents an internal file system property in Excel File
class CExcelProperty {
   char    m_data[PROPERTY_SIZE];         ///< Property data buffer
   CBuffer m_streamData;                  ///< Property stream buffer
public:
   /// Constructor
   /// @param pname CString, property name
   /// @param ptype unsigned, property type: 1 (directory), 2 (file), or 5 (root entry)
   /// @param nodeColor unsigned, node color: 0 (red) or 1 (black)
   /// @param previousProperty unsigned, previous property index
   /// @param nextProperty unsigned, next property index
   /// @param firstChildPropety unsigned, first child property index
   /// @param startBlock unsigned, first block of the file described by this property
   /// @param fileLength unsigned, the actual length of the file described by this property
   CExcelProperty(
      std::string pname,
      unsigned ptype=0x5,
      unsigned nodeColor=0x0,
      unsigned previousProperty=0xFFFFFFFF,
      unsigned nextProperty=0xFFFFFFFF,
      unsigned firstChildPropety=0xFFFFFFFF,
      unsigned startBlock=0xFFFFFFFE,
      unsigned fileLength=0
   );

   /// Constructor
   /// Creates property from internal Excel file' binary presentation
   /// @param data const char *, the bynary presentation of the property in internal Excel format
   CExcelProperty(const char *data);

   /// Returns the property name
   std::string name() const;

   /// Returns property type (1-directory, 2-file, 5-root entry)
   unsigned propertyType() const;

   /// Returns binary presentation of the property
   const char *data() const { return m_data; }

   /// Returns property stream buffer
   CBuffer& streamData() { return m_streamData; }

   /// Finds the stream data connected to the property and loads them into m_streamData
   /// @param batTable CExcelBAT *, the existing BAT table
   /// @param f FILE *, input file
   void extract(CExcelBAT *batTable,FILE *f);

   /// Returns the first block number for this property' stream in the BAT
   unsigned firstBATBlock() const;

   /// Sets the first block number for this property' stream in the BAT
   /// @param sbo unsigned, the first block number
   void firstBATBlock(unsigned sbo);

   /// Returns actual property' stream length
   unsigned fileLength() const;

   /// Sets actual property' stream length
   void fileLength(unsigned fl);

   /// Returns block count required to store the property' stream
   unsigned blockCount() const;
};

/// The collection of properties
class CExcelProperties : public std::vector<CExcelProperty *> {
public:
   /// Default constructor
   CExcelProperties() {}

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

   /// Cleaner
   void clear();

   /// Saves properties to file
   void save(FILE *f);

   /// Returns number of blocks required to store the properties
   unsigned blocks() const;

   /// Extracts properties from the file and header
   /// @param fileHeader CExcelHeader *, the Excel file header
   /// @param batTable CExcelBAT *, the Excel BAT table
   /// @param f FILE *, the input file
   void extract(CExcelHeader *fileHeader,CExcelBAT *batTable,FILE *f);

   /// Finds a property by name
   /// @param name const char *, property name
   CExcelProperty *find(const char *name);
};

/// @}

#endif
