#include <stdlib.h>
#include "share.h"
#include <pspctrl.h>
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include <string.h>
#include <math.h>
#include <pspsdk.h>
#include <pspnet.h>
#include <pspwlan.h>

static void initController(){
    u32 k1 = pspSdkSetK1(0);
	sceCtrlSetSamplingCycle(0);
    sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
    pspSdkSetK1(k1);
}

extern void readButtons(SceCtrlData *pad_data, int count);

typedef SceCtrlData Controls;

// The "Controls" userdata object.
// ------------------------------
UserdataStubs(Controls, Controls)

static int Controls_tostring (lua_State *L)
{
	char buff[32];
	sprintf(buff, "%d", toControls(L, 1)->Buttons);
	lua_pushfstring(L, "Controls (%s)", buff);
	return 1;
}
static int Controls_read(lua_State *L)
{
	Controls* pad = pushControls(L);
	readButtons(pad, 1); 
	return 1;
}
#define CHECK_CTRL(NAME, BIT) \
static int NAME(lua_State *L) \
{ \
	Controls *a = toControls(L, 1);\
	lua_pushboolean(L, (a->Buttons & BIT) == BIT); \
	return 1; \
}

CHECK_CTRL(Controls_select, PSP_CTRL_SELECT)
CHECK_CTRL(Controls_start, PSP_CTRL_START)
CHECK_CTRL(Controls_up, PSP_CTRL_UP)
CHECK_CTRL(Controls_right, PSP_CTRL_RIGHT)
CHECK_CTRL(Controls_down, PSP_CTRL_DOWN)
CHECK_CTRL(Controls_left, PSP_CTRL_LEFT)
CHECK_CTRL(Controls_l, PSP_CTRL_LTRIGGER)
CHECK_CTRL(Controls_r, PSP_CTRL_RTRIGGER)
CHECK_CTRL(Controls_triangle, PSP_CTRL_TRIANGLE)
CHECK_CTRL(Controls_circle, PSP_CTRL_CIRCLE)
CHECK_CTRL(Controls_cross, PSP_CTRL_CROSS)
CHECK_CTRL(Controls_square, PSP_CTRL_SQUARE)
CHECK_CTRL(Controls_home, PSP_CTRL_HOME)
CHECK_CTRL(Controls_hold, PSP_CTRL_HOLD)
CHECK_CTRL(Controls_note, PSP_CTRL_NOTE)
CHECK_CTRL(Controls_volup, PSP_CTRL_VOLUP)
CHECK_CTRL(Controls_voldown, PSP_CTRL_VOLDOWN)
CHECK_CTRL(Controls_screen, PSP_CTRL_SCREEN)


static int Controls_buttons(lua_State *L)
{
	Controls *a = toControls(L, 1);
	lua_pushnumber(L, a->Buttons);
	return 1;
}

static int Controls_analogX(lua_State *L) 
{ 
	Controls pad;
	sceCtrlReadBufferPositive(&pad, 1); 
	lua_pushnumber(L, pad.Lx -128); 
	return 1; 
}
static int Controls_analogY(lua_State *L) 
{ 
	Controls pad;
	sceCtrlReadBufferPositive(&pad, 1); 
	lua_pushnumber(L, pad.Ly -128); 
	return 1; 
}

static int Controls_equal(lua_State *L) {
	Controls* a = toControls(L, 1);
	Controls* b = toControls(L, 2);
	lua_pushboolean(L, a->Buttons == b->Buttons );
	return 1;
}
static int Controls_wlan(lua_State *L) {
	lua_pushnumber(L, sceWlanGetSwitchState());
	return 1;
}

	
static const luaL_reg Controls_methods[] = {
	{"read", Controls_read},
	{"select", Controls_select },
	{"start", Controls_start },
	{"up", Controls_up },
	{"right", Controls_right },
	{"down", Controls_down },
	{"left", Controls_left },
	{"l", Controls_l },
	{"r", Controls_r },
	{"triangle", Controls_triangle },
	{"circle", Controls_circle },
	{"cross", Controls_cross },
	{"square", Controls_square },
	{"home", Controls_home },
	{"hold", Controls_hold },
	{"note", Controls_note },
	{"volup", Controls_volup },
	{"voldown", Controls_voldown },
	{"screen", Controls_screen },
	{"analogX", Controls_analogX},
	{"analogY", Controls_analogY},
	{"buttons", Controls_buttons },
	{"wlan", Controls_wlan },
  {0, 0}
};
static const luaL_reg Controls_meta[] = {
  {"__tostring", Controls_tostring},
  {"__eq", Controls_equal},
  {0, 0}
};
UserdataRegister(Controls, Controls_methods, Controls_meta)
void setTableValue(lua_State *L, char* name, int value)
{
	lua_pushstring(L, name);
	lua_pushnumber(L, value);
	lua_settable(L, -3);
}

void control_init(lua_State *L) {
	initController();
	Controls_register(L);
	lua_pushstring(L, "Controls");
	/*lua_gettable(L, LUA_GLOBALSINDEX); \
	setTableValue(L, "selectMask", PSP_CTRL_SELECT);
	setTableValue(L, "startMask", PSP_CTRL_START);
	setTableValue(L, "upMask", PSP_CTRL_UP);
	setTableValue(L, "rightMask", PSP_CTRL_RIGHT);
	setTableValue(L, "downMask", PSP_CTRL_DOWN);
	setTableValue(L, "leftMask", PSP_CTRL_LEFT);
	setTableValue(L, "ltriggerMask", PSP_CTRL_LTRIGGER);
	setTableValue(L, "rtriggerMask", PSP_CTRL_RTRIGGER);
	setTableValue(L, "triangleMask", PSP_CTRL_TRIANGLE);
	setTableValue(L, "circleMask", PSP_CTRL_CIRCLE);
	setTableValue(L, "crossMask", PSP_CTRL_CROSS);
	setTableValue(L, "squareMask", PSP_CTRL_SQUARE);
	setTableValue(L, "homeMask", PSP_CTRL_HOME);
	setTableValue(L, "holdMask", PSP_CTRL_HOLD);
	setTableValue(L, "noteMask", PSP_CTRL_NOTE);
	setTableValue(L, "volupMask", PSP_CTRL_VOLUP);
	setTableValue(L, "voldownMask", PSP_CTRL_VOLDOWN);
	setTableValue(L, "screenMask", PSP_CTRL_SCREEN);*/
}
