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


#ifndef TABLELOGWRITER_H_
#define TABLELOGWRITER_H_

#include "LogWriter.h"

class DataEntry;
class ElementURI;
class OutStream;
class SyslogEntry;

/**
 *  Defines a LogWriter that generates a text 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 new line is added to the
 *  text table listing the current value of every variable.
 *
 *  See FileLogWriter for output to the filesystem.
 *
 *  \ingroup logging
 */
class TableLogWriter : public LogWriter
{
public:
    /// Constructor.
    TableLogWriter( int varCount, char** varList, char** unitList, bool interpolate );

    /// Constructor.
    TableLogWriter( LogWriter* outputTo, int varCount, char** varList, char** unitList, bool interpolate );

    /// Destructor.
    virtual ~TableLogWriter();

    /// Write an entry to the text log
    virtual unsigned int write( const LogEntry *entry, const Unit* unit = NULL );

    virtual unsigned int writeHeader();

    virtual unsigned int writeAllInterpolated();

    virtual unsigned int writeFooter();

    /// Reset cached input settings
    virtual void resetInputs();

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

    void initializeTableLogWriter();

    virtual void clearRow();
    virtual unsigned int writeRow();
    virtual unsigned int writeSyslog( const SyslogEntry* syslogEntry );
    virtual unsigned int writeToColumn( const DataEntry *dataEntry, const int column );

    const DataEntry** newDataEntryRow();
    void deleteDataEntryRow( const DataEntry** dataEntryRow );
    unsigned int writeInterpolated( const LogEntry *logEntry, const int column );
    unsigned int writeDataEntryRow( unsigned int row );
    DataEntry* interpolateDataEntry( const Timestamp& timestamp, const DataEntry* startEntry, const DataEntry* endEntry );
    DataEntry* nanDataEntry( const Timestamp& timestamp, const DataEntry* origEntry );

    LogWriter* outputTo_;
    int varCount_;
    char** varList_;
    char** unitList_;
    const Unit** units_;
    unsigned short* uriCodes_;
    bool* isUniversal_;
    int* codeLookup_;

    bool interpolate_;
    FlexArray<const DataEntry**> interpBuffer_;
    FlexArray<SyslogEntry*> interpSyslogs_;
    FlexArray<Timestamp*> interpTimes_;

    class True
    {};

    FlexArray<const True*> readerColumn_;

    Timestamp lastTime_;

    bool initializedTableLogWriter_;
    unsigned int slateElementURICount_;

    bool deleteLists_;

    static True True_;

};

#endif /*TABLELOGWRITER_H_*/
