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

#ifndef DATAACCESS_H_
#define DATAACCESS_H_

#include "data/BinaryDataType.h"
#include "data/DataAccessor.h"
#include "data/ElementURI.h"
#include "io/InStream.h"
#include "io/OutStream.h"

class Component;
class DataElement;
class Unit;
class UniversalDataElement;

/**
 *  Serializable representation of DataAccessor object.
 *  Has friend access to DataElement and DataValue/
 *
 *  \ingroup data
 */
class DataAccess
{
public:

    /**
     *  Constructor (called only by via Slate call for a new DataAccessor).
     */
    DataAccess( const DataAccessor& dataAccessor, UniversalDataElement* universal, unsigned short code = NO_CODE );

    /**
     *  Constructor (called by unserialiation code).
     */
    DataAccess( const unsigned short ownerCode,
                const unsigned short elementCode,
                const unsigned short unniversalCode,
                const char* unitName,
                BinaryDataType binaryType,
                unsigned short typeSize,
                DataAccessor::AccessorType accessorType,
                unsigned short code,
                bool noInterpFlag,
                Logger::TimePrecisionType timePrecisionType );

    virtual ~DataAccess();

    inline unsigned short getOwnerCode() const
    {
        return ownerCode_;
    }

    inline unsigned short getElementCode() const
    {
        return elementCode_;
    }

    inline unsigned short getUniversalCode() const
    {
        return universalCode_;
    }

    const Unit* getUnit();

    inline BinaryDataType getBinaryType() const
    {
        return binaryType_;
    }

    inline unsigned short getTypeSize() const
    {
        return typeSize_;
    }

    inline DataAccessor::AccessorType getAccessorType() const
    {
        return accessorType_;
    }

    inline void setCode( const unsigned short code )
    {
        code_ = code;
    }

    inline const unsigned short getCode() const
    {
        return code_;
    }

    void setNoInterpFlag()
    {
        noInterpFlag_ = true;
    }

    bool getNoInterpFlag() const
    {
        return noInterpFlag_;
    }

    const Str asString( bool includeCodeAndUnit );

    static const unsigned short NO_CODE = 0x3FFF;

    unsigned int write( OutStream& outStream );

    void copyUnitsTypeAndSizeFrom( DataAccess* dataAccess );

    static DataAccess* Read( InStream& inStream );

    Logger::TimePrecisionType getTimePrecision()
    {
        return timePrecision_;
    }

protected:

    unsigned short ownerCode_;
    unsigned short elementCode_;
    unsigned short universalCode_;
    const Unit* unit_;
    BinaryDataType binaryType_;
    unsigned short typeSize_;
    DataAccessor::AccessorType accessorType_;
    unsigned short code_;
    Str* tempUnitName_;
    bool noInterpFlag_;
    Logger::TimePrecisionType timePrecision_;

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

};

#endif /*DATAACCESS_H_*/
