#include "serial_lua.h"
#include "serial_port_lua.h"
#include "types.h"
#include "error.h"

extern "C"
{
	#include <lua.h>
	#include <lauxlib.h>
	#include <lualib.h>
}

using MicroMacro::SerialPort;


int Serial_lua::regmod(lua_State *L)
{
	static const luaL_Reg _funcs[] = {
		{"open", Serial_lua::open},
		{NULL, NULL}
	};

	luaL_newlib(L, _funcs);
	lua_setglobal(L, SERIAL_MODULE_NAME);

	return MicroMacro::ERR_OK;
}

int Serial_lua::cleanup(lua_State *L)
{
	return MicroMacro::ERR_OK;
}

int Serial_lua::open(lua_State *L)
{
	int top = lua_gettop(L);
	if( top != 1 && top != 2 )
		wrongArgs(L);
	checkType(L, LT_STRING, 1);

	char *portName	=	(char *)lua_tostring(L, 1);
	int baud		=	9600;

	if( top >= 2 )
	{
		checkType(L, LT_NUMBER, 2);
		baud		=	(int)lua_tointeger(L, 2);
	}

	SerialPort *pSerialPort = new SerialPort;
	SerialPort **ppSerialPort = static_cast<SerialPort **>(lua_newuserdata(L, sizeof(SerialPort **)));
	*ppSerialPort = pSerialPort;

	pSerialPort->open(portName, baud);

	if( !pSerialPort->connected )
	{
		lua_pop(L, 1); // Pop the garbage port off since it failed.
		lua_pushboolean(L, false);
		char errbuff[2048];
		slprintf(errbuff, sizeof(errbuff), "Failed to open serial port. Err code: %d\n", GetLastError());
		lua_pushstring(L, errbuff);
		return 2;
	}

	// It was created, so give it a metatable
	luaL_getmetatable(L, LuaType::metatable_serial_port);
	lua_setmetatable(L, -2);

	return 1;
}
