// DInput.cpp: implementation of the CDXDInput class.
//
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
#include <windows.h>
#include <windowsx.h>
#include <dinput.h>
#include <stdio.h>
*/

#include "DXDInput.h"
#include "mydef.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDXDInput::CDXDInput()
{
	ClassInit();
}

CDXDInput::~CDXDInput()
{
	ClassRelease();
}

//function
void CDXDInput::ClassInit()
{
	m_lpDInput     = NULL;
	m_lpDIKeyboard = NULL;
	m_lpDIMouse    = NULL;
}

void CDXDInput::ClassRelease()
{

	// 장치들의 해제.............
	if ( m_lpDIKeyboard != NULL )
	{
		m_lpDIKeyboard->Unacquire ();
		m_lpDIKeyboard->Release ();
		m_lpDIKeyboard = NULL;
	}
	if ( m_lpDIMouse != NULL )
	{
		m_lpDIMouse->Unacquire ();
		m_lpDIMouse->Release ();
		m_lpDIMouse = NULL;
	}
	if ( m_lpDInput != NULL )
	{
		m_lpDInput->Release ();
		m_lpDInput = NULL;
	}
}


///////////////////////////////////////////////////////////////////////////////////
// 다이렉트 인풋의 생성...... 반드시 윈도우 프로시져의 WM_CREATE 에서 생성할 것.
///////////////////////////////////////////////////////////////////////////////////

BOOL CDXDInput::DInputCreate ( HWND hwnd, DWORD keyFlags, DWORD mouseFlags  )
{
	HINSTANCE      hInst = ( HINSTANCE ) GetWindowLong ( hwnd, GWL_HINSTANCE );
	LPDIRECTINPUT  pDInput;
	HRESULT        hRef;

	hRef = DirectInputCreate (hInst, DIRECTINPUT_VERSION, &pDInput, NULL );
	if ( hRef != DI_OK )
	{
		ClassRelease ();
		AfxErrMsg("DirectInputCreate Error");
		return FALSE;
	}

	hRef = pDInput->QueryInterface ( IID_IDirectInput7, (LPVOID *)&m_lpDInput );
	if ( hRef != DI_OK )
	{
		ClassRelease ();
		AfxErrMsg("QueryInterface Error");
		return FALSE;
	}

	hRef = m_lpDInput->CreateDeviceEx ( GUID_SysKeyboard, IID_IDirectInputDevice7,
                                       (void**)&m_lpDIKeyboard, NULL );

	if ( hRef != DI_OK )
	{
		AfxErrMsg("Keyboard CreateDeviceEx Error");
		return FALSE;
	}

	hRef = m_lpDIKeyboard->SetDataFormat ( &c_dfDIKeyboard );

	if ( hRef != DI_OK )
	{
		ClassRelease ();
		AfxErrMsg("Keyboard DataFormat Error");
		return FALSE;
	}

	hRef = m_lpDIKeyboard->SetCooperativeLevel( hwnd, keyFlags );
	if ( hRef != DI_OK )
	{
		ClassRelease ();
		AfxErrMsg("Keyboard SetCooperativeLevel Error");
		return FALSE;
	}

	hRef = m_lpDInput->CreateDeviceEx ( GUID_SysMouse, IID_IDirectInputDevice7,
                                       (void**)&m_lpDIMouse, NULL );
	
	if ( hRef != DI_OK )
	{
		AfxErrMsg("Mouse CreateDeviceEx Error");
		return FALSE;
	}

	hRef = m_lpDIMouse->SetDataFormat ( &c_dfDIMouse ) ;
	if ( hRef != DI_OK )
	{
		ClassRelease ();
		AfxErrMsg("Mouse SetDataFormat Error");
	}

	hRef = m_lpDIMouse->SetCooperativeLevel( hwnd, mouseFlags );
	if ( hRef != DI_OK )
	{
		ClassRelease ();
		AfxErrMsg("Mouse SetCooperativeLevel Error");
	}
	return TRUE;
}


///////////////////////////////////////////////////////////////////////////////////
// 다이렉트 인풋의 생성...... 반드시 윈도우 프로시져의 WM_CREATE 에서 생성할 것.
///////////////////////////////////////////////////////////////////////////////////

HRESULT CDXDInput::AcquireCheck ( BOOL acquirecheck )
{
	HRESULT hRef;
	if ( m_lpDIKeyboard != NULL )
	{
		if ( acquirecheck )
		{
			hRef = m_lpDIKeyboard->Acquire ();
			if ( hRef != DI_OK )
			{
				switch ( hRef )
				{
				case DIERR_INVALIDPARAM:
					AfxErrMsg( "DIERR_INVALIDPARAM Error");
					break;
				case DIERR_NOTINITIALIZED:
					AfxErrMsg( "DIERR_NOTINITIALIZED Error");
					break;

					// 여기서 문제가 됨....
				case DIERR_OTHERAPPHASPRIO:
					AfxErrMsg( "DIERR_OTHERAPPHASPRIO Error");
					break;
				}
				AfxErrMsg("Keyboard acquire Error");
			}
		}
		else
		{
			hRef = m_lpDIKeyboard->Unacquire (); 
			if ( hRef != DI_OK )
			{
				if( hRef != DI_NOEFFECT )
					AfxErrMsg("Keyboard Unacquire Error");
			}
		}
	}

	if ( m_lpDIMouse != NULL )
	{
		if ( acquirecheck )
		{
			hRef = m_lpDIMouse->Acquire ();
			if ( hRef != DI_OK )
			{
				switch ( hRef )
				{
				case DIERR_INVALIDPARAM:
					AfxErrMsg( "DIERR_INVALIDPARAM Error");
					break;
				case DIERR_NOTINITIALIZED:
					AfxErrMsg( "DIERR_NOTINITIALIZED Error");
					break;

					// 여기서도 문제가 됨....
				case DIERR_OTHERAPPHASPRIO:
					AfxErrMsg( "DIERR_OTHERAPPHASPRIO Error");
					break;
				}
				AfxErrMsg("Mouse acquire Error");
			}
		}
		else
		{
			hRef = m_lpDIMouse->Unacquire ();
			if ( hRef != DI_OK )
			{
				if( hRef != DI_NOEFFECT )
					AfxErrMsg("Mouse Unacquire Error");
			}
		}
	}
	return FALSE;
}



HRESULT CDXDInput::GetKeyboardState ( BYTE *key )
{
	HRESULT hRef;
	BYTE    data[256];
	BOOL    check = TRUE;
	ZeroMemory ( data, sizeof(data) );


	if ( m_lpDIKeyboard == NULL )
	{
		AfxErrMsg( "Keyboard Error");
		return FALSE;
	}

	while (check)
	{
		hRef = m_lpDIKeyboard->GetDeviceState ( sizeof(data), data );
		if ( hRef == DI_OK )
		{
			check = FALSE;
		}
		else if ( hRef == DIERR_INPUTLOST )
		{
			hRef = m_lpDIKeyboard->Acquire ();
		}
	}

	for ( int i = 0; i < 256; i++ )
	{
		key[i] = data[i];
	}
	
	return hRef;
}



HRESULT CDXDInput::GetMouseState ( DIMOUSESTATE *Mouse )
{
	HRESULT hRef;
	BOOL    check = TRUE;

	if ( m_lpDIMouse == NULL )
	{
		AfxErrMsg( "Mouse Error");
		return FALSE;
	}

	while ( check ) 
	{
		hRef = m_lpDIMouse->GetDeviceState( sizeof(DIMOUSESTATE), Mouse );
		if ( hRef == DI_OK )
		{
			check = FALSE;
		}
		else if ( hRef == DIERR_INPUTLOST )
		{
			hRef = m_lpDIMouse->Acquire();
		}
	}
	return hRef;	
}

BOOL CDXDInput::KeyCheck(BYTE *key, int keycheck)
{
	return ( key[keycheck] & 0x80 ) ? TRUE : FALSE;
}
