//CDInputManager.cpp	- see header for more info

//includes///////////////////////////////

#ifndef INITGUID
//#define INITGUID
#endif


#include <winsock2.h>
#include <windows.h>   // include important windows stuff
#include <windowsx.h> 
#include <mmsystem.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h> 
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <OBJBASE.H>

//#define DIRECTINPUT_VERSION 0x0600
//#include <dinput.h> // include directinput

#include "CDInputManager.h"
#include "CGraphicSystem.h"
#include "Assert.h"



///////////////////////////////////////////////////
//*****************globals*************************
///////////////////////////////////////////////////

extern HWND main_window_handle; // globally track main window
extern HINSTANCE hinstance_app; // globally track hinstance






///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//CONSTRUCTOR/DESTRUCTOR//////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

CDInputManager::CDInputManager()
{
//	LOGFUNC("CDInputer Manager Create");

	//////////////////////////////////////////////////////////
	/*
	This constructor will do everything to Init DInput. Create
	The interface, get the devices, etc. No other setup functions
	are required
															*/
	//////////////////////////////////////////////////////////

	//First set everything to null
	
	lpdi	=		NULL;			//used to point to come

	//devices

	lpdikey =		NULL;			//keyboard interface





	//create the main DirectInput Object
	
	if(FAILED(DirectInputCreate(hinstance_app,					//this is a global reference to our app
								DIRECTINPUT_VERSION,			//this is the latest version of DInput
								&lpdi,							//save it to lpdi
								NULL)))							//ignore for now - NULL
	{
		Assert(false,"Error Creating Direct Input Object")
		return;
	}


	//create the keyboard device

	if(FAILED(lpdi->CreateDevice(GUID_SysKeyboard, &lpdikey, NULL)))
	{
		Assert(false,"Error creating keyboard device")
		return;
	}
	
	//create the mouse device

	if(FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdimouse, NULL)))
	{
		Assert(false,"Error creating mouse device")
		return;
	}

	
	//set the cooperation level

	if(FAILED(lpdikey->SetCooperativeLevel(main_window_handle, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
	{
		Assert(false,"Error setting keyboard Co-Op level")
		return ;
	}

	//now the mouse

	if(FAILED(lpdimouse->SetCooperativeLevel(main_window_handle, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
	{
		Assert(false,"Error setting mouse Co-Op level")
		return ;
	}



	
	//set the data format. We will use the generic keyboard one

	if(FAILED(lpdikey->SetDataFormat(&c_dfDIKeyboard)))
	{
		Assert(false,"Error setting Keyboard Data Format")
		return;
	}
	
	//now mouse

	if(FAILED(lpdimouse->SetDataFormat(&c_dfDIMouse)))
	{
		Assert(false,"Error setting mouse Data Format")
		return;
	}


	//now we finally aquire keyboard

	if(FAILED(lpdikey->Acquire()))
	{
		Assert(false,"Could not aquire keyboard")
		return;
	}

	//and now the mouse...

	if(FAILED(lpdimouse->Acquire()))
	{
//		Assert(false,"Could not aquire mouse")
		return;
	}	

	mousePoint.x=0;//g_DDManager.SCREEN_WIDTH/2;
	mousePoint.y=0;//g_DDManager.SCREEN_HEIGHT/2;

	clearText();

	for(int i=DIK_1; i <= DIK_SLASH; i++)
	{
		int tmpI = i - DIK_1;
		TextCommands[tmpI].Init(i);
	}

	SpaceCommand.Init(DIK_SPACE);




}

CDInputManager::~CDInputManager()
{
	//free up everything, pretty simple

	if(lpdikey)
		lpdikey->Unacquire();

	if(lpdimouse)
		lpdimouse->Unacquire();

	if(lpdikey)
		lpdikey->Release();

	if(lpdimouse)
		lpdimouse->Release();

	if(lpdi)
		lpdi->Release();

	



}


///////////////////////////////////////////////////////////////////////////////
//Methods for retrieving states////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void CDInputManager::GetKeyboardInput()
{
	///////////////////////////////////////////
	/*
		This will see what key is being pressed,
		and store it in Keystate. 
											 */
	///////////////////////////////////////////

	if(FAILED(lpdikey->GetDeviceState(sizeof(Keystate), (LPVOID)Keystate)))
	{
		Assert(false,"Error reading keyboard")
		return;
	}

}


void CDInputManager::GetMouseInput()
{
	//////////////////////////////////////////////
	/*
		This will see where the mosue is
		and what buttons are down. We can
		also get the wheel position (z button)
												*/
	//////////////////////////////////////////////

	if(FAILED(lpdimouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&Mousestate)))
	{
		Assert(false,"Error reading mouse")
		return;
	}

	mousePoint.x+=Mousestate.lX;
	mousePoint.y+=Mousestate.lY;

	//mousePoint.x = realMousePoint.x + offSet.x;
	//mousePoint.y = realMousePoint.y + offSet.y;

	

	//BOO

	if(mousePoint.x < -20)
		mousePoint.x = -20;

	if(mousePoint.y < -20)
		mousePoint.y = -20;
}

//////////////////////////////////////////////////////////////////////////////
//Putting them all together///////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

void CDInputManager::GetInput()
{
	/////////////////////////////////////////////
	/*
		This will call all of the get Input
		functions.
											   */
	/////////////////////////////////////////////

	GetKeyboardInput();
	GetMouseInput();

}


////////////////////////////////////////////////////////////

bool CDInputManager::LeftMouseDown()
{
	if(Mousestate.rgbButtons[0])
	{
		return true;		
	}
	

	return false;

	
}


bool CDInputManager::RightMouseDown()
{
	

	if(Mousestate.rgbButtons[1])
	{
		return true;		
	}	

	return false;

}


void CDInputManager::offsetMouse(POINT p)
{
	offSet.x = p.x;
	offSet.y = p.y;
}

void CDInputManager::clearText()
{
	memset(&textBuffer, ' ', 250);
	nextchar=0;
}


void CDInputManager::AddChar(DWORD c)
{

	//char tmp[2];
	//scan2ascii(c, (USHORT*)&tmp);


	if(c==DIK_BACK || c==DIK_BACKSPACE)
	{
		if(nextchar > 0)
			textBuffer[--nextchar]=' ';
	}
	else if(c==DIK_SPACE)
	{
		textBuffer[nextchar++]=' ';

	}
	else if(c==DIK_TAB || c==DIK_LSHIFT || c==DIK_RSHIFT || c==DIK_RETURN || c==DIK_RMENU || c==DIK_RCONTROL || c==DIK_LCONTROL || c==DIK_LMENU)
	{

	}
	else
	{
		scan2ascii(c, (USHORT*)&textBuffer[nextchar++]);
	}

}



int CDInputManager::scan2ascii(DWORD scancode, USHORT* result)
{
	static HKL layout=GetKeyboardLayout(0);
	static UCHAR State[256];

	if (GetKeyboardState(State)==FALSE)
		return 0;
	
	UINT vk=MapVirtualKeyEx(scancode,1,layout);
	
	return ToAsciiEx(vk,scancode,State,result,0,layout);
}


STRINGC CDInputManager::getText()
{

	for(int i=DIK_1; i <= DIK_SLASH; i++)
	{
		int tmpI = i - DIK_1;
		if(TextCommands[tmpI].isActive())
		{
			AddChar(i);
		}
	}

	if(SpaceCommand.isActive())
	{
		AddChar(DIK_SPACE);
	}

	


	if(nextchar > 250)
		nextchar=0;


	return STRINGC(textBuffer);
	

}
