#include "winmain.h"
#include "dinput.h"

LPDIRECTINPUT		 lpDInput		= NULL;	// pointer to direct input object
LPDIRECTINPUTDEVICE	 lpDIKeyboard	= NULL;	// pointer to keyboard device
LPDIRECTINPUTDEVICE	 lpDIMouse		= NULL;	// pointer to mouse device
char				 keyboard[144];			// contains state of keyboard
bool				 keyevent[144];			// scan code of a pressed key
DIMOUSESTATE		 MouseState;			// contains state of mouse
float				 mouse_x;
float				 mouse_y;

#define KEYBOARD_BUFFER_SIZE 1	// number of events in buffer

//==============================================
//	InitDInput()
//==============================================

int InitDInput(HWND hWnd, HINSTANCE hInstance)

{

	if (DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &lpDInput, NULL) != DI_OK)
	{
	}

	//--------------------
	// Keyboard
	//--------------------

	if (lpDInput->CreateDevice(GUID_SysKeyboard, &lpDIKeyboard, NULL) != DI_OK)
	{
	}

	if (lpDIKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
	{
	}

	if (lpDIKeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK)
	{
	}

	DIPROPDWORD dipdw;
	dipdw.diph.dwSize = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj = 0;
	dipdw.diph.dwHow = DIPH_DEVICE;
	dipdw.dwData = KEYBOARD_BUFFER_SIZE;

	if (lpDIKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK)
	{
	}

	if (lpDIKeyboard->Acquire() != DI_OK)
	{
	}

	//--------------------
	// Mouse
	//--------------------

	if (lpDInput->CreateDevice(GUID_SysMouse, &lpDIMouse, NULL) != DI_OK)
	{
	}

	if (lpDIMouse->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK)
	{
	}

	if (lpDIMouse->SetDataFormat(&c_dfDIMouse) != DI_OK)
	{
	}

	if (lpDIMouse->Acquire() != DI_OK)
	{
	}


return(0);
}

//==============================================
//	GetDInput()
//==============================================

int GetDInput()
{
	if(lpDIKeyboard->GetDeviceState(256, (LPVOID)keyboard) != DI_OK)
	{
	}

	if(lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&MouseState) != DI_OK)
	{
	}

	mouse_x = MouseState.lX;
	mouse_y = MouseState.lY;

	DIDEVICEOBJECTDATA key_pressed[KEYBOARD_BUFFER_SIZE]; 
	DWORD dwItems;
	HRESULT hRes = DIERR_INPUTLOST;

	while (DI_OK != hRes)
    {
		hRes = lpDIKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), key_pressed, &dwItems, 0);
		if (hRes != DI_OK)
		{
			lpDIKeyboard->Acquire();
		}
	}
	if ((key_pressed[0].dwData & 0x80) ? 1 : 0) // only key-down events are reported
	{
		keyevent[key_pressed[0].dwOfs] = true;
	}

return(0);
}

//==============================================
//	ReleaseDInput()
//==============================================

int ReleaseDInput()
{
	if (lpDInput != NULL)
	{
		lpDInput->Release();
	}
	
	if (lpDIKeyboard != NULL)
	{
		lpDIKeyboard->Unacquire();
		lpDIKeyboard->Release();
	}
	
	if (lpDIMouse != NULL)
	{
		lpDIMouse->Unacquire();
		lpDIMouse->Release();
	}

return(0);
}