#include "hookthread.h"
#define MM(px) 0.353*px
HookThread* HookThread::hInstance = 0;
void HookThread::run()
{
	px = 0;
	leftMouse = 0;
	rightMouse = 0;
	stopHook = false;
	hInstance = this;
	HINSTANCE h = ::GetModuleHandle((WCHAR*)QApplication::applicationFilePath().utf16());
	HOOKPROC hproc = &hookProcess;
	hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, hproc, h, 0);
	
    exec();
}
LRESULT CALLBACK HookThread::hookProcess(int nCode, WPARAM wParam, LPARAM lParam)
{
	MOUSEHOOKSTRUCT *mStruct = (MOUSEHOOKSTRUCT*)lParam;
	hInstance->oldMousePos = hInstance->mousePos;
	hInstance->mousePos = QPointF(mStruct->pt.x, mStruct->pt.y);
	switch (wParam)
	{
		case WM_LBUTTONDOWN:
			//case WM_LBUTTONUP: 
			//case WM_LBUTTONDBLCLK: 
			hInstance->leftMouse+=1;
			break;
		case WM_RBUTTONDOWN:
			//case WM_RBUTTONUP: 
			//case WM_RBUTTONDBLCLK: 
			hInstance->rightMouse+=1;
			break;
		case WM_MOUSEWHEEL:
			//If the message is WM_MOUSEWHEEL, the high-order word of mouseData member is the wheel delta. 
			//One wheel click is defined as WHEEL_DELTA, which is 120. 
			//(value >> 16) & 0xffff; retrieves the high-order word from the given 32-bit value
			//mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);
			//TODO: X BUTTONS (I havent them so was unable to test)
			//If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, 
			//or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released, 
			//and the low-order word is reserved. This value can be one or more of the following values. 
			//Otherwise, mouseData is not used. 
			break;
	}
	hInstance->px += (qMax(hInstance->oldMousePos.x(),hInstance->mousePos.x()) - 
					qMin(hInstance->oldMousePos.x(), hInstance->mousePos.x())) +
					(qMax(hInstance->oldMousePos.y(),hInstance->mousePos.y()) - 
					qMin(hInstance->oldMousePos.y(), hInstance->mousePos.y()));
	hInstance->mmins += MM((qMax(hInstance->oldMousePos.x(),hInstance->mousePos.x()) - 
					qMin(hInstance->oldMousePos.x(), hInstance->mousePos.x())) +
					(qMax(hInstance->oldMousePos.y(),hInstance->mousePos.y()) - 
					qMin(hInstance->oldMousePos.y(), hInstance->mousePos.y())));
	emit hInstance->hooked();
	return CallNextHookEx(hInstance->hMouseHook, nCode, wParam, lParam);
}