/** \file
 *
 *  Contains the HDF5LogWriter class definition.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 *
 */


#ifndef HDF5LOGWRITER_H_
#define HDF5LOGWRITER_H_

#include "data/BinaryDataType.h"
#include "logger/FilterLogWriter.h"
#include "logger/HasFilename.h"
#include "utils/HDF5.h"
#include "utils/Str.h"

class DataValue;

/**
 *  Defines a LogWriter that generates a NetCDF table of values.  A list of
 *  variable names is supplied to the constructor.  If any of these variables
 *  change their value in a computation cycle, then a record is added to the
 *  NetCDF file with the current value of every variable.  The Timestamp for
 *  each record corresponds to the time of the start of the computation cycle
 *  in which any value changed.
 *
 *  \ingroup logging
 */
class HDF5LogWriter : public FilterLogWriter, public HasFilename
{
public:

    /// Constructor.
    HDF5LogWriter( const Str& filename, bool version4, int varCount, char** varList, char** unitList,
                   int attCount = 0, char** attList = NULL );

    /// Destructor.
    virtual ~HDF5LogWriter();

    /// Start writing the NetCDF file
    unsigned int writeHeader();

    /// Write an entry to the buffer.  If a start of cycle is encountered,
    /// write the whole record to the NetCDF file.
    unsigned int write( const LogEntry *entry, const Unit* unit = NULL );

    /// Finish writing the NetCDF file
    unsigned int writeFooter();

    /// Return the filename
    const Str& getFilename()
    {
        return filename_;
    }

protected:

    // Override this method to do something special with data entries
    virtual unsigned int writeData( const DataEntry *dataEntry, int index, const Unit* unit );

    // Override this method to do something special with attribute entries
    virtual unsigned int writeAtt( const DataEntry *dataEntry, int index, const Unit* unit );

private:
    // Note that the copy constructor below is private and not given a body.
    // Any attempt to call it will return a compiler error.
    HDF5LogWriter( const HDF5LogWriter& old ); // disallow copy constructor

    /// Initialize variables, etc
    void initializeHDF5LogWriter();

    /// Add a new variable
    void addVar( const int index, const ElementURI* uri,
                 BinaryDataType binaryType, const Unit& unit,
                 short universalCode, bool useChunks );

    /// Set an attribute value
    void setAttValue( const DataEntry *dataEntry, const int attIndex );

    const Str filename_;
    HDF5File* hdf5File_;
    bool hdf5LogWriterInitialized_;
    bool finalized_;
    HDF5Dataset** vars_;
    HDF5Dataset** timeVars_;

};

#endif /*HDF5LOGWRITER_H_*/
