/*
 * PtokaX MultiLib - Compatibility layer allowing same lib to work on PXLua based on Lua 5.1, 5.2 and 5.3.

 * Copyright (C) 2012-2013  Petr Kozelka, PPK at PtokaX dot org

 * This code is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

 * See http://creativecommons.org/licenses/by-nc/4.0/ for license details.
 */

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#ifndef LuaH
#define LuaH
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <stddef.h>
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define LUA_NUMBER          double
#define LUA_INTEGER         long long
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define LUA_MULTRET         (-1)
extern int LUA_REGISTRYINDEX;
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define LUALIB_API  __declspec(dllexport)
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef struct lua_State lua_State;
typedef int (* lua_CFunction)(lua_State *);
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef int (* plua_upvalueindex)(int);
plua_upvalueindex lua_upvalueindex;
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef void * (* lua_Alloc)(void * ud, void * ptr, size_t osize, size_t nsize);
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define LUA_TNONE           (-1)
#define LUA_TNIL            0
#define LUA_TBOOLEAN        1
#define LUA_TLIGHTUSERDATA  2
#define LUA_TNUMBER         3
#define LUA_TSTRING         4
#define LUA_TTABLE          5
#define LUA_TFUNCTION       6
#define LUA_TUSERDATA       7

#define LUA_MINSTACK        20
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef LUA_NUMBER lua_Number;
typedef LUA_INTEGER lua_Integer;
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

typedef int (* plua_gettop)(lua_State *);
plua_gettop lua_gettop;

typedef void (* plua_settop)(lua_State *, int);
plua_settop lua_settop;

typedef void (* plua_pushvalue)(lua_State *, int);
plua_pushvalue lua_pushvalue;

typedef void (* plua_remove)(lua_State *, int);
plua_remove lua_remove;

typedef void (* plua_insert)(lua_State *, int);
plua_insert lua_insert;

typedef void (* plua_replace)(lua_State *, int);
plua_replace lua_replace;

typedef int (* plua_checkstack)(lua_State *, int);
plua_checkstack lua_checkstack;

typedef int (* plua_isnumber)(lua_State *, int);
plua_isnumber lua_isnumber;

typedef int (* plua_isstring)(lua_State *, int);
plua_isstring lua_isstring;

typedef int (* plua_isuserdata)(lua_State *, int);
plua_isuserdata lua_isuserdata;

typedef int (* plua_type)(lua_State *, int);
plua_type lua_type;

typedef const char * (* plua_typename)(lua_State *, int);
plua_typename lua_typename;

typedef lua_Number (* plua_tonumber)(lua_State *, int); // 5.1 only
plua_tonumber lua_tonumber;

typedef lua_Number (* plua_tonumberx)(lua_State *, int, int *); // 5.2+
plua_tonumberx lua_tonumberx;

typedef lua_Integer (* plua_tointeger)(lua_State *, int); // 5.1 only
plua_tointeger lua_tointeger;

typedef lua_Integer (* plua_tointegerx)(lua_State *, int, int *); // 5.2+
plua_tointegerx lua_tointegerx;

typedef int (* plua_toboolean)(lua_State *, int);
plua_toboolean lua_toboolean;

typedef const char * (* plua_tolstring)(lua_State *, int, size_t *);
plua_tolstring lua_tolstring;

typedef size_t (* plua_objlen)(lua_State *, int); // 5.1 only
plua_objlen lua_objlen;

typedef size_t (* plua_rawlen)(lua_State *, int); // 5.2+
plua_rawlen lua_rawlen;

typedef size_t (* plua_strlen)(lua_State *, int); // 5.1 only
plua_strlen lua_strlen;

typedef void * (* plua_touserdata)(lua_State *, int);
plua_touserdata lua_touserdata;

typedef int (* plua_rawequal)(lua_State *, int, int);
plua_rawequal lua_rawequal;

typedef void (* plua_pushnil)(lua_State *);
plua_pushnil lua_pushnil;

typedef void (* plua_pushnumber)(lua_State *, lua_Number);
plua_pushnumber lua_pushnumber;

typedef void (* plua_pushinteger)(lua_State *, lua_Integer);
plua_pushinteger lua_pushinteger;

typedef const char * (* plua_pushlstring)(lua_State *, const char *, size_t);
plua_pushlstring lua_pushlstring;

typedef const char * (* plua_pushstring)(lua_State *, const char *);
plua_pushstring lua_pushstring;

typedef const char * (* plua_pushfstring)(lua_State *, const char *, ...);
plua_pushfstring lua_pushfstring;

typedef void (* plua_pushcclosure)(lua_State *, lua_CFunction, int);
plua_pushcclosure lua_pushcclosure;

typedef void (* plua_pushboolean)(lua_State *, int);
plua_pushboolean lua_pushboolean;

typedef void (* plua_pushlightuserdata)(lua_State *, void *);
plua_pushlightuserdata lua_pushlightuserdata;

typedef void (* plua_gettable)(lua_State *, int);
plua_gettable lua_gettable;

typedef void (* plua_getfield)(lua_State *, int, const char *);
plua_getfield lua_getfield;

typedef void (* plua_rawget)(lua_State *, int);
plua_rawget lua_rawget;

typedef void (* plua_rawgeti)(lua_State *, int, lua_Integer);
plua_rawgeti lua_rawgeti;

typedef void (* plua_createtable)(lua_State *, int, int);
plua_createtable lua_createtable;

typedef void * (* plua_newuserdata)(lua_State *, size_t);
plua_newuserdata lua_newuserdata;

typedef int (* plua_getmetatable)(lua_State *, int);
plua_getmetatable lua_getmetatable;

typedef void (* plua_settable)(lua_State *, int);
plua_settable lua_settable;

typedef void (* plua_setfield)(lua_State *, int, const char *);
plua_setfield lua_setfield;

typedef void (* plua_rawset)(lua_State *, int);
plua_rawset lua_rawset;

typedef void (* plua_rawseti)(lua_State *, int, lua_Integer);
plua_rawseti lua_rawseti;

typedef int (* plua_setmetatable)(lua_State *, int);
plua_setmetatable lua_setmetatable;

typedef void (* plua_call)(lua_State *, int, int); // 5.1 only
plua_call lua_call;

typedef void (* plua_callk)(lua_State *, int, int, int, lua_CFunction); // 5.2+
plua_callk lua_callk;

typedef int (* plua_pcall)(lua_State *, int, int, int); // 5.1 only
plua_pcall lua_pcall;

typedef int (* plua_pcallk)(lua_State *, int, int, int, int, lua_CFunction); // 5.2+
plua_pcallk lua_pcallk;

typedef int (* plua_error)(lua_State *);
plua_error lua_error;

typedef int (* plua_next)(lua_State *, int);
plua_next lua_next;

typedef void (* plua_concat)(lua_State *, int);
plua_concat lua_concat;

typedef void (* plua_len)(lua_State *, int); // 5.2+
plua_len lua_len;

typedef lua_Alloc (* plua_getallocf) (lua_State *, void **);
plua_getallocf lua_getallocf;
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define lua_pop(L, n)                   lua_settop(L, -(n)-1)
#define lua_newtable(L)                 lua_createtable(L, 0, 0)
#define lua_pushcfunction(L, f)         lua_pushcclosure(L, (f), 0)
#define lua_isfunction(L, n)            (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L, n)               (lua_type(L, (n)) == LUA_TTABLE)
#define lua_isnil(L, n)                 (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L, n)             (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isnone(L, n)                (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n)           (lua_type(L, (n)) <= 0)
#define lua_pushliteral(L, s)           lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1)
#define lua_tostring(L, i)              lua_tolstring(L, (i), NULL)
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

static lua_Number lua52_tonumber(lua_State *L, int iValue);
static lua_Integer lua52_tointeger(lua_State *L, int idx);
static void lua52_call(lua_State *L, int nargs, int nresults);
static int lua52_pcall(lua_State *L, int nargs, int nresults, int errfunc);
static int lua51_upvalueindex(int i);
static int lua52_upvalueindex(int i);
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

int InitLuaLib();
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#endif
