#include "KeyboardManager.h"

KeyboardManager::KeyboardManager(void)
{
	g_pDI = 0;

	ZeroMemory( &m_KeyBuffer, sizeof( m_KeyBuffer ) );
	m_pKeyDev = 0;

	initialized = FALSE;
}

KeyboardManager::~KeyboardManager(void)
{
}

HRESULT KeyboardManager::Initialize( HWND g_hWndMain ) {
	HRESULT r;

	if ( !g_pDI ) {
		return E_FAIL;
	}

	// Release the device if it has already been created
	if ( m_pKeyDev ) {
		m_pKeyDev->Unacquire();
		m_pKeyDev->Release();
	}

	// Create the device for the keyboard
	r = g_pDI->CreateDevice( GUID_SysKeyboard, &m_pKeyDev, NULL );
	if ( FAILED( r ) ) {
		GameError( "Failed to create key device" );
		return E_FAIL;
	}

	// Set the data format for the device
	r = m_pKeyDev->SetDataFormat( &c_dfDIKeyboard );
	if ( FAILED( r ) ) {
		GameError( "Unable to set the keyboard data format" );
		return E_FAIL;
	}

	// Set the cooperative level
	r = m_pKeyDev->SetCooperativeLevel( g_hWndMain,
										DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );

	if ( FAILED( r ) ) {
		GameError( "Unable to set keyboard cooperative level" );
		return E_FAIL;
	}

	// Acquire the device
	r = m_pKeyDev->Acquire();
	if ( FAILED( r ) ) {
		GameError( "Unable to acquire the keyboard" );
		return E_FAIL;
	}

	// Set the initialization flag to true
	initialized = TRUE;

	return S_OK;
}

BOOL KeyboardManager::IsKeyDown( int Key ) {
	HRESULT r = 0;

	// Make sure the keyboard has been initialized
	if ( !initialized ) {
		return FALSE;
	}

	// Get the state of the keyboard into the key buffer
	r = m_pKeyDev->GetDeviceState( sizeof( m_KeyBuffer ), &m_KeyBuffer );
	if ( FAILED( r ) ) {
		// If the device is not acquired....
		if ( r == DIERR_INPUTLOST ) {
			// ...then reacquire the device
			while ( r == DIERR_INPUTLOST ) {
				r = m_pKeyDev->Acquire();
			}

			if ( SUCCEEDED( r ) ) {
				m_pKeyDev->GetDeviceState( sizeof( m_KeyBuffer ), &m_KeyBuffer );
			} else {
				return FALSE;
			}
		} else {
			// Otherwise it was some other error
			return FALSE;
		}
	}

	// Check if the key was set
	if ( m_KeyBuffer[ Key ] & 0x80 ) {
		return TRUE;
	} else {
		return FALSE;
	}
}

HRESULT KeyboardManager::InitializeInput( HINSTANCE hInstance ) {
	// Release any previous objects if they exist
	if ( g_pDI ) {
		g_pDI->Release();
	}

	// Create the DirectInput8 object
	HRESULT r = DirectInput8Create( hInstance,
							DIRECTINPUT_VERSION,
							IID_IDirectInput8,
							( void** ) &g_pDI,
							NULL );
	if ( FAILED( r ) ) {
		GameError( "Failed to create DirectInput" );
		return E_FAIL;
	}

	return S_OK;
}

HRESULT KeyboardManager::ShutdownInput() {
	if ( g_pDI ) {
		g_pDI->Release();
		g_pDI = 0;
	}

	return E_FAIL;
}

HRESULT KeyboardManager::CheckState() {
	HRESULT r = m_pKeyDev->GetDeviceState( sizeof( m_KeyBuffer ), &m_KeyBuffer );

	if ( FAILED( r ) ) {
		r = m_pKeyDev->Acquire();
		if ( FAILED( r ) ) {
			return E_FAIL;
		}
	}

	return S_OK;
}

bool KeyboardManager::movement() {
	return ( IsKeyDown(DIK_UP) || IsKeyDown(DIK_DOWN) || IsKeyDown( DIK_LEFT) || IsKeyDown( DIK_RIGHT) );
	
}

BOOL KeyboardManager::IsKeyUp( int Key ) {
	return !IsKeyDown( Key );
}

bool KeyboardManager::movementUp(){
    return ( IsKeyDown(DIK_UP) && IsKeyUp(DIK_DOWN) && IsKeyUp( DIK_LEFT)   && IsKeyUp( DIK_RIGHT)   ||
             IsKeyDown(DIK_UP) && IsKeyUp(DIK_DOWN) && IsKeyDown( DIK_LEFT) && IsKeyDown( DIK_RIGHT) );
}
bool KeyboardManager::movementUpRight(){
    return ( IsKeyDown(DIK_UP) && IsKeyUp(DIK_DOWN) && IsKeyUp( DIK_LEFT) && IsKeyDown( DIK_RIGHT) );
}
bool KeyboardManager::movementRight(){
    return ( IsKeyUp(DIK_UP)   && IsKeyUp(DIK_DOWN)   && IsKeyUp( DIK_LEFT) && IsKeyDown( DIK_RIGHT) ||
             IsKeyDown(DIK_UP) && IsKeyDown(DIK_DOWN) && IsKeyUp( DIK_LEFT) && IsKeyDown( DIK_RIGHT) );
}
bool KeyboardManager::movementDownRight(){
    return ( IsKeyUp(DIK_UP) && IsKeyDown(DIK_DOWN) && IsKeyUp( DIK_LEFT) && IsKeyDown( DIK_RIGHT) );
}
bool KeyboardManager::movementDown(){
    return ( IsKeyUp(DIK_UP) && IsKeyDown(DIK_DOWN) && IsKeyUp( DIK_LEFT)   && IsKeyUp( DIK_RIGHT)   ||
             IsKeyUp(DIK_UP) && IsKeyDown(DIK_DOWN) && IsKeyDown( DIK_LEFT) && IsKeyDown( DIK_RIGHT) );
}
bool KeyboardManager::movementDownLeft(){
    return ( IsKeyUp(DIK_UP) && IsKeyDown(DIK_DOWN) && IsKeyDown( DIK_LEFT) && IsKeyUp( DIK_RIGHT) );
}
bool KeyboardManager::movementLeft(){
    return ( IsKeyUp(DIK_UP)   && IsKeyUp(DIK_DOWN)   && IsKeyDown( DIK_LEFT) && IsKeyUp( DIK_RIGHT) ||
             IsKeyDown(DIK_UP) && IsKeyDown(DIK_DOWN) && IsKeyDown( DIK_LEFT) && IsKeyUp( DIK_RIGHT) );
}
bool KeyboardManager::movementUpLeft(){
    return ( IsKeyDown(DIK_UP) && IsKeyUp(DIK_DOWN) && IsKeyDown( DIK_LEFT) && IsKeyUp( DIK_RIGHT) );
}
