#include <common/mmtimer.hpp>

MMTimer::MMTimer(void)
: mMinResolution(0), mIsOkay(FALSE), mHasTimedEvent(FALSE), mTimerID(0), mIsFirstBreak(TRUE)
{
	if(::timeGetDevCaps(&mTimerCapability,sizeof(TIMECAPS)))return;
  mMinResolution=mTimerCapability.wPeriodMin;
	if(::timeBeginPeriod(mMinResolution))return;
  mIsOkay=TRUE;
}

MMTimer::MMTimer(WORD minResolution)
: mMinResolution(minResolution), mIsOkay(FALSE), mHasTimedEvent(FALSE), mTimerID(0), mIsFirstBreak(TRUE)
{
	if(::timeGetDevCaps(&mTimerCapability,sizeof(TIMECAPS)))return;
  if(mMinResolution<mTimerCapability.wPeriodMin)mMinResolution=mTimerCapability.wPeriodMin;
	if(::timeBeginPeriod(mMinResolution))return;
  mIsOkay=TRUE;
}

MMTimer::~MMTimer()
{
	if(mIsOkay){stopTimer();::timeEndPeriod(mMinResolution);}
}

bool MMTimer::startTimer(UINT deltaTime)
{
	if(!mIsOkay)return false;
	if(mHasTimedEvent)return false;
	isFirstBreak(true);
	if(0==(mTimerID=::timeSetEvent(deltaTime,mMinResolution,(LPTIMECALLBACK)timerProc,(DWORD)this,TIME_PERIODIC)))return false;
  mHasTimedEvent=true;
  return true;
}

bool MMTimer::stopTimer(void)
{
	bool returnCode(false);

	if(!mIsOkay)return returnCode;
	if(!mHasTimedEvent)return returnCode;
	if(!::timeKillEvent(mTimerID))returnCode=true;
	isFirstBreak(false);
  mHasTimedEvent=false;
	mTimerID=0;
  return returnCode;
}

void CALLBACK MMTimer::timerProc(UINT /*wTimerID*/,UINT /*mMsg*/,DWORD dwUser,DWORD /*dummyOne*/,DWORD /*dummyTwo*/)
{
	CallbackData callbackData;
	if(!((MMTimer*)dwUser))return;
	if(((MMTimer*)dwUser)->isFirstBreak())
	{
	  ((MMTimer*)dwUser)->isFirstBreak(FALSE);
		((MMTimer*)dwUser)->timerStarted();
	}
	if(((CallbackData::ReturnType)FALSE)==((MMTimer*)dwUser)->mCallbackPointer.callback(callbackData))
	{
	  ((MMTimer*)dwUser)->timerStopped();
	  ((MMTimer*)dwUser)->stopTimer();
	}
  return;
}

// virtuals

void MMTimer::timerStarted(void)
{
  return;
}

void MMTimer::timerStopped(void)
{
  return;
}
