/**
 * @file Timestamp.h
 * Definition of class example::Timestamp.
 */

#ifndef __Timestamp_h_
#define __Timestamp_h_

#include <string>

namespace example {
class IStreamable;
class InStream;
class OutStream;

/**
 * Timestamp is a timestamp with nanosecond resolution.
 */
class Timestamp
  : public IStreamable
{
public:

/**
 * Default constructor.
 */
Timestamp();

/**
 * Constructor.
 *
 * @param sec   The seconds
 * @param nsec  The nanoseconds
 */
Timestamp(long sec, unsigned long nsec);

/**
 * Destructor.
 */
virtual ~Timestamp();

/**
 * Adds two timestamps.
 *
 * @param rhs The other timestamp
 * @return The resulting timestamp
 */
Timestamp operator+(const Timestamp& rhs) const;

/**
 * Subtracts two timestamps.
 *
 * @param rhs The other timestamp
 * @return The resulting timestamp
 */
Timestamp operator-(const Timestamp& rhs) const;

/**
 * Compares two timestamps.
 *
 * @param rhs The other timestamp
 * @return true if timestamp is smaller than the given timestamp
 */
bool operator<(const Timestamp& rhs) const;

/**
 * Compares two timestamps.
 *
 * @param rhs The other timestamp
 * @return true if timestamp is greater than the given timestamp
 */
bool operator>(const Timestamp& rhs) const;

/**
 * Compares two timestamps.
 *
 * @param rhs The other timestamp
 * @return true if timestamp is equal to the given timestamp
 */
bool operator==(const Timestamp& rhs) const;

/**
 * Compares two timestamps.
 *
 * @param rhs The other timestamp
 * @return true if timestamp is not equal to the given timestamp
 */
bool operator!=(const Timestamp& rhs) const;

/**
 * Adds an other timestamp.
 *
 * @param rhs The other timestamp
 */
void operator+=(const Timestamp& rhs);

/**
 * Adds milliseconds.
 *
 * @param ms The milliseconds
 * @return The resulting timestamp
 */
Timestamp addMilliseconds(unsigned long ms) const;

/**
 * Adds nanoseconds.
 *
 * @param ns The nanoseconds
 * @return The resulting timestamp
 */
Timestamp addNanoseconds(unsigned long ns) const;

/**
 * Checks if this timestamp is zero.
 *
 * @return true if timestamp is zero
 */
bool isZero() const;

/**
 * Gets the milliseconds.
 * @attention Negative timestamp returns zero
 *
 * @return The milliseconds
 */
unsigned long getMilliseconds() const;

/**
 * Divide timestamps by two.
 *
 * @return The resulting timestamp
 */
Timestamp divideByTwo();

/**
 * Gets the string-representation.
 *
 * @return The string representation
 */
std::string getString() const;

/**
 * Gets the string-representation in milliseconds.
 *
 * @return The string representation
 */
std::string getStringMilliseconds() const;

/**
 * Resets the timestamp.
 */
void reset();

/** The seconds */
long sec;

/** The nanoseconds */
unsigned long nsec;

InStream& operator <<(InStream& in);

OutStream& operator >>(OutStream& out) const;
};
} // namespace

#endif // __Timestamp_h_
