#include <common/wintimer.hpp>
#include <common/except.hpp>

char WinTimer::smszClassName[]="WINTIMER";
char WinTimer::smszMenuName[]="";

WinTimer::WinTimer(HINSTANCE hProcessInstance)
: mTimerHandler(this,&WinTimer::timerHandler),
  mIsOkay(FALSE), mTimerID(InvalidID), mhInstance(hProcessInstance)
{
  initWinTimer();
}

WinTimer::WinTimer(const Window &someWindow)
: mTimerHandler(this,&WinTimer::timerHandler),
  mIsOkay(FALSE), mTimerID(InvalidID), mhInstance(someWindow.processInstance())
{
  initWinTimer();
}

void WinTimer::initWinTimer(void)
{
	Window::insertHandler(VectorHandler::TimerHandler,&mTimerHandler);
	registerClass();
	createWindow();
	mIsOkay=TRUE;
}

WinTimer::~WinTimer()
{
	if((HWND)*this){stopTimer();destroy();}
  Window::removeHandler(VectorHandler::TimerHandler,&mTimerHandler);
}

void WinTimer::registerClass(void)
{
	WNDCLASS wndClass;

	if(::GetClassInfo(mhInstance,smszClassName,(WNDCLASS FAR*)&wndClass))return;
	wndClass.style         =CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
	wndClass.lpfnWndProc   =(WNDPROC)Window::WndProc;
	wndClass.cbClsExtra    =0;
	wndClass.cbWndExtra    =sizeof(WinTimer*);
	wndClass.hInstance     =mhInstance;
	wndClass.hIcon         =::LoadIcon(NULL,IDI_APPLICATION);
	wndClass.hCursor       =::LoadCursor(NULL,IDC_ARROW);
	wndClass.hbrBackground =(HBRUSH)::GetStockObject(BLACK_BRUSH);
	wndClass.lpszMenuName  =smszMenuName;
	wndClass.lpszClassName =smszClassName;
	::RegisterClass(&wndClass);
	if(0==::GetClassInfo(mhInstance,smszClassName,(WNDCLASS FAR*)&wndClass))throw(NullError());
}

void WinTimer::createWindow(void)
{
	::CreateWindow(smszClassName,smszMenuName,
		WS_OVERLAPPED,
		CW_USEDEFAULT,CW_USEDEFAULT,
		CW_USEDEFAULT,CW_USEDEFAULT,
		NULL,NULL,mhInstance,(LPSTR)this);
	show(SW_HIDE);
  update();
}

WORD WinTimer::startTimer(UINT delayTime)
{
	if(!(HWND)*this)return FALSE;
	if(TimerID==mTimerID)return FALSE;
  return setTimer(mTimerID=TimerID,delayTime);
}

WORD WinTimer::stopTimer(void)
{
	WORD returnCode(FALSE);

	if(!(HWND)*this)return returnCode;
	if(InvalidID==mTimerID)return returnCode;
	returnCode=killTimer(mTimerID);
	mTimerID=InvalidID;
  return returnCode;
}

CallbackData::ReturnType WinTimer::timerHandler(CallbackData &someCallbackData)
{
	size_t size(mCallbackVector.size());

	for(int vectorIndex=0;vectorIndex<size;vectorIndex++)
    mCallbackVector[vectorIndex].callback(someCallbackData);
  return (CallbackData::ReturnType)FALSE;
}

WORD WinTimer::insertHandler(PureCallback *lpCallback)
{
	mCallbackVector.insert(&CallbackPointer(lpCallback));
  return mCallbackVector.size();
}

void WinTimer::removeHandler(PureCallback *lpCallback)
{
	size_t size((size_t)mCallbackVector.size());

	for(int vectorIndex=0;vectorIndex<size;vectorIndex++)
	{
		if(mCallbackVector[vectorIndex]==lpCallback)
		{
			mCallbackVector.remove(vectorIndex);
			size=(size_t)mCallbackVector.size();
      vectorIndex=-1;
		}
	}
}





































