#include "main.h"
#include <lua.h>
#include <lauxlib.h>
#include "input.h"
#include "gfx.h"

static const struct {
	SDLKey key;
	const char *name;
} keys[] = {
	{SDLK_BACKSPACE,"BACKSPACE"},
	{SDLK_TAB,"TAB"},
	{SDLK_CLEAR,"CLR"},
	{SDLK_CLEAR,"CLEAR"},
	{SDLK_RETURN,"ENTER"},
	{SDLK_RETURN,"RETURN"},
	{SDLK_PAUSE,"PAUSE"},
	{SDLK_ESCAPE,"ESC"},
	{SDLK_ESCAPE,"ESCAPE"},
	{SDLK_SPACE,"SPACE"},
	{SDLK_SPACE,"SPACEBAR"},
	{SDLK_EXCLAIM,"EXCLAIM"},
	{SDLK_EXCLAIM,"EXCLAMATION"},
	{SDLK_EXCLAIM,"!"},
	{SDLK_QUOTEDBL,"QUOTEDBL"},
	{SDLK_QUOTEDBL,"DOUBLEQUOTE"},
	{SDLK_QUOTEDBL,"\""},
	{SDLK_HASH,"HASH"},
	{SDLK_DOLLAR,"DOLLAR"},
	{SDLK_DOLLAR,"$"},
	{SDLK_AMPERSAND,"AMP"},
	{SDLK_AMPERSAND,"AMPERSAND"},
	{SDLK_AMPERSAND,"ET"},
	{SDLK_AMPERSAND,"&"},
	{SDLK_QUOTE,"QUOTE"},
	{SDLK_QUOTE,"SINGLEQUOTE"},
	{SDLK_QUOTE,"'"},
	{SDLK_LEFTPAREN,"LEFTPAREN"},
	{SDLK_LEFTPAREN,"OPENPAREN"},
	{SDLK_LEFTPAREN,"("},
	{SDLK_RIGHTPAREN,"RIGHTPAREN"},
	{SDLK_RIGHTPAREN,"CLOSEPAREN"},
	{SDLK_RIGHTPAREN,")"},
	{SDLK_ASTERISK,"ASTERISK"},
	{SDLK_ASTERISK,"*"},
	{SDLK_PLUS,"PLUS"},
	{SDLK_PLUS,"+"},
	{SDLK_COMMA,"COMMA"},
	{SDLK_COMMA,","},
	{SDLK_MINUS,"MINUS"},
	{SDLK_MINUS,"-"},
	{SDLK_PERIOD,"PERIOD"},
	{SDLK_PERIOD,"."},
	{SDLK_SLASH,"SLASH"},
	{SDLK_SLASH,"FORWARDSLASH"},
	{SDLK_SLASH,"/"},
	{SDLK_0,"0"},
	{SDLK_1,"1"},
	{SDLK_2,"2"},
	{SDLK_3,"3"},
	{SDLK_4,"4"},
	{SDLK_5,"5"},
	{SDLK_6,"6"},
	{SDLK_7,"7"},
	{SDLK_8,"8"},
	{SDLK_9,"9"},
	{SDLK_COLON,"COLON"},
	{SDLK_COLON,":"},
	{SDLK_SEMICOLON,"SEMICOLON"},
	{SDLK_SEMICOLON,";"},
	{SDLK_LESS,"LESS"},
	{SDLK_LESS,"LESSTHAN"},
	{SDLK_LESS,"<"},
	{SDLK_EQUALS,"EQUALS"},
	{SDLK_EQUALS,"EQUAL"},
	{SDLK_EQUALS,"="},
	{SDLK_GREATER,"GREATER"},
	{SDLK_GREATER,"GREATERTHAN"},
	{SDLK_GREATER,">"},
	{SDLK_QUESTION,"QUESTION"},
	{SDLK_QUESTION,"QUESTIONMARK"},
	{SDLK_QUESTION,"?"},
	{SDLK_AT,"AT"},
	{SDLK_AT,"@"},
	{SDLK_LEFTBRACKET,"LEFTBRACKET"},
	{SDLK_LEFTBRACKET,"OPENBRACKET"},
	{SDLK_LEFTBRACKET,"["},
	{SDLK_BACKSLASH,"BACKSLASH"},
	{SDLK_BACKSLASH,"\\"},
	{SDLK_RIGHTBRACKET,"RIGHTBRACKET"},
	{SDLK_RIGHTBRACKET,"CLOSEBRACKET"},
	{SDLK_RIGHTBRACKET,"]"},
	{SDLK_CARET,"CARET"},
	{SDLK_CARET,"^"},
	{SDLK_UNDERSCORE,"UNDERSCORE"},
	{SDLK_UNDERSCORE,"_"},
	{SDLK_BACKQUOTE,"BACKQUOTE"},
	{SDLK_BACKQUOTE,"`"},
	{SDLK_a,"A"},
	{SDLK_b,"B"},
	{SDLK_c,"C"},
	{SDLK_d,"D"},
	{SDLK_e,"E"},
	{SDLK_f,"F"},
	{SDLK_g,"G"},
	{SDLK_h,"H"},
	{SDLK_i,"I"},
	{SDLK_j,"J"},
	{SDLK_k,"K"},
	{SDLK_l,"L"},
	{SDLK_m,"M"},
	{SDLK_n,"N"},
	{SDLK_o,"O"},
	{SDLK_p,"P"},
	{SDLK_q,"Q"},
	{SDLK_r,"R"},
	{SDLK_s,"S"},
	{SDLK_t,"T"},
	{SDLK_u,"U"},
	{SDLK_v,"V"},
	{SDLK_w,"W"},
	{SDLK_x,"X"},
	{SDLK_y,"Y"},
	{SDLK_z,"Z"},
	{SDLK_DELETE,"DEL"},
	{SDLK_DELETE,"DELETE"},
	{SDLK_KP0,"KP0"},
	{SDLK_KP1,"KP1"},
	{SDLK_KP2,"KP2"},
	{SDLK_KP3,"KP3"},
	{SDLK_KP4,"KP4"},
	{SDLK_KP5,"KP5"},
	{SDLK_KP6,"KP6"},
	{SDLK_KP7,"KP7"},
	{SDLK_KP8,"KP8"},
	{SDLK_KP9,"KP9"},
	{SDLK_KP_PERIOD,"KP_PERIOD"},
	{SDLK_KP_PERIOD,"KP."},
	{SDLK_KP_DIVIDE,"KP_DIVIDE"},
	{SDLK_KP_DIVIDE,"KP/"},
	{SDLK_KP_MULTIPLY,"KP_MULTIPLY"},
	{SDLK_KP_MULTIPLY,"KP*"},
	{SDLK_KP_MINUS,"KP_MINUS"},
	{SDLK_KP_MINUS,"KP-"},
	{SDLK_KP_PLUS,"KP_PLUS"},
	{SDLK_KP_PLUS,"KP+"},
	{SDLK_KP_ENTER,"KP_ENTER"},
	{SDLK_KP_EQUALS,"KP_EQUALS"},
	{SDLK_KP_EQUALS,"KP="},
	{SDLK_UP,"UP"},
	{SDLK_DOWN,"DOWN"},
	{SDLK_RIGHT,"RIGHT"},
	{SDLK_LEFT,"LEFT"},
	{SDLK_INSERT,"INS"},
	{SDLK_INSERT,"INSERT"},
	{SDLK_HOME,"HOME"},
	{SDLK_END,"END"},
	{SDLK_PAGEUP,"PGUP"},
	{SDLK_PAGEUP,"PAGEUP"},
	{SDLK_PAGEDOWN,"PGDN"},
	{SDLK_PAGEDOWN,"PAGEDOWN"},
	{SDLK_PAGEDOWN,"PGDOWN"},
	{SDLK_F1,"F1"},
	{SDLK_F2,"F2"},
	{SDLK_F3,"F3"},
	{SDLK_F4,"F4"},
	{SDLK_F5,"F5"},
	{SDLK_F6,"F6"},
	{SDLK_F7,"F7"},
	{SDLK_F8,"F8"},
	{SDLK_F9,"F9"},
	{SDLK_F10,"F10"},
	{SDLK_F11,"F11"},
	{SDLK_F12,"F12"},
	{SDLK_F13,"F13"},
	{SDLK_F14,"F14"},
	{SDLK_F15,"F15"},
	{SDLK_NUMLOCK,"NUMLOCK"},
	{SDLK_CAPSLOCK,"CAPSLOCK"},
	{SDLK_SCROLLOCK,"SCROLLOCK"},
	{SDLK_SCROLLOCK,"SCROLLLOCK"},
	{SDLK_RSHIFT,"RSHIFT"},
	{SDLK_RSHIFT,"RIGHTSHIFT"},
	{SDLK_LSHIFT,"LSHIFT"},
	{SDLK_LSHIFT,"LEFTSHIFT"},
	{SDLK_LSHIFT,"SHIFT"},
	{SDLK_RCTRL,"RCTRL"},
	{SDLK_RCTRL,"RIGHTCTRL"},
	{SDLK_LCTRL,"LCTRL"},
	{SDLK_LCTRL,"LEFTCTRL"},
	{SDLK_LCTRL,"CTRL"},
	{SDLK_RALT,"RALT"},
	{SDLK_RALT,"RIGHTALT"},
	{SDLK_LALT,"LALT"},
	{SDLK_LALT,"LEFTALT"},
	{SDLK_LALT,"ALT"},
	{SDLK_RMETA,"RMETA"},
	{SDLK_RMETA,"RIGHTMETA"},
	{SDLK_LMETA,"LMETA"},
	{SDLK_LMETA,"LEFTMETA"},
	{SDLK_LMETA,"META"},
	{SDLK_LSUPER,"LSUPER"},
	{SDLK_LSUPER,"LEFTSUPER"},
	{SDLK_LSUPER,"SUPER"},
	{SDLK_LSUPER,"LWINDOWS"},
	{SDLK_LSUPER,"LEFTWINDOWS"},
	{SDLK_LSUPER,"WINDOWS"},
	{SDLK_RSUPER,"RSUPER"},
	{SDLK_RSUPER,"RIGHTSUPER"},
	{SDLK_RSUPER,"RWINDOWS"},
	{SDLK_RSUPER,"RIGHTWINDOWS"},
	{SDLK_MODE,"MODE"},
	{SDLK_MODE,"ALTGR"},
	{SDLK_HELP,"HELP"},
	{SDLK_PRINT,"PRINT"},
	{SDLK_SYSREQ,"SYSREQ"},
	{SDLK_BREAK,"BREAK"},
	{SDLK_MENU,"MENU"},
	{SDLK_EURO,"EURO"},
	{SDLK_UNDO,"UNDO"},
	{0,NULL}
};

void Lua_ReadConfig(void)
{
	// Initialize Lua state
	Uint32 i = 0;
	lua_State *L = luaL_newstate();

	// Add the BTN table
	lua_newtable(L);
	for (i = 0; i < BTN_MAX; i++) {
		lua_pushnumber(L,i);
		lua_setfield(L,-2,btn_names[i]);
	}
	lua_setglobal(L,"BTN");

	// Add the KEY table
	lua_newtable(L);
	for (i = 0; keys[i].key; i++)
	{
		lua_pushnumber(L,keys[i].key);
		lua_setfield(L,-2,keys[i].name);
	}
	lua_setglobal(L,"KEY");

	// Add the Joystick table
	lua_newtable(L);
	lua_setglobal(L,"Joystick");

	// Run the config file
	if (luaL_dofile(L,"Config.lua"))
		fatal_error(lua_tostring(L,-1));
	lua_pop(L,-1);

	lua_getglobal(L,"ModPath");
	if (lua_isstring(L,-1)) {
		const char *path = lua_tostring(L,-1);
		modpath = malloc(strlen(path)+1);
		strcpy(modpath,path);
	}
	lua_pop(L,1);

	// Get the render settings
	lua_getglobal(L,"Render");
	if (lua_istable(L,-1)) {
		lua_getfield(L,-1,"Resolution");
		if (lua_istable(L,-1)) {
			lua_pushinteger(L,1);
			lua_gettable(L,-2);
			scale = luaL_checkinteger(L,-1)/640; // TODO: Support resolutions that aren't multiples of 320... x_x;
			lua_pop(L,1);
		}
		lua_pop(L,1);

		lua_getfield(L,-1,"Fullscreen");
		if (lua_toboolean(L,-1))
			gfx_flags |= GFX_FULLSCREEN;
		lua_pop(L,1);
	}
	lua_pop(L,1);

	lua_getglobal(L,"Wii");
	if (lua_istable(L,-1)) {
		lua_getfield(L,-1,"Graphics");
		if (lua_toboolean(L,-1))
			gfx_flags |= GFX_WIIDATA;
		lua_pop(L,1);
		lua_getfield(L,-1,"Data");
		if (lua_toboolean(L,-1))
			wii_priority = true;
		lua_pop(L,1);
	}
	lua_pop(L,1);

	// Get the keyboard settings
	lua_getglobal(L,"Keyboard");
	if (lua_istable(L,-1)) {
		lua_pushnil(L);
		while (lua_next(L,-2))
		{
			if (lua_istable(L,-1)) {
				int i;
				for (i = 1; ; i++) {
					lua_pushinteger(L,i);
					lua_gettable(L,-2);
					if (lua_isnil(L,-1))
						break;
					I_SetKeymap(luaL_checkinteger(L,-3),luaL_checkinteger(L,-1));
					lua_pop(L,1);
				}
				lua_pop(L,1);
			}
			else
				I_SetKeymap(luaL_checkinteger(L,-2),luaL_checkinteger(L,-1));
			lua_pop(L,1);
		}
	}
	lua_pop(L,1);

	// Destroy the Lua state
	lua_close(L);
}
