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

#ifndef STRVALUE_H_
#define STRVALUE_H_

#include "DataValue.h"
#include "utils/Str.h"
#include "units/Units.h"

class RingBufferVoid;

/**
 *  Wraps a string (see Str) as a DataValue, so strings
 *  can be written to and read from the slate.  Also accommodates
 *  serialization of strings.
 *
 *  StrValues always have units of Units::NONE
 *
 *  Note: since these DataValues are created and destructed
 *  frequently, the new and delete operators have been overridden,
 *  so that objects can be re-used as needed.
 *
 *  StrValue::MallocRing_  stores deleted objects.
 *
 * \ingroup data
 */
class StrValue : public DataValue
{
public:

    /// Default constructior
    StrValue();

    /// Two value constructior
    StrValue( const char* value, size_t length = Str::NO_POS, const Unit& unit = Units::NONE );

    /// Single value constructior
    StrValue( const Str value );

    /// Copy Constructor
    StrValue( const StrValue& value );

    /// Constructor from binary
    StrValue( const void *binary );

    /// Destructor
    virtual ~StrValue()
    {}
    ;

    /// Override new
    void* operator new( size_t size );

    /// Override delete
    void operator delete( void* p );

    /// Return a pointer to a new copy
    virtual StrValue* copy() const;

    /// Subtraction of another DataValue to yield another DataValue
    virtual void minus( const DataValue* rhs, DataValue* assignTo ) const
    {}

    /// Multiplication by a double to yield another DataValue
    virtual void times( const double rhs, DataValue* assignTo ) const
    {}

    /// Return the absolute value of this difference from another DataValue
    virtual double absDiff( const DataValue* rhs ) const;

    /// Copy value to unsigned char
    virtual bool copyTo( const Unit& unit, unsigned char& assignTo ) const
    {
        return false;
    }

    /// Copy n-dimensional value to double
    //virtual bool copyTo( const Unit& unit, double& assignTo, unsigned int dim ) const;

    /// Copy value to double
    virtual bool copyTo( const Unit& unit, double& assignTo ) const
    {
        return false;
    }

    /// Copy value to float
    virtual bool copyTo( const Unit& unit, float& assignTo ) const
    {
        return false;
    }

    /// Copy value to unsigned int
    virtual bool copyTo( const Unit& unit, int& assignTo ) const
    {
        return false;
    }

    /// Comparison with unsigned char
    virtual int compare( const Unit& unit, const unsigned char& compareTo ) const
    {
        return -1;
    }

    /// Comparison with double
    virtual int compare( const Unit& unit, const double& compareTo ) const
    {
        return -1;
    }

    /// Comparison with float
    virtual int compare( const Unit& unit, const float& compareTo ) const
    {
        return -1;
    }

    /// Comparison with int
    virtual int compare( const Unit& unit, const int& compareTo ) const
    {
        return -1;
    }

    /// Comparison with another DataValue
    virtual int compare( const DataValue& compareTo ) const;

    /// Equality test with with unsigned char
    virtual bool equals( const Unit& unit, const unsigned char& compareTo ) const
    {
        return false;
    }

    /// Equality test with float
    virtual bool equals( const Unit& unit, const float& compareTo ) const
    {
        return false;
    }

    /// Equality test with double
    virtual bool equals( const Unit& unit, const double& compareTo ) const
    {
        return false;
    }

    /// Equality test with int
    virtual bool equals( const Unit& unit, const int& compareTo ) const
    {
        return false;
    }

    /// Equality test with another DataValue
    virtual bool equals( const DataValue& compareTo ) const;

    /// set from unsigned char value
    virtual bool setFrom( const Unit& unit, unsigned char value )
    {
        return false;
    }

    /// set from double value
    virtual bool setFrom( const Unit& unit, double value )
    {
        return false;
    }

    /// set from float value
    virtual bool setFrom( const Unit& unit, float value )
    {
        return false;
    }

    /// set int value
    virtual bool setFrom( const Unit& unit, int value )
    {
        return false;
    }

    /// set DataValue value
    virtual bool setFrom( const DataValue& value );

    // as a Str
    virtual const Str& asString() const;

    // sets the value
    void setString( const Str& str );

    // as a Str
    virtual Str toString() const;

    // as a Str
    virtual Str toString( const Unit& unit ) const;

    /// Send the data value to the indicated stream.
    /// Return the number of bytes written.
    /// For now, assume little-endian.
    virtual unsigned int toStream( OutStream& outStream ) const;

    /// Load the data from the a binary representation in the buffer
    /// Typically just a memcopy of the variable, though endianness
    /// may come into it.
    virtual void fromBinary( const void *buffer, unsigned short typeSize );
    virtual void fromBinary( const void *buffer );

protected:

    // The actual data
    Str value_;

};

#endif /*STRVALUE_H_*/
