//Copyright (C) 2007 SiegeLord
//See ReadMe.txt and License.txt for copying information

#include "../include/engine/input.h"

//The Key States:
//-1 = just released
//0 = up
//1 = down
//2 = just pressed

int g_nKeyStates[KEY_MAX];
int g_nMouseStates[3];

int g_nMouseX;
int g_nMouseY;
int g_nMouseDZ;

bool g_bMouseLocked = false;//locked by gui or some such, just means that mouse position is not updated anymore

void mouse_call(int f)
{
	if(!f & MOUSE_FLAG_LEFT_DOWN)
	{
		switch(g_nMouseStates[0])
		{
		case -1:
			g_nMouseStates[0] = 2;
			break;
		case 0:
			g_nMouseStates[0] = 2;
			break;
		case 1:
			//g_nKeyStates[ii] = 1;
			break;
		case 2:
			g_nMouseStates[0] = 1;
			break;
		default://init purposes
			g_nMouseStates[0] = 0;
			break;
		}
	}
	if(!f & MOUSE_FLAG_LEFT_UP)
	{
		switch(g_nMouseStates[0])
		{
		case -1:
			g_nMouseStates[0] = 0;
			break;
		case 0:
			//g_nKeyStates[ii] = 0;
			break;
		case 1:
			g_nMouseStates[0] = -1;
			break;
		case 2:
			g_nMouseStates[0] = -1;
			break;
		default://init purposes
			g_nMouseStates[0] = 0;
			break;
		}
	}

	if(!f & MOUSE_FLAG_RIGHT_DOWN)
	{
		switch(g_nMouseStates[0])
		{
		case -1:
			g_nMouseStates[0] = 2;
			break;
		case 0:
			g_nMouseStates[0] = 2;
			break;
		case 1:
			//g_nKeyStates[ii] = 1;
			break;
		case 2:
			g_nMouseStates[0] = 1;
			break;
		default://init purposes
			g_nMouseStates[0] = 0;
			break;
		}
	}
	if(!f & MOUSE_FLAG_RIGHT_UP)
	{
		switch(g_nMouseStates[0])
		{
		case -1:
			g_nMouseStates[0] = 0;
			break;
		case 0:
			//g_nKeyStates[ii] = 0;
			break;
		case 1:
			g_nMouseStates[0] = -1;
			break;
		case 2:
			g_nMouseStates[0] = -1;
			break;
		default://init purposes
			g_nMouseStates[0] = 0;
			break;
		}
	}
}
END_OF_FUNCTION(mouse_call)



void InitInput()
{
	LOCK_FUNCTION(mouse_call);
	mouse_callback = mouse_call;
	install_keyboard();
	install_mouse();
	UpdateInput();
}

//updates input, and stores the new key states
void UpdateInput()
{
	static int mouse_x, mouse_y;

	poll_mouse();
	poll_keyboard();

	int pos = mouse_pos;

	int mx = pos >> 16;
	int my = pos & 0x0000ffff;

	if(mx != mouse_x || my != mouse_y)
	{
		g_bMouseLocked = false;
	}

	mouse_x = mx;
	mouse_y = my;

	if(!g_bMouseLocked)
	{
		g_nMouseX = mouse_x;
		g_nMouseY = mouse_y;
	}

	g_nMouseDZ = mouse_z;

	position_mouse_z(0);

	int buttons = mouse_b;

	//mouse stuff
	for(int ii = 0; ii < 3; ii++)
	{
		int n = 1 << ii;
		if(buttons & n)
		{
			switch(g_nMouseStates[ii])
			{
			case -1:
				g_nMouseStates[ii] = 2;
				break;
			case 0:
				g_nMouseStates[ii] = 2;
				break;
			case 1:
				//g_nKeyStates[ii] = 1;
				break;
			case 2:
				g_nMouseStates[ii] = 1;
				break;
			default://init purposes
				g_nMouseStates[ii] = 0;
				break;
			}
		}
		else
		{
			switch(g_nMouseStates[ii])
			{
			case -1:
				g_nMouseStates[ii] = 0;
				break;
			case 0:
				//g_nKeyStates[ii] = 0;
				break;
			case 1:
				g_nMouseStates[ii] = -1;
				break;
			case 2:
				g_nMouseStates[ii] = -1;
				break;
			default://init purposes
				g_nMouseStates[ii] = 0;
				break;
			}
		}
	}

	//keyboard stuff
	for(int ii = 0; ii < KEY_MAX; ii++)
	{
		if(key[ii])
		{
			switch(g_nKeyStates[ii])
			{
			case -1:
				g_nKeyStates[ii] = 2;
				break;
			case 0:
				g_nKeyStates[ii] = 2;
				break;
			case 1:
				//g_nKeyStates[ii] = 1;
				break;
			case 2:
				g_nKeyStates[ii] = 1;
				break;
			default://init purposes
				g_nKeyStates[ii] = 0;
				break;
			}
		}
		else
		{
			switch(g_nKeyStates[ii])
			{
			case -1:
				g_nKeyStates[ii] = 0;
				break;
			case 0:
				//g_nKeyStates[ii] = 0;
				break;
			case 1:
				g_nKeyStates[ii] = -1;
				break;
			case 2:
				g_nKeyStates[ii] = -1;
				break;
			default://init purposes
				g_nKeyStates[ii] = 0;
				break;
			}
		}
	}
}

//Again, for reference:
//-1 = just released
//0 = up
//1 = down
//2 = just pressed

bool IsKeyJustPressed(unsigned char n)
{
	return g_nKeyStates[n] == 2;
}
bool IsKeyDown(unsigned char n)
{
	return g_nKeyStates[n] > 0;
}
bool IsKeyJustReleased(unsigned char n)
{
	return g_nKeyStates[n] == -1;
}
bool IsKeyUp(unsigned char n)
{
	return g_nKeyStates[n] < 1;
}

//mouse stuff
bool IsMKeyJustPressed(unsigned char n)
{
	return g_nMouseStates[n] == 2;
}
bool IsMKeyDown(unsigned char n)
{
	return g_nMouseStates[n] > 0;
}
bool IsMKeyJustReleased(unsigned char n)
{
	return g_nMouseStates[n] == -1;
}
bool IsMKeyUp(unsigned char n)
{
	return g_nMouseStates[n] < 1;
}

bool IsCtrlDown()
{
	return IsKeyDown(KEY_LCONTROL) || IsKeyDown(KEY_RCONTROL);
}

bool IsShiftDown()
{
	return IsKeyDown(KEY_LSHIFT) || IsKeyDown(KEY_RSHIFT);
}

bool IsAltDown()
{
	return IsKeyDown(KEY_ALT) || IsKeyDown(KEY_ALTGR);
}
