/****************************************************************/
/**@file timer.cpp: 
 * Desctiption: Real time timer support stuff.			*
 * Dependency: Windows (9x|2k|XP) 			        *
 ****************************************************************/
#include <windows.h>
#include <Mmsystem.h>

#include "timer.h"

#if _MSC_VER <= 1200
 #define DWORD_PTR unsigned long
#endif

/** Main callback procedure that redirects callback to wrappered object */
void CALLBACK CbTimeProc(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
RtTimer *Timer = reinterpret_cast<RtTimer*>(dwUser);

  (void)uMsg; (void)uID; (void)dw1; (void)dw2;	//make compiller happy

  if(Timer==NULL) return;
  if(Timer->TickIsRunning) return;
  Timer->TickIsRunning = true;
  try {Timer->Tick();}
  catch(...) {} ///just for safety. \todo: emit some warning somewhere
  Timer->TickIsRunning = false;
}


void RtTimer::Start(int Period)
{
  if(MmR>0) Stop();

  period=Period;
  MmR = timeSetEvent(
    Period,	   // uDelay,      
    1,	           // uResolution, 
    CbTimeProc,    //lpTimeProc,  
    (DWORD)this,   //DWORD_PTR      dwUser,      
    TIME_PERIODIC|TIME_CALLBACK_FUNCTION //fuEvent      
    );
}


void RtTimer::Stop(void)
{
  if(MmR<=0) return;
  timeKillEvent(MmR);  
  MmR=0;
}


DWORD RtTimer::GetTimeInMs(void)
{
 return timeGetTime();
}