#include <stdlib.h>
#include <string.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <psprtc.h>
#include <pspaudio.h>
#include <pspaudiolib.h>
#include <pspusb.h>
#include <pspusbstor.h>
#include <psppower.h>
#include <pspdebug.h>
#include <unistd.h>
#include <sys/stat.h>
#include <psploadexec.h>
#include <pspumd.h>
#include <pspsdk.h>
#include <pspuser.h>
#include <pspgu.h>
#include <pspgum.h>
#include <malloc.h>
#include <stdio.h>
#include <psphprm.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <pspdisplay.h>
#include <psputils.h>
#include <oslib/oslib.h>
#include <machine/fastmath.h>
#include <pspiofilemgr.h>
#include <pspusbdevice.h>
#include <psphprm.h>
#include <kubridge.h>
#include <systemctrl.h>
#include <systemctrl_se.h>
#include <psputility.h>
#include "share.h"
#include "savedata.c"
static int usbActivated = 0;
static SceUID irda_fd = -1; 
//message
void ShowMessageDialog(const char *message, int enableYesno)
{	
	oslInitMessageDialog(message, enableYesno);
	OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
	int endmess = 0;
	while(endmess == 0){
		oslStartDrawing();
		oslClearScreen(0);
		oslDrawImageXY(img, 0, 0);
		oslDrawDialog();
		oslEndDrawing();
		oslEndFrame();
		oslSyncFrame();
		if (oslGetDialogStatus() == PSP_UTILITY_DIALOG_NONE){
			oslEndDialog();
			endmess = 1;
		}
	}
	oslFreeImageData(img);
}
void runebootfile(char *path)
{
	struct SceKernelLoadExecVSHParam param;
	int apitype = 0x141;
	char *program = path;
	char *mode = "game";
	memset(&param, 0, sizeof(param));
	param.size = sizeof(param);
	param.args = strlen(program)+1;
	param.argp = program;
	param.key = mode;
	sctrlKernelLoadExecVSHWithApitype(apitype, program, &param);
}
static int LoadStartModule(char *path)
{
    u32 loadResult;
    u32 startResult;
    int status;
    loadResult = kuKernelLoadModule(path, 0, NULL); 
    startResult = sceKernelStartModule(loadResult, 0, NULL, &status, NULL);
    return loadResult;
} 

static int StopUnloadModule(SceUID modID){
    int status;
    sceKernelStopModule(modID, 0, NULL, &status, NULL);
    sceKernelUnloadModule(modID);
    return 0;
}
static int lua_getCurrentDirectory(lua_State *L)
{
	char path[256];
	getcwd(path,256);
	lua_pushstring(L, path);
	return 1;
}
static int lua_setCurrentDirectory(lua_State *L)
{
	chdir(luaL_checkstring(L, 1));
	lua_getCurrentDirectory(L);
	return 1;
}

static int lua_curdir(lua_State *L) {
	int argc = lua_gettop(L);
	if(argc == 0) return lua_getCurrentDirectory(L);
	if(argc == 1) return lua_setCurrentDirectory(L);
}


// Move g_dir to the stack and MEET CERTAIN DOOM! If the SceIoDirent is found on the STACK instead of among the globals, the PSP WILL CRASH IN A VERY WEIRD WAY. You have been WARNED.
static SceIoDirent g_dir;

static int lua_dir(lua_State *L)
{
	int argc = lua_gettop(L);	
	const char *path = "";
	if (argc == 0) {
		path = "";
	} else {
		path = luaL_checkstring(L, 1);
	}
	int fd = sceIoDopen(path);

	if (fd < 0) {
		lua_pushnil(L);  /* return nil */
		return 1;
	}
	lua_newtable(L);
	int i = 1;
	while (sceIoDread(fd, &g_dir) > 0) {
		lua_pushnumber(L, i++);  /* push key for file entry */
		lua_newtable(L);
			lua_pushstring(L, "name");
			lua_pushstring(L, g_dir.d_name);
			lua_settable(L, -3);
	
			lua_pushstring(L, "size");
			lua_pushnumber(L, g_dir.d_stat.st_size);
			lua_settable(L, -3);
	
			lua_pushstring(L, "directory");
			lua_pushboolean(L, FIO_S_ISDIR(g_dir.d_stat.st_mode));
			lua_settable(L, -3);

		lua_settable(L, -3);
	}
	sceIoDclose(fd);
	return 1;  /* table is already on top */
}

static int lua_createDir(lua_State *L)
{
	mkdir(luaL_checkstring(L, 1), 0777);
	return 0;
}

static int lua_removeDir(lua_State *L)
{
	sceIoRmdir(luaL_checkstring(L, 1));
	return 0;
}

static int lua_removeFile(lua_State *L)
{
	sceIoRemove(luaL_checkstring(L, 1));
	return 0;
}

static int lua_rename(lua_State *L)
{
	sceIoRename(luaL_checkstring(L, 1), luaL_checkstring(L, 2));
	return 0;
}
static int lua_usbActivate(lua_State *L)
{
	if (usbActivated) return 0;
	oslInitUsbStorage();
	oslStartUsbStorage();
	usbActivated = 1;
	return 0;
}

static int lua_usbDeactivate(lua_State *L)
{
	if (!usbActivated) return 0;
	usbActivated = 0;
	oslStopUsbStorage();
	pspUsbDeviceFinishDevice();
	oslDeinitUsbStorage();
	return 0;
}
static int lua_powerIsPowerOnline(lua_State *L)
{
	lua_pushboolean(L, scePowerIsPowerOnline());
	return 1;
}

static int lua_powerIsBatteryExist(lua_State *L)
{
	lua_pushboolean(L, scePowerIsBatteryExist());
	return 1;
}

static int lua_powerIsBatteryCharging(lua_State *L)
{
	lua_pushboolean(L, scePowerIsBatteryCharging());
	return 1;
}

static int lua_powerGetBatteryChargingStatus(lua_State *L)
{
	lua_pushnumber(L, scePowerGetBatteryChargingStatus());
	return 1;
}

static int lua_powerIsLowBattery(lua_State *L)
{
	lua_pushboolean(L, scePowerIsLowBattery());
	return 1;
}

static int lua_powerGetBatteryLifePercent(lua_State *L)
{
	lua_pushnumber(L, scePowerGetBatteryLifePercent());
	return 1;
}

static int lua_powerGetBatteryLifeTime(lua_State *L)
{
	lua_pushnumber(L, scePowerGetBatteryLifeTime());
	return 1;
}

static int lua_powerGetBatteryTemp(lua_State *L)
{
	lua_pushnumber(L, scePowerGetBatteryTemp());
	return 1;
}

static int lua_powerGetBatteryVolt(lua_State *L)
{
	lua_pushnumber(L, scePowerGetBatteryVolt());
	return 1;
}

static int lua_powerTick(lua_State *L)
{
	scePowerTick(0);
	return 0;
}
static int lua_md5sum(lua_State *L)
{
	size_t size;
	const char *string = luaL_checklstring(L, 1, &size);
	u8 digest[16];
	sceKernelUtilsMd5Digest((u8*)string, size, digest);
	int i;
	char result[33];
	for (i = 0; i < 16; i++) sprintf(result + 2 * i, "%02x", digest[i]);
	lua_pushstring(L, result);
	return 1;
}
extern void SIOInit(void);
extern void SIOBaud(int baud);
extern void SIOSend(int ch);
extern int SIORecv(void);
static int lua_sioInit(lua_State *L)
{
	int baudRate = luaL_checkint(L, 1);
	SIOInit();
	SIOBaud(baudRate);
	return 0;
}

static int lua_sioWrite(lua_State *L)
{
	int ch = luaL_checkint(L, 1);
	SIOSend(ch);
	return 0;
}

static int lua_sioRead(lua_State *L)
{
	int ch = SIORecv();
	lua_pushnumber(L, ch);
	return 1;
}
static int lua_irdaInit(lua_State *L)
{
	LoadStartModule("flash0:/kd/irda.prx");
	irda_fd = sceIoOpen("irda0:", PSP_O_RDWR, 0);
	return 0;
}

static int lua_irdaWrite(lua_State *L)
{
	size_t size;
	const char *string = luaL_checklstring(L, 1, &size);
	sceIoWrite(irda_fd, string, size);
	return 0;
}

static int lua_irdaRead(lua_State *L)
{
	char data[256];
	int count = sceIoRead(irda_fd, &data, 256);
	if (count > 0) {
		lua_pushlstring(L, data, count);
	} else {
		lua_pushstring(L, "");
	}
	return 1;
}
static int lua_sleep(lua_State *L)
{
	sceKernelDelayThread(luaL_checknumber(L, 1) * 1000);
	return 0;
}
static int lua_getFreeMemory(lua_State *L)
{
	OSL_MEMSTATUS ram = oslGetRamStatus();
	lua_pushnumber(L, ram.maxAvailable);
	return 1;
}
static int lua_madeby(lua_State *L)
{
	const char* message2 = "LPHMv3 by Homemister\nCodename Luamin\n"
			"Uses intraFont by BenHur\n"
			"Thankyou to Sayka and wicked_fable and TheUnderminer\n"
			"Logo and Function list by LXD\n"
			"OSLMod for Graphics engine\n"
			"Lua 5.1.4\n"
			"2/08/2009";
	ShowMessageDialog(message2, 0);
	return 0;
}

static int lua_Quit(lua_State *L)
{
	sceKernelExitGame();
	return 0;
}
static int lua_setcpu(lua_State *L)
{
	int cpuspeed = luaL_checkint(L, 1)+1;
	if (scePowerGetCpuClockFrequencyInt() != cpuspeed){
		if (cpuspeed > 333) {
			cpuspeed = 333;
		}
		if (cpuspeed < 10) {
			cpuspeed = 10;
		}
		scePowerSetClockFrequency(cpuspeed,cpuspeed,((int)floorf(cpuspeed * 0.5)));
	}
	return 0;
}
static int lua_getcpu(lua_State *L)
{
	lua_pushnumber(L, scePowerGetCpuClockFrequencyInt());
	return 1;
}
static int lua_Memclean(lua_State *L)
{
    lua_gc(L, LUA_GCCOLLECT, 0);
    return 0;
}
static int lua_prxload(lua_State *L)
{
	lua_pushnumber(L, LoadStartModule(luaL_checkstring(L, 1)));
    return 1;
}
static int lua_stopmodule(lua_State *L)
{
    StopUnloadModule(luaL_checknumber(L, 1));
    return 0;
}
static int lua_LoadExec(lua_State *L)
{
	runebootfile(luaL_checkstring(L, 1));
    return 0;
}
static int lua_startpsx(lua_State *L)
{
	struct SceKernelLoadExecVSHParam param;
    char* loadpath = luaL_checkstring(L, 1);
	int apitype = 0x143;
	char *mode = "pops"; 
	memset(&param, 0, sizeof(param));
	param.size = sizeof(param);
	param.args = strlen(loadpath)+1;
	param.argp = loadpath;
	param.key = mode;
	sctrlKernelLoadExecVSHWithApitype(apitype, loadpath, &param);
    return 0;
}
static int lua_nickName(lua_State *L)
{
    char namebuffer[128];
    sceUtilityGetSystemParamString(1, namebuffer, 128);
    lua_pushstring(L, namebuffer);
    return 1;
}
static int lua_message(lua_State *L)
{
   ShowMessageDialog(luaL_checkstring(L, 1), luaL_checkint(L, 2));
   return 1;
}
static int lua_buttonpress(lua_State *L)
{
	if(oslGetDialogButtonPressed() == PSP_UTILITY_MSGDIALOG_RESULT_YES)
		lua_pushnumber(L, 1);
	else if(oslGetDialogButtonPressed() == PSP_UTILITY_MSGDIALOG_RESULT_NO)
		lua_pushnumber(L, 2);
	else if(oslGetDialogButtonPressed() == PSP_UTILITY_MSGDIALOG_RESULT_BACK)
		lua_pushnumber(L, 3);
	else
		lua_pushnumber(L, 4);
    return 1;
}
static int lua_standby(lua_State *L)
{
	scePowerRequestStandby();
    return 0;
}
static int lua_suspend(lua_State *L)
{
	scePowerRequestSuspend();
    return 0;
}
static int lua_runumd(lua_State *L)
{
	struct SceKernelLoadExecVSHParam param;
	int apitype = 0x120;
	char *program = "disc0:/PSP_GAME/SYSDIR/EBOOT.BIN";
	char *mode = "game";
	memset(&param, 0, sizeof(param));
	param.size = sizeof(param);
	param.args = strlen(program)+1;
	param.argp = program;
	param.key = mode;
	sctrlKernelLoadExecVSHWithApitype(apitype, program, &param);
    return 0;
}
static int lua_runupdate(lua_State *L)
{
	struct SceKernelLoadExecVSHParam param;
	char* loadpath = luaL_checkstring(L, 1);
	int apitype = 0x140;
	char *mode = "updater";
	memset(&param, 0, sizeof(param));
	param.size = sizeof(param);
	param.args = strlen(loadpath)+1;
	param.argp = loadpath;
	param.key = mode;
	sctrlKernelLoadExecVSHWithApitype(apitype, loadpath, &param);
    return 0;
}
extern SetConfFile(int n);
extern SetUmdFile(char *umdfile);
static int lua_runiso(lua_State *L)
{
	char* isopath = luaL_checkstring(L, 1);
	struct SceKernelLoadExecVSHParam param;
	SEConfig config;	
	int apitype = 0x120;
	char *program = "disc0:/PSP_GAME/SYSDIR/EBOOT.BIN";
	char *mode = "game";
	SetUmdFile(isopath);
	sctrlSEGetConfigEx(&config, sizeof(config));
	if (config.umdmode == MODE_MARCH33)
	{
		SetConfFile(1);
	}
	else if (config.umdmode == MODE_NP9660)
	{
		SetConfFile(2);
	}
	else
	{
		SetConfFile(0);
	}
	memset(&param, 0, sizeof(param));
	param.size = sizeof(param);
	param.args = strlen(program)+1;
	param.argp = program;
	param.key = mode;
	sctrlKernelLoadExecVSHWithApitype(apitype, program, &param);
    return 0;
}
static int lua_usbdevflash0(lua_State *L)
{
	LoadStartModule("flash0:/kd/usbdevice.prx"); 
	pspUsbDeviceSetDevice(PSP_USBDEVICE_FLASH0,0,0);
    return 0;
}
static int lua_usbdevflash1(lua_State *L)
{
	LoadStartModule("flash0:/kd/usbdevice.prx"); 
	pspUsbDeviceSetDevice(PSP_USBDEVICE_FLASH1,0,0);
    return 0;
}
static int lua_usbdevflash2(lua_State *L)
{
	LoadStartModule("flash0:/kd/usbdevice.prx"); 
	pspUsbDeviceSetDevice(PSP_USBDEVICE_FLASH2,0,0);
    return 0;
}
static int lua_usbdevflash3(lua_State *L)
{
	LoadStartModule("flash0:/kd/usbdevice.prx"); 
	pspUsbDeviceSetDevice(PSP_USBDEVICE_FLASH3,0,0);
    return 0;
}

static int lua_usbdevUMD(lua_State *L)
{
	LoadStartModule("flash0:/kd/usbdevice.prx"); 
	pspUsbDeviceSetDevice(PSP_USBDEVICE_UMD9660,0,0);
    return 0;
}
static int lua_playerver(lua_State *L)
{
	lua_pushnumber(L, 10);
    return 1;
}
static int lua_cfwver(lua_State *L)
{
	int ver = sceKernelDevkitVersion();
	char *aStr;
	char buffer[16];
	sprintf(buffer,"%x",ver);
	buffer[1]='.'; 	buffer[3]= buffer[4]; 	buffer[4]=0;
	aStr = buffer;
	lua_pushstring(L, aStr);
    return 1;
}
static int lua_model(lua_State *L)
{
    if (kuKernelGetModel() != 1)
		lua_pushnumber(L, 1000);
	else
		lua_pushnumber(L, 2000);
    return 1;
}
static int lua_devsize(lua_State *L)
{
    u32 size;
    const char *devid = luaL_checkstring(L, 1);
    unsigned int buf[5];
    unsigned int *pbuf = buf;
    sceIoSync("lflash0:0,0", 1);
    sceIoDevctl(devid, 0x02425818, &pbuf, sizeof(pbuf), 0, 0);

    size = buf[1]*buf[3]*buf[4];
		lua_pushnumber(L, size);
    return 1;
}
static int lua_devtotalsize(lua_State *L)
{
    u32 size;
    const char *devid = luaL_checkstring(L, 1);
    unsigned int buf[5];
    unsigned int *pbuf = buf;
    sceIoSync("msfat0:", 1);
    sceIoDevctl(devid, 0x02425818, &pbuf, sizeof(pbuf), 0, 0);
    size = buf[0]*buf[3]*buf[4];
	lua_pushnumber(L, size);
    return 1;
}
static int lua_time(lua_State *L)
{
    	  pspTime rtime;
		int pm = 0;
		char *pmam;
          sceRtcGetCurrentClockLocalTime(&rtime);	// get the time from the PSP real time clock
	  int select = luaL_checkint(L, 1);
          int hour = rtime.hour;
		if(hour>12){
			hour = hour - 12;
			pm = 1;
		}			
          int minutes = rtime.minutes;			

          int seconds = rtime.seconds;

          int microseconds = rtime.microseconds; 

          if(select==1){
		lua_pushnumber(L, hour);
	  }
          if(select==2){
		lua_pushnumber(L, minutes);
	  }
          if(select==3){
		lua_pushnumber(L, seconds);
	  }
          if(select==4){
		lua_pushnumber(L, microseconds);
	  }
          if(select==5){
		if(pm==0)
			pmam = "am";
		else
			pmam = "pm";
		lua_pushstring(L, pmam);
	  }
    return 1;
}
static int lua_date(lua_State *L)
{
    pspTime rtime;
    sceRtcGetCurrentClockLocalTime(&rtime);	// get the time from the PSP real time clock
	int select = luaL_checkint(L, 1);
    if(select==1){
		lua_pushnumber(L, rtime.year);
	}
    if(select==2){
		lua_pushnumber(L, rtime.month);
	}
    if(select==3){
		lua_pushnumber(L, rtime.day);
	}
    return 1;
}
static int lua_getfilesize(lua_State *L)
{
	  SceIoStat stats;
	  sceIoGetstat(luaL_checkstring(L, 1), &stats);
	  	SceOff info = stats.st_size;
		lua_pushnumber(L, info);
    return 1;
}
static int lua_direxsist(lua_State *L)
{
	SceUID exsist = sceIoDopen(luaL_checkstring(L, 1));
	if(exsist>=0)
		lua_pushnumber(L, 1);
	else
		lua_pushnumber(L, 0);
	sceIoClose(exsist);
    return 1;
}
static int lua_fileexsist(lua_State *L)
{
	SceUID exsist = sceIoOpen(luaL_checkstring(L, 1), PSP_O_RDONLY, 0777);
	if(exsist>=0)
		lua_pushnumber(L, 1);
	else
		lua_pushnumber(L, 0);
	sceIoClose(exsist);
    return 1;
}
/*
static int lua_osk(lua_State *L)
{
	OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
	int endosk = 0;
	char userText[256] = "";
	oslInitOsk(luaL_checkstring(L, 1), luaL_checkstring(L, 2), 256,50, -1);
    while(endosk == 0){
		oslStartDrawing();
		oslClearScreen(0);
		oslDrawImageXY(img, 0, 0);
		oslDrawOsk();
		if (oslGetOskStatus() == PSP_UTILITY_DIALOG_NONE){
			if (oslOskGetResult() != OSL_OSK_CANCEL){
				oslOskGetText(userText);
			}
			oslEndOsk();
			endosk = 1;
		}
        oslEndDrawing();
        oslSwapBuffers();
    }
	oslFreeImageData(img);
	oslStartDrawing();
	lua_pushstring(L, userText);
    return 1;
}*/
char* ShowSonyOSK(void) { 
#define NUM_INPUT_FIELDS	(1)
#define TEXT_LENGTH			(128)
	unsigned short intext[NUM_INPUT_FIELDS][TEXT_LENGTH];
	unsigned short outtext[NUM_INPUT_FIELDS][TEXT_LENGTH];
	unsigned short desc[NUM_INPUT_FIELDS][TEXT_LENGTH];
	memset(&intext, 0, NUM_INPUT_FIELDS * TEXT_LENGTH * sizeof(unsigned short));
	memset(&outtext, 0, NUM_INPUT_FIELDS * TEXT_LENGTH * sizeof(unsigned short));
	memset(&desc, 0, NUM_INPUT_FIELDS * TEXT_LENGTH * sizeof(unsigned short));
	int i;
	int done = 0;
	SceUtilityOskData data[NUM_INPUT_FIELDS];
	memset(&data[i], 0, sizeof(SceUtilityOskData));
	data[i].language = PSP_UTILITY_OSK_LANGUAGE_DEFAULT; // Use system default for text input
	data[i].lines = 1;
	data[i].unk_24 = 1;
	data[i].inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL; // Allow all input types
	data[i].desc = desc[i];
	data[i].intext = intext[i];
	data[i].outtextlength = TEXT_LENGTH;
	data[i].outtextlimit = 32; // Limit input to 32 characters
	data[i].outtext = outtext[i];
	SceUtilityOskParams params;
	memset(&params, 0, sizeof(params));
	params.base.size = sizeof(params);
	sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &params.base.language);
	sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &params.base.buttonSwap);
	params.base.graphicsThread = 17;
	params.base.accessThread = 19;
	params.base.fontThread = 18;
	params.base.soundThread = 16;
	params.datacount = NUM_INPUT_FIELDS;
	params.data = data;
ShowMessageDialog("OK", 0);
	sceUtilityOskInitStart(&params);
ShowMessageDialog("OK", 0);
	while(!done)
	{
		oslStartDrawing();
		oslClearScreen(0);
		switch(sceUtilityOskGetStatus())
		{
			case PSP_UTILITY_DIALOG_INIT:
				ShowMessageDialog("OK", 0);
				break;
			
			case PSP_UTILITY_DIALOG_VISIBLE:
				sceUtilityOskUpdate(1);
				break;
			
			case PSP_UTILITY_DIALOG_QUIT:
				sceUtilityOskShutdownStart();
				break;
			
			case PSP_UTILITY_DIALOG_FINISHED:
				break;
				
			case PSP_UTILITY_DIALOG_NONE:
				done = 1;
				
			default :
				break;
		}
		oslEndDrawing();
		oslEndFrame();
		oslSyncFrame();
	}
	int j;
		char buf[256];
		for(j = 0; data[i].outtext[j]; j++)
		{
			unsigned c = data[i].outtext[j];
			
			if(32 <= c && c <= 127) // print ascii only
				sprintf(buf,"%c", data[i].outtext[j]);
		}
	
	return buf;
} 
static int lua_osk(lua_State *L)
{
   //int argc = lua_gettop(L);
   //OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
   //char *_desc = luaL_checkstring(L, 2);
   //char *_intext = luaL_checkstring(L, 1);
   //char *input = ShowSonyOSK(); // Desc , InText, image
   //oslFreeImageData(img);
	//oslStartDrawing();
	oslInitOsk(luaL_checkstring(L, 2), luaL_checkstring(L, 1), 128, 1,1);
	char message[100] = "";
	memset(message, 0, sizeof(message));
	while (1){
		if (oslOskIsActive()){
			oslStartDrawing();
			oslClearScreen(0);
			oslDrawOsk();
			if (oslGetOskStatus() == PSP_UTILITY_DIALOG_NONE){
				if (oslOskGetResult() == OSL_OSK_CANCEL)
					sprintf(message, "");
				else{
					char userText[100] = "";
					oslOskGetText(userText);
					sprintf(message, "%s", userText);
				}
				oslEndOsk();
				break;
			}
			oslEndDrawing();
			oslEndFrame();
			oslSyncFrame();
		}
	}
   lua_pushstring(L, message);
   return 1;
}
static int lua_gamesave(lua_State *L)
{
    if (lua_gettop(L) != 5) return luaL_error(L, "Title1,TITLE2,Details,Savedata as string");
	int mode = 0;
	char *TITLE1 = luaL_checkstring(L, 1);
	char *TITLE2 = luaL_checkstring(L, 2);
	char *DETAILS = luaL_checkstring(L, 3);
	char *SVDATA = luaL_checkstring(L, 4);
	char *Gamename = luaL_checkstring(L, 5);
	mode = PSP_UTILITY_SAVEDATA_LISTSAVE;
	OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
	ShowSaveDialog(mode, TITLE1, TITLE2, DETAILS, SVDATA,Gamename, img);
    return 0;
}
static int lua_gameload(lua_State *L)
{
    if (lua_gettop(L) != 1) return luaL_error(L, "no arguments expected.");
	int mode = 0;
	char *string;
	char *string2;
	char *Gamename = luaL_checkstring(L, 1);
	mode = PSP_UTILITY_SAVEDATA_LISTLOAD;
	OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
	string2 = ShowSaveDialogload(mode, string,Gamename, img);
	lua_pushstring(L, string2);
    return 1;
}
/*
static int lua_gamesave(lua_State *L)
{
OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
int end = 0;
char *gameTitle = luaL_checkstring(L, 1);
char *gameID = luaL_checkstring(L, 2);
char *saveName = luaL_checkstring(L, 3);
char nameList[][20] =	// End list with ""
{
 "0000",
 "0001",
 "0002",
 "0003",
 "0004",
 "0005",
 "0006",
 "0007",
 "0008",
 "0009",
 "0010",
 ""
};
char *data = luaL_checkstring(L, 4);
char *iconpath = luaL_checkstring(L, 5);
struct oslSaveLoad saveLoadData;
    int type = OSL_DIALOG_NONE;
    char message[256] = "";
    memset(&saveLoadData, 0, sizeof(saveLoadData));
    strcpy(saveLoadData.gameTitle, gameTitle);
    strcpy(saveLoadData.gameID, gameID);
    strcpy(saveLoadData.saveName, saveName);
    saveLoadData.nameList = nameList;
if((strcmp( "", iconpath ))){
	SceUID fd = sceIoOpen(iconpath, PSP_O_RDONLY, 0777);
	int sizeicon = sceIoLseek32(fd, 0, PSP_SEEK_END);
	sceIoLseek32(fd, 0, PSP_SEEK_SET);
	char icondata[12000];
	sceIoRead(fd, icondata, sizeicon);
	sceIoClose(fd);
    saveLoadData.icon0 = icondata;
    saveLoadData.size_icon0 = sizeicon;
}
    saveLoadData.data = data;
    saveLoadData.dataSize = 256;
    oslInitSaveDialog(&saveLoadData);
    memset(message, 0, sizeof(message));
    while(end == 0){
	type = oslGetSaveLoadType();
        oslStartDrawing();
	    oslDrawImageXY(img, 0, 0);
            if (type != OSL_DIALOG_NONE){
                oslDrawSaveLoad();
                if (oslGetLoadSaveStatus() == PSP_UTILITY_DIALOG_NONE){
					oslEndSaveLoadDialog();
					end = 1;
                }
            }
        oslEndDrawing();
        oslSwapBuffers();
    }
    oslFreeImageData(img);
    lua_pushstring(L, message);
    return 1;
}
static int lua_gameload(lua_State *L)
{
OSL_IMAGE *img = oslCreateSwizzledImage(OSL_SECONDARY_BUFFER, OSL_IN_RAM);
int end = 0;
char *gameID = luaL_checkstring(L, 1);
char *saveName = luaL_checkstring(L, 2);
char nameList[][20] =	// End list with ""
{
 "0000",
 "0001",
 "0002",
 "0003",
 "0004",
 "0005",
 "0006",
 "0007",
 "0008",
 "0009",
 "0010",
 ""
};
struct oslSaveLoad saveLoadData;
    int type = OSL_DIALOG_NONE;
    char message[256] = "";
    char loadedData[256] = "";
    memset(&saveLoadData, 0, sizeof(saveLoadData));
    strcpy(saveLoadData.gameID, gameID);
    strcpy(saveLoadData.saveName, saveName);
    saveLoadData.nameList = nameList;
    saveLoadData.data = &loadedData;
    saveLoadData.dataSize = 256;
    oslInitLoadDialog(&saveLoadData);
    memset(message, 0, sizeof(message));
    while(end == 0){
	type = oslGetSaveLoadType();
            oslStartDrawing();
	    oslDrawImageXY(img, 0, 0);
            if (type != OSL_DIALOG_NONE){
                oslDrawSaveLoad();
                if (oslGetLoadSaveStatus() == PSP_UTILITY_DIALOG_NONE){
                    oslEndSaveLoadDialog();
					end = 1;
                }
            }
        oslEndDrawing();
        oslSwapBuffers();
    }
    oslFreeImageData(img);
    lua_pushstring(L, message);
    return 1;
}*/
extern int imposeGetVolume();
extern int imposeSetVolume(int volume);
extern int imposeGetMute();
extern int imposeSetMute(int value);
extern int getBrightness();
extern void setBrightness(int brightness);
extern int imposeSetBrightness(int value);
extern int imposeGetBrightness();
extern int displayEnable(void);
extern int displayDisable(void);
extern int getBrightness();
extern void setBrightness(int brightness);
extern int imposeSetHomePopup(int value);
static int lua_setbright(lua_State *L)
{
	int bright = luaL_checknumber(L, 1);
	if(bright>100){
		bright = 100;
	}
	if(bright<0){
		bright = 0;
	}
	setBrightness(bright);
    imposeSetBrightness(bright);
	lua_pushnumber(L, bright);
    return 1;
}
static int lua_getbright(lua_State *L)
{
	lua_pushnumber(L, getBrightness());
    return 1;
}
static int lua_enabledisplay(lua_State *L)
{
    displayEnable();
    return 0;
}
static int lua_disabledisplay(lua_State *L)
{
	displayDisable();
    return 0;
}
static int lua_getvolume(lua_State *L)
{
	int volume = imposeGetVolume();
	lua_pushnumber(L, volume);
    return 1;
}
static int lua_setvolume(lua_State *L)
{
	int volume = luaL_checknumber(L, 1);
	if(volume>30){
		volume = 30;
	}
	if(volume<0){
		volume = 0;
	}
	imposeSetVolume(volume);
	lua_pushnumber(L, volume);
    return 1;
}
static int lua_mute(lua_State *L)
{
	int value = luaL_checknumber(L, 1);
	imposeSetMute(value);
	lua_pushnumber(L, value);
    return 1;
}
static int lua_homepopup(lua_State *L)
{
	int value = luaL_checknumber(L, 1);
	imposeSetHomePopup(value);
	lua_pushnumber(L, value);
    return 1;
}
//UMD START

static int umd_init(lua_State *L)
{
// Wait for disc and mount to filesystem
  sceUmdActivate(1, "disc0:"); // Mount UMD to disc0: file system
  sceUmdWaitDriveStat(UMD_WAITFORINIT);
  	lua_pushnumber(L, 1);
	return 1;
}

static int umd_checkdisk(lua_State *L)
{
	lua_pushnumber(L, sceUmdCheckMedium());
	return 1;
}


static int umd_term(lua_State *L)
{
	sceUmdDeactivate(1, "disc0:");
	return 0;
}
static int umd_getSize(lua_State *L)
{
	int size;
	SceUID umd;
	umd = sceIoOpen("umd0:", PSP_O_RDONLY, 0777);
	size = sceIoLseek(umd, 0, PSP_SEEK_END);
	size = size*2048;
	sceIoClose(umd);
	lua_pushnumber(L, size);	
	return 1;
}
static const luaL_reg UMD_functions[] = {
  {"init",              umd_init},
  {"term",              umd_term},
  {"checkDisk",         umd_checkdisk},
  {"getSize",         umd_getSize},
  {0, 0}
};
static int Hprm_read(lua_State *L)
{
u32 k1 = pspSdkSetK1(0);
	u32 remoteButtons;
	sceHprmPeekCurrentKey(&remoteButtons);
	if(remoteButtons & PSP_HPRM_PLAYPAUSE){
		lua_pushstring(L, "PLAY");
		return 1;
	}
	if(remoteButtons & PSP_HPRM_FORWARD){
		lua_pushstring(L, "FWD");
		return 1;
	}
	if(remoteButtons & PSP_HPRM_BACK){
		lua_pushstring(L, "BACK");
		return 1;
	}
	if(remoteButtons & PSP_HPRM_VOL_UP){
		lua_pushstring(L, "VOLUP");
		return 1;
	}
	if(remoteButtons & PSP_HPRM_VOL_DOWN){
		lua_pushstring(L, "VOLDOWN");
		return 1;
	}
	if(remoteButtons & PSP_HPRM_HOLD ){
		lua_pushstring(L, "HOLD");
		return 1;
	}
	lua_pushnumber(L, 0);
	pspSdkSetK1(k1);
	return 1;
}
static int Hprm_headphone(lua_State *L)
{
u32 k1 = pspSdkSetK1(0);
	lua_pushnumber(L, sceHprmIsHeadphoneExist());
	pspSdkSetK1(k1);
	return 1;
}
static int Hprm_remote(lua_State *L)
{
u32 k1 = pspSdkSetK1(0);
	lua_pushnumber(L, sceHprmIsRemoteExist());
	pspSdkSetK1(k1);
	return 1;
}
static int Hprm_mic(lua_State *L)
{
u32 k1 = pspSdkSetK1(0);
	lua_pushnumber(L, sceHprmIsMicrophoneExist());
	pspSdkSetK1(k1);
	return 1;
}
static const luaL_reg Hprm_functions[] = {
  {"read",              Hprm_read},
  {"headphone",              Hprm_headphone},
  {"remote",              Hprm_remote},
  {"mic",              Hprm_mic},
  {0, 0}
};
//End UMD
static const luaL_reg System_functions[] = {
  {"currentDirectory",              lua_curdir},
  {"listDirectory",           	    lua_dir},
  {"createDirectory",               lua_createDir},
  {"removeDirectory",               lua_removeDir},
  {"removeFile",                    lua_removeFile},
  {"rename",                        lua_rename},
  {"usbDiskModeActivate",           lua_usbActivate},
  {"usbDiskModeDeactivate",    	    lua_usbDeactivate},
  {"powerIsPowerOnline",            lua_powerIsPowerOnline},
  {"powerIsBatteryExist",           lua_powerIsBatteryExist},
  {"powerIsBatteryCharging",        lua_powerIsBatteryCharging},
  {"powerGetBatteryChargingStatus", lua_powerGetBatteryChargingStatus},
  {"powerIsLowBattery",             lua_powerIsLowBattery},
  {"powerGetBatteryLifePercent",    lua_powerGetBatteryLifePercent},
  {"powerGetBatteryLifeTime",       lua_powerGetBatteryLifeTime},
  {"powerGetBatteryTemp",           lua_powerGetBatteryTemp},
  {"powerGetBatteryVolt",           lua_powerGetBatteryVolt},
  {"powerTick",                     lua_powerTick},
  {"md5sum",                        lua_md5sum},
  {"irdaInit",                      lua_irdaInit},
  {"irdaRead",                      lua_irdaRead},
  {"irdaWrite",                     lua_irdaWrite},
  {"sleep",                         lua_sleep},
  {"getFreeMemory",                 lua_getFreeMemory},
  {"cfwVersion",                        lua_cfwver},
  {"madeby",                        lua_madeby},
  {"getModel",                        lua_model},
  {"getFreeSpace",                        lua_devsize},
  {"getTotalSize",                        lua_devtotalsize},
  {"Quit",							lua_Quit},
  {"setCpuSpeed",					lua_setcpu},
  {"getCpuSpeed",					lua_getcpu},
  {"runEboot",						lua_LoadExec},
  {"playerVer",						lua_playerver},
  {"memClean",						lua_Memclean},
  {"loadPrx",						lua_prxload},
  {"stopPRX",						lua_stopmodule},
  {"nickName",						lua_nickName},
  {"message",						lua_message},
  {"buttonPressed",					lua_buttonpress},
  {"suspend",						lua_suspend},
  {"shutdown",						lua_standby},
  {"startUMD",						lua_runumd},
  {"startUpdate",						lua_runupdate},
  {"startISO",						lua_runiso},
  {"startOSK",						lua_osk},
  {"startPSX",						lua_startpsx},
  {"getTime",						lua_time},
  {"getDate",						lua_date},
  {"startGameSave",						lua_gamesave},
  {"startGameLoad",						lua_gameload},
  {"doesDirExist",						lua_direxsist},
  {"doesFileExist",						lua_fileexsist},
  {"getFileSize",						lua_getfilesize},
  {"usbDevFlash0",						lua_usbdevflash0},
  {"usbDevFlash1",						lua_usbdevflash1},
  {"usbDevFlash2",						lua_usbdevflash2},
  {"usbDevFlash3",						lua_usbdevflash3},
  {"usbDevUMD",						lua_usbdevUMD},
  {"sioInit",                       lua_sioInit},
  {"sioRead",                       lua_sioRead},
  {"sioWrite",                      lua_sioWrite},
  {"setBrightness",						lua_setbright},
  {"getBrightness",						lua_getbright},
  {"setVolume",						lua_setvolume},
  {"getVolume",						lua_getvolume},
  {"enableDisplay",						lua_enabledisplay},
  {"disableDisplay",						lua_disabledisplay},
  {"mute",						lua_mute},
  {"homePopup",						lua_homepopup},
  {0, 0}
};
void sys_init(lua_State *L) {
	luaL_openlib(L, "UMD", UMD_functions, 0);
	luaL_openlib(L, "Hprm", Hprm_functions, 0);
	luaL_openlib(L, "System", System_functions, 0);
}

