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

#ifndef DATAREADER_H_
#define DATAREADER_H_

#include "data/DataAccessor.h"
#include "data/Double.h"
#include "utils/Timestamp.h"

class DataReader;
class Unit;
template<typename T> class FlexArray;

/**
 *  A DataAccessor that reads values from the Slate
 *  Contains a default dataValue that must not be NULL,
 *  which is returned if a dataValue request is made and
 *  this Accessor's associated DataElement is unavailable
 *  for some reason (not initialized, orphaned, or failed).
 *
 *  \ingroup data
 */
class DataReader : public DataAccessor
{
public:
    DataReader( Component* owner, DataElement& element,
                const DataValue* defaultValue,
                bool deleteDefaultValue = true );
    DataReader( Component* owner, DataElement& element,
                const Unit& defaultUnit );
    virtual ~DataReader();

    const Unit* getDefaultUnit();

    //===============================================================
    /// Status and state functions
    // (or these common, should be DataElement?)
    bool isUnavailable( void );
    bool isInvalid( void );
    bool isOrphaned( void );
    bool isActive( void );

    //===============================================================
    /// Get functions
    bool read( const Unit& unit, unsigned char& readTo );
    bool read( const Unit& unit, double& readTo );
    bool read( const Unit& unit, float& readTo );
    bool read( const Unit& unit, int& readTo );
    bool read( bool& readTo );
    bool read( Timespan& readTo );
    bool read( DataValue& readTo );
    int asInt( const Unit& unit );
    double asDouble( const Unit& unit ) __attribute__( ( deprecated ) );
    Str asString( const Unit& unit );

    /**
     * Returns the Timestamp of the last write to this reader's DataElement
     * - Meets requirement \ref req_timing_lastUpdate
     */
    const Timestamp& getTimestamp( void ) const;

    /**
     * Returns true if the value was touched since the last run of the
     * indicated component.
     */
    bool wasTouchedSinceLastRun( const Component* component );

    virtual void requestData( bool requestingData )
    {
        requestData( requestingData ? MIN_POWER : NO_STRATEGY );
    }

    virtual void requestData( RequestStrategy requestStrategy )
    {
        requestStrategy_ = requestStrategy;
    }

    bool isRequestingData( void )
    {
        return  requestStrategy_ != NO_STRATEGY;
    }

    RequestStrategy getRequestStrategy( void )
    {
        return requestStrategy_;
    }

    void setImplementor( bool implementor = true )
    {
        implementor_ = implementor;
    }

    bool isImplementor()
    {
        return implementor_;
    }

    DataValue* getDefaultValueCopy()
    {
        return defaultValue_ ? defaultValue_->copy() : NULL;
    }


protected:

    RequestStrategy requestStrategy_;
    const DataValue* defaultValue_;
    const Unit& defaultUnit_;
    bool deleteDefaultValue_;
    bool implementor_;

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

#endif /*DATAREADER_H_*/
