#ifndef TIME_H_INCLUDED
#define TIME_H_INCLUDED

#include <time.h>
#include <winsock.h>
#include <assert.h>

/* Windows CE does not have "getenv()" */
#define getenv(s)	NULL

struct timezone
{
 int tz_minuteswest; /* minutes W of Greenwich */
 int tz_dsttime;     /* type of dst correction */
};

#ifdef __cplusplus
extern "C" {
#endif

_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
{
  FILETIME        ft;
  SYSTEMTIME      st;
  LARGE_INTEGER   li;
  __int64         t;
  DWORD dwTick;
  static WORD wPreviousMilliseconds;
  static WORD wPreviousSecond;
  static int systemTimeResolution;

  if (! systemTimeResolution)
  {
    // tests resolution of GetSystemTime().
    SYSTEMTIME t1, t2;
    GetSystemTime(&t1);
    Sleep(100);
    GetSystemTime(&t2);
    if (! t1.wMilliseconds && ! t2.wMilliseconds)
    {
      systemTimeResolution = 1; // low resolution
    }
    else
    {
      systemTimeResolution = 2; // high resolution
    }
#ifdef DEBUG
    switch (systemTimeResolution)
    {
    case 0:
      assert(0);
      break;
    case 1:
      OutputDebugString(_T("Resolution of GetSystemTime() is LOW\r\n"));
      break;
    case 2:
      OutputDebugString(_T("Resolution of GetSystemTime() is HIGH\r\n"));
      break;
    default:
      assert(0);
      break;
    }
#endif
  }

  // get system time.
  GetSystemTime(&st);

  // adjust resolution.
  if (systemTimeResolution == 1)
  {
    // low resolution system timer.
    // create pseudo resolution with GetTickCount()
    st.wMilliseconds = (WORD) (GetTickCount() % 1000);
    if (wPreviousSecond == st.wSecond
        && wPreviousMilliseconds > st.wMilliseconds)
    {
      // ignore rollover
      st.wMilliseconds = wPreviousMilliseconds;
    }
    else
    {
      wPreviousMilliseconds = st.wMilliseconds;
    }
    wPreviousSecond = st.wSecond;
  }
  else if (systemTimeResolution == 2)
  {
    // high resolution system timer.
    dwTick = 0;
  }
  else
  {
    assert(0);
  }

  SystemTimeToFileTime(&st,&ft);
  li.LowPart  = ft.dwLowDateTime;
  li.HighPart = ft.dwHighDateTime;
  t  = li.QuadPart;			// 100ナノ秒単位
  t -= 116444736000000000i64;		// 1601/1/1 から 1970/1/1 までの経過時間
					//   = 370 (years)
					//     * 365.25 (days/year)
					//     * 24 (hr/day)
					//     * 60 (min/hr)
					//     * 60 (sec/min)
					//     * 10,000,000 (100ナノ秒単位）

  t /= 10;				// 100ナノ秒から1マイクロ秒単位に変換する
  
  tv->tv_sec  = (long) (t / 1000000);	// 秒
  tv->tv_usec = (long) (t % 1000000);	// マイクロ秒;
  return 0;
}

#ifdef __cplusplus
}
#endif

#endif
