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

#ifndef MESSAGINGDATAWRITER_H_
#define MESSAGINGDATAWRITER_H_

#include "DataWriter.h"
#include "DataElement.h"


class Unit;
class UniversalDataElement;
class DataWriter;

/**
 *  A DataAccessor that writes values to the Slate
 *  via its associated DataElement, and optionally, to LCM
 *
 *  \ingroup data
 */
class MessagingDataWriter : public DataWriter
{
public:


    /// @fn MessagingDataWriter( MessagingComponent* owner, DataElement& element, UniversalDataElement* universal, Logger::TimePrecisionType timePrecisionType, const Str& channel );
    /// @brief Initializing constructor.
    /// @param[in] owner MessagingComponent
    /// @param[in] element DataElement
    /// @param[in] universal UniversalDataElement
    /// @param[in] timePrecisionType Logger::TimePrecisionType
    /// @param[in] channel channel name
    MessagingDataWriter( Component* owner,
                         DataElement& element,
                         UniversalDataElement* universal,
                         Logger::TimePrecisionType timePrecisionType,
                         const Str& channel = Str::EMPTY_STR );

    /// @fn virtual ~MessagingDataWriter()
    /// @brief virtual destructor.
    virtual ~MessagingDataWriter();

    /**
     *  Sets the Component's DataValue, with an optional timestamp
     *  - Meets requirement \ref req_timing_timeStamp
     *  - Publishes to LCM (per policy)
     */
    virtual bool write( const Unit& unit, const unsigned char value, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );
    virtual bool write( const Unit& unit, const double value, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );
    virtual bool write( const Unit& unit, const int value, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );
    virtual bool write( const DataValue& value, const Timestamp& timestamp = Timestamp::NOT_SET_TIME );

    void setChannelName( const Str& channel );

    const Str& getChannelName( void ) const;

protected:
    ///@var Mutex Mutex_
    ///@brief Mutex for thread-safing an instance of DataElement.
    static Mutex Mutex_;

    ///@var Str channel_;
    ///@brief messaging channel name for this DataWriter
    Str channel_;

private:
    // don't allow copy constructor
    MessagingDataWriter( const MessagingDataWriter& );
    MessagingDataWriter& operator= ( const MessagingDataWriter& );

};

#endif /*MESSAGINGDATAWRITER_H_*/
