#ifdef _WIN32

#include "timestamp.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

class TimestampImplWin32 : public TimestampImpl {
private:
  LARGE_INTEGER performanceCount;

public:
  TimestampImplWin32() { QueryPerformanceCounter(&this->performanceCount); }

  TimestampImplWin32(double secs) {
    LARGE_INTEGER freq;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&this->performanceCount);
    this->performanceCount.QuadPart +=
        static_cast<LONGLONG>(secs * (double)freq.QuadPart);
  }

  virtual bool future() const {
    LARGE_INTEGER now;
    QueryPerformanceCounter(&now);
    return this->performanceCount.QuadPart > now.QuadPart;
  }

  virtual bool less(const TimestampImpl *other) const {
    const TimestampImplWin32 *other_impl =
        dynamic_cast<const TimestampImplWin32 *>(other);
    return this->performanceCount.QuadPart <
           other_impl->performanceCount.QuadPart;
  }

  virtual bool greater(const TimestampImpl *other) const {
    const TimestampImplWin32 *other_impl =
        dynamic_cast<const TimestampImplWin32 *>(other);
    return this->performanceCount.QuadPart >
           other_impl->performanceCount.QuadPart;
  }

  virtual double diff_secs(const TimestampImpl *other) const {
    const TimestampImplWin32 *other_impl =
        dynamic_cast<const TimestampImplWin32 *>(other);
    LONGLONG sec_diff =
        this->performanceCount.QuadPart - other_impl->performanceCount.QuadPart;

    LARGE_INTEGER freq;
    QueryPerformanceFrequency(&freq);

    return (double)sec_diff / (double)freq.QuadPart;
  }
};

Timestamp::Timestamp() : p_impl(new TimestampImplWin32()) {}
Timestamp::Timestamp(double secs) : p_impl(new TimestampImplWin32(secs)) {}

#endif // WIN32
