/*******************************************************************************
** Copyright (c) 2005 MaK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
/*******************************************************************************
** $RCSfile: logicalTimeIntervalImplFloat.h,v $ $Revision: 1.1 $ $State: Exp $
*******************************************************************************/

#ifndef RTI_LogicalTimeIntervalImplFloat_H_
#define RTI_LogicalTimeIntervalImplFloat_H_

#include <RTI/LogicalTimeInterval.h>

// Old deprecated stuff, keeping it here in case we support these platforms again
// #if !WIN32 && !VXWORKS && !VMS && !__darwin__
// #include <values.h>
// #else
// #if VMS
// #include <limits>
// #define MAXDOUBLE       numeric_limits<double>::max()
// #endif

#include <float.h>
#define POSITIVE_INFINITY (DBL_MAX)
#define NEGATIVE_INFINITY (-DBL_MAX)
#define EPSILON (DBL_MIN)
#ifdef _WIN32
#define nextafter _nextafter
#endif

class RTI_EXPORT_FEDTIME LogicalTimeIntervalImplFloat
   : public rti1516::LogicalTimeInterval
{
public:
   static std::wstring theImplementationName;

public:

   // Constructors
   LogicalTimeIntervalImplFloat();
   LogicalTimeIntervalImplFloat(const double&);
   LogicalTimeIntervalImplFloat(rti1516::LogicalTimeInterval const &);
   LogicalTimeIntervalImplFloat(const LogicalTimeIntervalImplFloat&);

   // Destructor
   virtual ~LogicalTimeIntervalImplFloat()
   throw ();

   // Basic accessors/mutators
   virtual void setZero();
   virtual bool isZero() const;

   virtual void setEpsilon();
   virtual bool isEpsilon() const;

   // Assignment
   virtual
   rti1516::LogicalTimeInterval&
   operator= (rti1516::LogicalTimeInterval const & value)
      throw (
         rti1516::InvalidLogicalTimeInterval);

    // Set self to the difference between two LogicalTimes
    virtual
    void
    setToDifference(rti1516::LogicalTime const & minuend,
      rti1516::LogicalTime const& subtrahend)
      throw (rti1516::InvalidLogicalTime);
   
   virtual
   rti1516::LogicalTimeInterval&
   operator+= (rti1516::LogicalTimeInterval const & addend)
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual
   rti1516::LogicalTimeInterval&
   operator-= (rti1516::LogicalTimeInterval const & subtrahend)
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual
   bool
   operator> (rti1516::LogicalTimeInterval const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual
   bool
   operator< (rti1516::LogicalTimeInterval const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual
   bool
   operator== (rti1516::LogicalTimeInterval const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual
   bool
   operator>= (rti1516::LogicalTimeInterval const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual
   bool
   operator<= (rti1516::LogicalTimeInterval const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   // Generates an encoded value that can be used to send
   // LogicalTimeIntervals to other federates in updates or interactions
   virtual rti1516::VariableLengthData encode() const;

   // Alternate encode for directly filling a buffer
   virtual unsigned long encodedLength() const;
   virtual unsigned long encode(void* buffer, unsigned long bufferSize) const
       throw (rti1516::CouldNotEncode);

   // Decode encodedValue into self
   virtual void decode(rti1516::VariableLengthData const & encodedValue)
      throw (
         rti1516::InternalError,
         rti1516::CouldNotDecode);

   // Alternate decode that reads directly from a buffer
   virtual void decode(void* buffer, unsigned long bufferSize)
      throw (
         rti1516::InternalError,
         rti1516::CouldNotDecode);

   virtual std::wstring toString() const;

   // Returns the name of the Implementation, as needed by
   // createFederationExecution.
    virtual std::wstring implementationName() const;

public:
   //-----------------------------------------------------------------
   // Implementation functions
   //-----------------------------------------------------------------
   virtual double getInterval() const;

   //-----------------------------------------------------------------
   // Implementation operators
   //-----------------------------------------------------------------
   virtual bool operator== (const double&) const
   throw (rti1516::InvalidLogicalTimeInterval);

   virtual bool operator!= (rti1516::LogicalTimeInterval const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual bool operator!= (LogicalTimeIntervalImplFloat const & value) const
      throw (
         rti1516::InvalidLogicalTimeInterval);

   virtual bool operator!= (const double&) const
      throw (rti1516::InvalidLogicalTimeInterval);

   virtual LogicalTimeIntervalImplFloat& operator= (
      const LogicalTimeIntervalImplFloat& value)
      throw (rti1516::InvalidLogicalTimeInterval);

   virtual rti1516::LogicalTimeInterval& operator= (const double&)
      throw (rti1516::InvalidLogicalTimeInterval);

   virtual rti1516::LogicalTimeInterval& operator+= (const double&)
      throw (rti1516::InvalidLogicalTimeInterval);

   virtual rti1516::LogicalTimeInterval& operator-= (const double&)
      throw (rti1516::InvalidLogicalTimeInterval);

   virtual void setToDifference(double minuend, double subtrahend)
      throw (rti1516::InvalidLogicalTimeInterval);

private:
   //-----------------------------------------------------------------
   // Implementation member variables
   //-----------------------------------------------------------------
   double myInterval;
   double myZero;
   double myEpsilon;
   double myPositiveInfinity;
};

#endif // RTI_LogicalTimeIntervalImplFloat_H_

