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

#ifndef UNIVERSALDATAWRITER_H_
#define UNIVERSALDATAWRITER_H_

#include "data/BlobWriter.h"
#include "data/MessagingDataWriter.h"

class UniversalDataElement;

/**
 *  A DataAccessor that writes values to the Slate
 *  via its associated DataElement.
 *
 *  \ingroup data
 */
class UniversalDataWriter : public MessagingDataWriter
{
public:
    UniversalDataWriter( Component* owner,
                         DataElement& element,
                         UniversalDataElement* universal,
                         Logger::TimePrecisionType timePrecision );

    UniversalDataWriter( Component* owner,
                         DataElement& element,
                         UniversalDataElement* universal,
                         Logger::TimePrecisionType timePrecision,
                         const Str& channel );

    virtual ~UniversalDataWriter();

    /**
     *  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 );

//    virtual void setChannelName( const Str& channel )
//    {
//        MessagingDataWriter::setChannelName( channel );
//    }

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

protected:
};

class UniversalBlobWriter: public UniversalDataWriter, public AbstractBlobWriter
{

public:

    virtual ~UniversalBlobWriter() {}

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

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

protected:

    friend class Component;

    UniversalBlobWriter( Component* owner,
                         DataElement& element,
                         UniversalDataElement* universal,
                         Logger::TimePrecisionType timePrecisionType )
        : UniversalDataWriter( owner, element, universal, timePrecisionType ),
          AbstractBlobWriter( DataWriter::getUri() )
    {}

};


#endif /*UNIVERSALDATAWRITER_H_*/
