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

#ifndef LCMUNIVERSALDATAWRITER_H_
#define LCMUNIVERSALDATAWRITER_H_

#include "data/BlobWriter.h"
#include "data/LcmDataWriter.h"
#include "data/UniversalDataWriter.h"

class UniversalDataElement;

/**
 *  LCM-enabled subclass of UniversalDataWriter. Publishes universal data item
 *  writes (made via UniversalDataWriter) to a specified LCM channel.
 */
class LcmUniversalDataWriter : public UniversalDataWriter, public LcmDataWriter
{
public:

    /**
       Constructor
       @param[in] element data element (passed to UniversalDataWriter
       @param[in] universal universal data element (passed to UniversalDataWriter)
       @param[in] timePrecision timestamp precision (passed to UniversalDataWriter)
       @param[in] source LCM source name
       @param[in] channel LCM channel name
       @param[in] policy LCM policy (e.g. for enabling/disabling publishing)
       @sa: DataWriter, UniversalDataWriter, LCMDataWriter

    */
    LcmUniversalDataWriter( Component* owner,
                            DataElement& element,
                            UniversalDataElement* universal,
                            Logger::TimePrecisionType timePrecision,
                            Str source,
                            Str channel,
                            LcmPolicy *policy = NULL );
    virtual ~LcmUniversalDataWriter();

    /**
     *  Sets the Component's DataValue, with precision and an optional timestamp
     *  - Meets reqiurement \ref req_timing_timeStamp
     */
    virtual bool writeWithAccuracy( const Unit& unit, const unsigned char value, const float accuracy, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );
    virtual bool writeWithAccuracy( const Unit& unit, const double value, const float accuracy, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );
    virtual bool writeWithAccuracy( const Unit& unit, const int value, const float accuracy, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );
    virtual bool writeWithAccuracy( const DataValue& value, const float accuracy, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );

    // Set accuracy separately
    virtual bool setAccuracy( const Unit& unit, const float value );

    /// Get accuracy function
    /// For recalling the current accuracy...
    virtual float getAccuracy( const Unit& unit );

    /// Returns true if one of the registered readers is requesting data
//    bool isAnyDataRequested();

protected:
};

class LcmUniversalBlobWriter: public LcmUniversalDataWriter, public AbstractBlobWriter
{

public:

    virtual ~LcmUniversalBlobWriter() {}

    // Re-implement abstract method from AbstractBlobWriter
    virtual bool write( const DataValue& value, const Timestamp& timestamp )
    {
//        return LcmUniversalDataWriter::write( value, timestamp );
        return LcmDataWriter::write( value, timestamp );
    }

    // Re-implement abstract method from AbstractBlobWriter
    virtual const ElementURI& getUri( void ) const
    {
        return UniversalDataWriter::getUri();
    }

protected:

    friend class Component;

    LcmUniversalBlobWriter( Component* owner,
                            DataElement& element,
                            UniversalDataElement* universal,
                            Logger::TimePrecisionType timePrecisionType,
                            Str source,
                            Str channel,
                            LcmPolicy *policy = NULL )
        : LcmUniversalDataWriter( owner, element, universal, timePrecisionType, source, channel, policy ),
          AbstractBlobWriter( UniversalDataWriter::getUri() )
    {}



};


#endif /*LCMUNIVERSALDATAWRITER_H_*/
