#include "osdepend.h"
#include "driver.h"
#include "keycode.h"

#define DEBUG(x)	{ x }


extern int beos_key_pressed(int keycode);
extern int beos_joystick_poll(void);
extern int beos_joystick_digital(int nr, int what);
extern void beos_get_mouse(int *deltax, int *deltay);
extern char key[];


void my_textout (char *buf, int x, int y);

int use_mouse;
int joystick;

extern int		MAX_JOYSTICKS;

struct KeyboardInfo keylist[] =
{
	{ "A",			eKey_A,				KEYCODE_A },
	{ "B",			eKey_B,				KEYCODE_B },
	{ "C",			eKey_C,				KEYCODE_C },
	{ "D",			eKey_D,				KEYCODE_D },
	{ "E",			eKey_E,				KEYCODE_E },
	{ "F",			eKey_F,				KEYCODE_F },
	{ "G",			eKey_G,				KEYCODE_G },
	{ "H",			eKey_H,				KEYCODE_H },
	{ "I",			eKey_I,				KEYCODE_I },
	{ "J",			eKey_J,				KEYCODE_J },
	{ "K",			eKey_K,				KEYCODE_K },
	{ "L",			eKey_L,				KEYCODE_L },
	{ "M",			eKey_M,				KEYCODE_M },
	{ "N",			eKey_N,				KEYCODE_N },
	{ "O",			eKey_O,				KEYCODE_O },
	{ "P",			eKey_P,				KEYCODE_P },
	{ "Q",			eKey_Q,				KEYCODE_Q },
	{ "R",			eKey_R,				KEYCODE_R },
	{ "S",			eKey_S,				KEYCODE_S },
	{ "T",			eKey_T,				KEYCODE_T },
	{ "U",			eKey_U,				KEYCODE_U },
	{ "V",			eKey_V,				KEYCODE_V },
	{ "W",			eKey_W,				KEYCODE_W },
	{ "X",			eKey_X,				KEYCODE_X },
	{ "Y",			eKey_Y,				KEYCODE_Y },
	{ "Z",			eKey_Z,				KEYCODE_Z },
	{ "0",			eKey_0,				KEYCODE_0 },
	{ "1",			eKey_1,				KEYCODE_1 },
	{ "2",			eKey_2,				KEYCODE_2 },
	{ "3",			eKey_3,				KEYCODE_3 },
	{ "4",			eKey_4,				KEYCODE_4 },
	{ "5",			eKey_5,				KEYCODE_5 },
	{ "6",			eKey_6,				KEYCODE_6 },
	{ "7",			eKey_7,				KEYCODE_7 },
	{ "8",			eKey_8,				KEYCODE_8 },
	{ "9",			eKey_9,				KEYCODE_9 },
	{ "0 PAD",		eKey_0_Pad,			KEYCODE_0_PAD },
	{ "1 PAD",		eKey_1_Pad,			KEYCODE_1_PAD },
	{ "2 PAD",		eKey_2_Pad,			KEYCODE_2_PAD },
	{ "3 PAD",		eKey_3_Pad,			KEYCODE_3_PAD },
	{ "4 PAD",		eKey_4_Pad,			KEYCODE_4_PAD },
	{ "5 PAD",		eKey_5_Pad,			KEYCODE_5_PAD },
	{ "6 PAD",		eKey_6_Pad,			KEYCODE_6_PAD },
	{ "7 PAD",		eKey_7_Pad,			KEYCODE_7_PAD },
	{ "8 PAD",		eKey_8_Pad,			KEYCODE_8_PAD },
	{ "9 PAD",		eKey_9_Pad,			KEYCODE_9_PAD },
	{ "F1",			eKey_F1,			KEYCODE_F1 },
	{ "F2",			eKey_F2,			KEYCODE_F2 },
	{ "F3",			eKey_F3,			KEYCODE_F3 },
	{ "F4",			eKey_F4,			KEYCODE_F4 },
	{ "F5",			eKey_F5,			KEYCODE_F5 },
	{ "F6",			eKey_F6,			KEYCODE_F6 },
	{ "F7",			eKey_F7,			KEYCODE_F7 },
	{ "F8",			eKey_F8,			KEYCODE_F8 },
	{ "F9",			eKey_F9,			KEYCODE_F9 },
	{ "F10",		eKey_F10,			KEYCODE_F10 },
	{ "F11",		eKey_F11,			KEYCODE_F11 },
	{ "F12",		eKey_F12,			KEYCODE_F12 },
	{ "ESC",		eKey_Escape,		KEYCODE_ESC },
	{ "~",			eKey_Tilde,			KEYCODE_TILDE },
	{ "-",			eKey_Minus,			KEYCODE_OTHER },
	{ "=",			eKey_Equals,		KEYCODE_OTHER },
	{ "BKSPACE",	eKey_Backspace,		KEYCODE_BACKSPACE },
	{ "TAB",		eKey_Tab,			KEYCODE_TAB },
	{ "[",			eKey_OpenBrace,		KEYCODE_OTHER },
	{ "]",			eKey_CloseBrace,	KEYCODE_OTHER },
	{ "ENTER",		eKey_Enter,			KEYCODE_ENTER },
	{ ";",			eKey_SemiColon,		KEYCODE_OTHER },
	{ ":",			eKey_Colon,			KEYCODE_OTHER },
	{ "\\",			eKey_Backslash,		KEYCODE_OTHER },
	{ "<",			eKey_LessThan,		KEYCODE_OTHER },
	{ ",",			eKey_Comma,			KEYCODE_OTHER },
	{ ".",			eKey_Period,		KEYCODE_OTHER },
	{ "/",			eKey_Slash,			KEYCODE_OTHER },
	{ "SPACE",		eKey_Space,			KEYCODE_SPACE },
	{ "INS",		eKey_Insert,		KEYCODE_INSERT },
	{ "DEL",		eKey_Del,			KEYCODE_DEL },
	{ "HOME",		eKey_Home,			KEYCODE_HOME },
	{ "END",		eKey_End,			KEYCODE_END },
	{ "PGUP",		eKey_PageUp,		KEYCODE_PGUP },
	{ "PGDN",		eKey_PageDown,		KEYCODE_PGDN },
	{ "LEFT",		eKey_Left,			KEYCODE_LEFT },
	{ "RIGHT",		eKey_Right,			KEYCODE_RIGHT },
	{ "UP",			eKey_Up,			KEYCODE_UP },
	{ "DOWN",		eKey_Down,			KEYCODE_DOWN },
	{ "/ PAD",		eKey_Slash_Pad,		KEYCODE_OTHER },
	{ "* PAD",		eKey_Asterisk_Pad,	KEYCODE_OTHER },
	{ "- PAD",		eKey_Minus_Pad,		KEYCODE_OTHER },
	{ "+ PAD",		eKey_Plus_Pad,		KEYCODE_OTHER },
	{ ". PAD",		eKey_Del_Pad,		KEYCODE_OTHER },
	{ "ENTER PAD",	eKey_Enter_Pad,		KEYCODE_OTHER },
	{ "PRTSCR",		eKey_PrintScreen,	KEYCODE_OTHER },
	{ "PAUSE",		eKey_Pause,			KEYCODE_OTHER },
	{ "LSHIFT",		eKey_LeftShift,		KEYCODE_LSHIFT },
	{ "RSHIFT",		eKey_RightShift,	KEYCODE_RSHIFT },
	{ "LCTRL",		eKey_LeftControl,	KEYCODE_LCONTROL },
	{ "RCTRL",		eKey_RightControl,	KEYCODE_RCONTROL },
	{ "ALT",		eKey_Alt,			KEYCODE_LALT },
	{ "ALTGR",		eKey_AltRight,		KEYCODE_RALT },
	{ "LWIN",		eKey_WinLeft,		KEYCODE_OTHER },
	{ "RWIN",		eKey_WinRight,		KEYCODE_OTHER },
	{ "MENU",		eKey_Menu,			KEYCODE_OTHER },
	{ "SCRLOCK",	eKey_ScrLock,		KEYCODE_OTHER },
	{ "NUMLOCK",	eKey_NumLock,		KEYCODE_OTHER },
	{ "CAPSLOCK",	eKey_CapsLock,		KEYCODE_OTHER },
	{ 0, 0, 0 }	/* end of table */
};

/* return a list of all available keys */
const struct KeyboardInfo *osd_get_key_list(void)
{
	return keylist;
}

void osd_customize_inputport_defaults(struct ipd *defaults)
{
//	if (use_hotrod)
//	{
//		while (defaults->type != IPT_END)
//		{
//			if (defaults->keyboard == KEYCODE_UP) defaults->keyboard = eKey_8_Pad;
//			if (defaults->keyboard == KEYCODE_DOWN) defaults->keyboard = eKey_2_Pad;
//			if (defaults->keyboard == KEYCODE_LEFT) defaults->keyboard = eKey_4_Pad;
//			if (defaults->keyboard == KEYCODE_RIGHT) defaults->keyboard = eKey_6_Pad;
//			if (defaults->type == IPT_UI_SELECT) defaults->keyboard = eKey_LeftControl;
//			if (defaults->type == (IPT_JOYSTICKRIGHT_UP    | IPF_PLAYER1)) defaults->keyboard = eKey_R;
//			if (defaults->type == (IPT_JOYSTICKRIGHT_DOWN  | IPF_PLAYER1)) defaults->keyboard = eKey_F;
//			if (defaults->type == (IPT_JOYSTICKRIGHT_LEFT  | IPF_PLAYER1)) defaults->keyboard = eKey_D;
//			if (defaults->type == (IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER1)) defaults->keyboard = eKey_G;
//			if (defaults->type == (IPT_JOYSTICKLEFT_UP     | IPF_PLAYER1)) defaults->keyboard = eKey_8_Pad;
//			if (defaults->type == (IPT_JOYSTICKLEFT_DOWN   | IPF_PLAYER1)) defaults->keyboard = eKey_2_Pad;
//			if (defaults->type == (IPT_JOYSTICKLEFT_LEFT   | IPF_PLAYER1)) defaults->keyboard = eKey_4_Pad;
//			if (defaults->type == (IPT_JOYSTICKLEFT_RIGHT  | IPF_PLAYER1)) defaults->keyboard = eKey_6_Pad;
//
//			defaults++;
//		}
//	}
}

int osd_is_key_pressed(int keycode)
{
	if (keycode >= eKey_Max) return 0;

	if (keycode == eKey_Pause)
	{
		static int pressed,counter;
		int res;

		res = beos_key_pressed(eKey_Pause) ^ pressed;
		if (res)
		{
			if (counter > 0)
			{
				if (--counter == 0)
					pressed = beos_key_pressed(eKey_Pause);
			}
			else counter = 10;
		}

		return res;
	}

	return beos_key_pressed(keycode);
}


int osd_wait_keypress(void)
{
//	clear_keybuf();
//	return readkey() >> 8;
	return 0;
}

/*
  limits:
  - 4 joysticks
  - 15 sticks on each joystick
  - 63 buttons on each joystick

  - 256 total inputs
*/
#define JOYCODE(joy,stick,axis_or_button,dir) \
		((((dir)&0x03)<<14)|(((axis_or_button)&0x3f)<<8)|(((stick)&0x1f)<<3)|(((joy)&0x07)<<0))

#define GET_JOYCODE_JOY(code) (((code)>>0)&0x07)
#define GET_JOYCODE_STICK(code) (((code)>>3)&0x1f)
#define GET_JOYCODE_AXIS(code) (((code)>>8)&0x3f)
#define GET_JOYCODE_BUTTON(code) GET_JOYCODE_AXIS(code)
#define GET_JOYCODE_DIR(code) (((code)>>14)&0x03)

#define MAX_JOY 256
#define MAX_JOY_NAME_LEN 20

static struct JoystickInfo joylist[MAX_JOY] =
{
	/* will be filled later */
	{ 0, 0, 0 }	/* end of table */
};

static char joynames[MAX_JOY_NAME_LEN+1][MAX_JOY];	/* will be used to store names for the above */


static int joyequiv[][2] =
{
	{ JOYCODE(1,1,1,1),	JOYCODE_1_LEFT },
	{ JOYCODE(1,1,1,2),	JOYCODE_1_RIGHT },
	{ JOYCODE(1,1,2,1),	JOYCODE_1_UP },
	{ JOYCODE(1,1,2,2),	JOYCODE_1_DOWN },
	{ JOYCODE(1,0,1,0),	JOYCODE_1_BUTTON1 },
	{ JOYCODE(1,0,2,0),	JOYCODE_1_BUTTON2 },
	{ JOYCODE(1,0,3,0),	JOYCODE_1_BUTTON3 },
	{ JOYCODE(1,0,4,0),	JOYCODE_1_BUTTON4 },
	{ JOYCODE(1,0,5,0),	JOYCODE_1_BUTTON5 },
	{ JOYCODE(1,0,6,0),	JOYCODE_1_BUTTON6 },
	{ JOYCODE(2,1,1,1),	JOYCODE_2_LEFT },
	{ JOYCODE(2,1,1,2),	JOYCODE_2_RIGHT },
	{ JOYCODE(2,1,2,1),	JOYCODE_2_UP },
	{ JOYCODE(2,1,2,2),	JOYCODE_2_DOWN },
	{ JOYCODE(2,0,1,0),	JOYCODE_2_BUTTON1 },
	{ JOYCODE(2,0,2,0),	JOYCODE_2_BUTTON2 },
	{ JOYCODE(2,0,3,0),	JOYCODE_2_BUTTON3 },
	{ JOYCODE(2,0,4,0),	JOYCODE_2_BUTTON4 },
	{ JOYCODE(2,0,5,0),	JOYCODE_2_BUTTON5 },
	{ JOYCODE(2,0,6,0),	JOYCODE_2_BUTTON6 },
	{ JOYCODE(3,1,1,1),	JOYCODE_3_LEFT },
	{ JOYCODE(3,1,1,2),	JOYCODE_3_RIGHT },
	{ JOYCODE(3,1,2,1),	JOYCODE_3_UP },
	{ JOYCODE(3,1,2,2),	JOYCODE_3_DOWN },
	{ JOYCODE(3,0,1,0),	JOYCODE_3_BUTTON1 },
	{ JOYCODE(3,0,2,0),	JOYCODE_3_BUTTON2 },
	{ JOYCODE(3,0,3,0),	JOYCODE_3_BUTTON3 },
	{ JOYCODE(3,0,4,0),	JOYCODE_3_BUTTON4 },
	{ JOYCODE(3,0,5,0),	JOYCODE_3_BUTTON5 },
	{ JOYCODE(3,0,6,0),	JOYCODE_3_BUTTON6 },
	{ JOYCODE(4,1,1,1),	JOYCODE_4_LEFT },
	{ JOYCODE(4,1,1,2),	JOYCODE_4_RIGHT },
	{ JOYCODE(4,1,2,1),	JOYCODE_4_UP },
	{ JOYCODE(4,1,2,2),	JOYCODE_4_DOWN },
	{ JOYCODE(4,0,1,0),	JOYCODE_4_BUTTON1 },
	{ JOYCODE(4,0,2,0),	JOYCODE_4_BUTTON2 },
	{ JOYCODE(4,0,3,0),	JOYCODE_4_BUTTON3 },
	{ JOYCODE(4,0,4,0),	JOYCODE_4_BUTTON4 },
	{ JOYCODE(4,0,5,0),	JOYCODE_4_BUTTON5 },
	{ JOYCODE(4,0,6,0),	JOYCODE_4_BUTTON6 },
	{ 0,0 }
};


static void init_joy_list(void)
{
//	int tot,i,j,k;
//	char buf[256];
//
//	tot = 0;
//	for (i = 0;i < MAX_JOYSTICKS;i++)
//	{
//		for (j = 0;j < joy[i].num_sticks;j++)
//		{
//			for (k = 0;k < joy[i].stick[j].num_axis;k++)
//			{
//				sprintf(buf,"J%d %s %s -",i+1,joy[i].stick[j].name,joy[i].stick[j].axis[k].name);
//				strncpy(joynames[tot],buf,MAX_JOY_NAME_LEN);
//				joynames[tot][MAX_JOY_NAME_LEN] = 0;
//				joylist[tot].name = joynames[tot];
//				joylist[tot].code = JOYCODE(i+1,j+1,k+1,1);
//				tot++;
//
//				sprintf(buf,"J%d %s %s +",i+1,joy[i].stick[j].name,joy[i].stick[j].axis[k].name);
//				strncpy(joynames[tot],buf,MAX_JOY_NAME_LEN);
//				joynames[tot][MAX_JOY_NAME_LEN] = 0;
//				joylist[tot].name = joynames[tot];
//				joylist[tot].code = JOYCODE(i+1,j+1,k+1,2);
//				tot++;
//			}
//		}
//		for (j = 0;j < joy[i].num_buttons;j++)
//		{
//			sprintf(buf,"J%d %s",i+1,joy[i].button[j].name);
//			strncpy(joynames[tot],buf,MAX_JOY_NAME_LEN);
//			joynames[tot][MAX_JOY_NAME_LEN] = 0;
//			joylist[tot].name = joynames[tot];
//			joylist[tot].code = JOYCODE(i+1,0,j+1,0);
//			tot++;
//		}
//	}
//
//	/* terminate array */
//	joylist[tot].name = 0;
//	joylist[tot].code = 0;
//	joylist[tot].standardcode = 0;
//
//	/* fill in equivalences */
//	for (i = 0;i < tot;i++)
//	{
//		joylist[i].standardcode = JOYCODE_OTHER;
//
//		j = 0;
//		while (joyequiv[j][0] != 0)
//		{
//			if (joyequiv[j][0] == joylist[i].code)
//			{
//				joylist[i].standardcode = joyequiv[j][1];
//				break;
//			}
//			j++;
//		}
//	}
}


/* return a list of all available joys */
const struct JoystickInfo *osd_get_joy_list(void)
{
	return joylist;
}


int osd_is_joy_pressed(int joycode)
{
//	int joy_num,stick;
//
//
//	joy_num = GET_JOYCODE_JOY(joycode);
//
//	/* do we have as many sticks? */
//	if (joy_num == 0 || joy_num > MAX_JOYSTICKS)
//		return 0;
//	joy_num--;
//
//	if (joy_num == 0)
//	{
//		/* special case for mouse buttons */
//		switch (joycode)
//		{
//			case JOYCODE(1,0,1,0):
//				if (mouse_b & 1) return 1; break;
//			case JOYCODE(1,0,2,0):
//				if (mouse_b & 2) return 1; break;
//			case JOYCODE(1,0,3,0):
//				if (mouse_b & 4) return 1; break;
//			case JOYCODE(1,0,4,0): /* any mouse button */
//				if (mouse_b) return 1; break;
//		}
//	}
//
//	stick = GET_JOYCODE_STICK(joycode);
//
//	if (stick == 0)
//	{
//		/* buttons */
//		int button;
//
//		button = GET_JOYCODE_BUTTON(joycode);
//		if (button == 0 || button > joy[joy_num].num_buttons)
//			return 0;
//		button--;
//
//		return joy[joy_num].button[button].b;
//	}
//	else
//	{
//		/* sticks */
//		int axis,dir;
//
//		if (stick > joy[joy_num].num_sticks)
//			return 0;
//		stick--;
//
//		axis = GET_JOYCODE_AXIS(joycode);
//		dir = GET_JOYCODE_DIR(joycode);
//
//		if (axis == 0 || axis > joy[joy_num].stick[stick].num_axis)
//			return 0;
//		axis--;
//
//		switch (dir)
//		{
//			case 1:
//				return joy[joy_num].stick[stick].axis[axis].d1; break;
//			case 2:
//				return joy[joy_num].stick[stick].axis[axis].d2; break;
//			default:
//				return 0; break;
//		}
//	}

	return 0;
}

void osd_poll_joysticks(void)
{
	beos_joystick_poll();
}

/* return a value in the range -128 .. 128 (yes, 128, not 127) */
void osd_analogjoy_read(int player,int *analog_x, int *analog_y)
{
#if 0
	*analog_x = *analog_y = 0;

	/* is there an analog joystick at all? */
	if (player+1 > num_joysticks || joystick == JOY_TYPE_NONE)
		return;

	*analog_x = joy[player].stick[0].axis[0].pos;
	*analog_y = joy[player].stick[0].axis[1].pos;
#endif	// 0
}


static int calibration_target;

int osd_joystick_needs_calibration (void)
{
#if 0
	/* This could be improved, but unfortunately, this version of Allegro */
	/* lacks a flag which tells if a joystick is calibrationable, it only  */
	/* remembers whether calibration is yet to be done. */
	if (joystick == JOY_TYPE_NONE)
		return 0;
	else
#endif	// 0
		return 1;
}


void osd_joystick_start_calibration (void)
{
#if 0
	/* reinitialises the joystick. */
	remove_joystick();
	install_joystick (joystick);
	calibration_target = 0;
#endif	// 0
}

char *osd_joystick_calibrate_next (void)
{
#if 0
	while (calibration_target < num_joysticks)
	{
		if (joy[calibration_target].flags & JOYFLAG_CALIBRATE)
			return (calibrate_joystick_name (calibration_target));
		else
			calibration_target++;
	}
#endif	// 0
	return 0;
}

void osd_joystick_calibrate (void)
{
#if 0
	calibrate_joystick (calibration_target);
#endif	// 0
}

void osd_joystick_end_calibration (void)
{
#if 0
	save_joystick_data(0);
#endif	// 0
}


void osd_trak_read(int player,int *deltax,int *deltay)
{
	if (player != 0 || use_mouse == 0)
		*deltax = *deltay = 0;
	else /*get_mouse_mickeys(deltax,deltay);*/
		beos_get_mouse(deltax, deltay);
}

void beos_init_input(void)
{
	init_joy_list();
}

void osd_led_w(int led,int on) {
}

